Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/staging-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Staging tests

on:
pull_request:
types: [labeled]
branches:
- master
- 'rel/**'
issue_comment:
types: [created]
workflow_dispatch:
inputs:
test_envs:
description: 'Tox test environments to run (e.g. py312)'
required: false
default: 'py314'
test_filter:
description: 'Pytest filter expression (-k flag)'
required: false
default: ''

concurrency:
group: staging-tests
cancel-in-progress: false

jobs:
staging-tests:
name: Staging tests
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' && github.event.label.name == 'test-staging') ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/test-staging'))
runs-on:
group: infra1-runners-arc
labels: runners-small
steps:
- name: Get PR head SHA (comment trigger)
if: github.event_name == 'issue_comment'
id: pr
run: |
PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }})
echo "sha=$(echo "$PR_DATA" | jq -r .head.sha)" >> "$GITHUB_OUTPUT"
echo "ref=$(echo "$PR_DATA" | jq -r .head.ref)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ steps.pr.outputs.sha || github.event.pull_request.head.sha || github.sha }}

- name: Set up Python
uses: astral-sh/setup-uv@v6
with:
python-version: '3.14'

- name: Install dependencies
run: uv sync --all-groups --locked

- name: Clean staging environment
run: make clean-staging
env:
TOKEN: ${{ secrets.PYTHON_SDK_STG_API_KEY }}

- name: Load staging environment
run: make load-staging
env:
TOKEN: ${{ secrets.PYTHON_SDK_STG_API_KEY }}

- name: Run staging tests
run: |
make test-staging \
TEST_ENVS=${{ github.event.inputs.test_envs || 'py314' }} \
ADD_ARGS="${{ github.event.inputs.test_filter && format('-k {0}', github.event.inputs.test_filter) || '' }}"
env:
TOKEN: ${{ secrets.PYTHON_SDK_STG_API_KEY }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ docs/.hugo_build.lock

# Export artifacts from Docker export-controller service
packages/gooddata-sdk/tests/export/exports/default/

# Staging test fixture backups (created by conftest.py, self-heal on next run)
*.staging-backup
36 changes: 36 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,42 @@ docker compose --profile fdw up -d

This starts a PostgreSQL instance with the gooddata-fdw extension on port 2543.

## Run staging tests

Staging tests run against a shared GoodData staging environment instead of a local docker-compose stack.
They are useful for validating changes against a real deployment.

### Triggers

The staging tests workflow (`.github/workflows/staging-tests.yaml`) can be triggered in three ways:

1. **Label** — Add the `test-staging` label to a PR targeting `master` or `rel/**`.
2. **PR comment** — Post `/test-staging` as a comment on a PR.
3. **Manual dispatch** — Trigger from the Actions tab with optional `test_envs` and `test_filter` inputs.

Only one staging test run executes at a time (concurrency group `staging-tests`, non-cancelling).

### Running staging tests locally

You need a staging API token (`TOKEN`). The workflow uses the `PYTHON_SDK_STG_API_KEY` secret; locally you
pass it via the `TOKEN=` make argument:

```bash
# 1. Clean the staging workspace (removes previous test data)
make clean-staging TOKEN=<your-staging-token>

# 2. Load the demo layout into staging
make load-staging TOKEN=<your-staging-token>

# 3. Run the tests
make test-staging TOKEN=<your-staging-token>

# Optionally limit python version and test filter:
make test-staging TOKEN=<your-staging-token> TEST_ENVS=py312 ADD_ARGS="-k test_catalog"
```

The token is passed as a CLI argument (`--gd-test-token`) to pytest, **not** as an environment variable.

## Run continuous integration tests
Tests in pull request (PR) are executed using docker. The following is done to make test environment as close
to reproducible as possible:
Expand Down
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ test:
for project in $(NO_CLIENT_GD_PROJECTS_DIRS); do $(MAKE) -C packages/$${project} test || RESULT=$$?; done; \
exit $$RESULT

.PHONY: test-staging
test-staging:
@test -n "$(TOKEN)" || (echo "ERROR: TOKEN is required. Usage: make test-staging TOKEN=<api-token>" && exit 1)
$(MAKE) -C packages/gooddata-sdk test-staging TOKEN=$(TOKEN)

.PHONY: clean-staging
clean-staging:
@test -n "$(TOKEN)" || (echo "ERROR: TOKEN is required. Usage: make clean-staging TOKEN=<api-token>" && exit 1)
cd packages/tests-support && STAGING=1 TOKEN="$(TOKEN)" python clean_staging.py

.PHONY: load-staging
load-staging:
@test -n "$(TOKEN)" || (echo "ERROR: TOKEN is required. Usage: make load-staging TOKEN=<api-token>" && exit 1)
cd packages/tests-support && STAGING=1 TOKEN="$(TOKEN)" python upload_demo_layout.py

.PHONY: release
release:
if [ -z "$(VERSION)" ]; then echo "Usage: 'make release VERSION=X.Y.Z'"; false; else \
Expand Down
16 changes: 14 additions & 2 deletions gooddata-api-client/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ docs/GeographicDataApi.md
docs/GetAiLakeOperation200Response.md
docs/GetImageExport202ResponseInner.md
docs/GetQualityIssuesResponse.md
docs/GetServiceStatusResponse.md
docs/GrainIdentifier.md
docs/GrantedPermission.md
docs/GranularitiesFormatting.md
Expand Down Expand Up @@ -1014,6 +1015,9 @@ docs/ListDatabaseInstancesResponse.md
docs/ListKnowledgeDocumentsResponseDto.md
docs/ListLinks.md
docs/ListLinksAllOf.md
docs/ListLlmProviderModelsRequest.md
docs/ListLlmProviderModelsRequestProviderConfig.md
docs/ListLlmProviderModelsResponse.md
docs/ListServicesResponse.md
docs/LlmModel.md
docs/LlmProviderAuth.md
Expand Down Expand Up @@ -1193,8 +1197,8 @@ docs/TabularExportRequest.md
docs/TestConnectionApi.md
docs/TestDefinitionRequest.md
docs/TestDestinationRequest.md
docs/TestLlmProviderByIdRequest.md
docs/TestLlmProviderDefinitionRequest.md
docs/TestLlmProviderDefinitionRequestProviderConfig.md
docs/TestLlmProviderResponse.md
docs/TestNotification.md
docs/TestNotificationAllOf.md
Expand All @@ -1207,6 +1211,8 @@ docs/TotalDimension.md
docs/TotalExecutionResultHeader.md
docs/TotalResultHeader.md
docs/TranslationsApi.md
docs/TrendingObjectItem.md
docs/TrendingObjectsResult.md
docs/TriggerAutomationRequest.md
docs/TriggerQualityIssuesCalculationResponse.md
docs/UpsertKnowledgeDocumentRequestDto.md
Expand Down Expand Up @@ -1708,6 +1714,7 @@ gooddata_api_client/model/geo_collection_identifier.py
gooddata_api_client/model/get_ai_lake_operation200_response.py
gooddata_api_client/model/get_image_export202_response_inner.py
gooddata_api_client/model/get_quality_issues_response.py
gooddata_api_client/model/get_service_status_response.py
gooddata_api_client/model/grain_identifier.py
gooddata_api_client/model/granted_permission.py
gooddata_api_client/model/granularities_formatting.py
Expand Down Expand Up @@ -2328,6 +2335,9 @@ gooddata_api_client/model/list_database_instances_response.py
gooddata_api_client/model/list_knowledge_documents_response_dto.py
gooddata_api_client/model/list_links.py
gooddata_api_client/model/list_links_all_of.py
gooddata_api_client/model/list_llm_provider_models_request.py
gooddata_api_client/model/list_llm_provider_models_request_provider_config.py
gooddata_api_client/model/list_llm_provider_models_response.py
gooddata_api_client/model/list_services_response.py
gooddata_api_client/model/llm_model.py
gooddata_api_client/model/llm_provider_auth.py
Expand Down Expand Up @@ -2487,8 +2497,8 @@ gooddata_api_client/model/table_warning.py
gooddata_api_client/model/tabular_export_request.py
gooddata_api_client/model/test_definition_request.py
gooddata_api_client/model/test_destination_request.py
gooddata_api_client/model/test_llm_provider_by_id_request.py
gooddata_api_client/model/test_llm_provider_definition_request.py
gooddata_api_client/model/test_llm_provider_definition_request_provider_config.py
gooddata_api_client/model/test_llm_provider_response.py
gooddata_api_client/model/test_notification.py
gooddata_api_client/model/test_notification_all_of.py
Expand All @@ -2500,6 +2510,8 @@ gooddata_api_client/model/total.py
gooddata_api_client/model/total_dimension.py
gooddata_api_client/model/total_execution_result_header.py
gooddata_api_client/model/total_result_header.py
gooddata_api_client/model/trending_object_item.py
gooddata_api_client/model/trending_objects_result.py
gooddata_api_client/model/trigger_automation_request.py
gooddata_api_client/model/trigger_quality_issues_calculation_response.py
gooddata_api_client/model/upsert_knowledge_document_request_dto.py
Expand Down
15 changes: 14 additions & 1 deletion gooddata-api-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Class | Method | HTTP request | Description
*AILakeApi* | [**deprovision_ai_lake_database_instance**](docs/AILakeApi.md#deprovision_ai_lake_database_instance) | **DELETE** /api/v1/ailake/database/instances/{instanceId} | (BETA) Delete an existing AILake Database instance
*AILakeApi* | [**get_ai_lake_database_instance**](docs/AILakeApi.md#get_ai_lake_database_instance) | **GET** /api/v1/ailake/database/instances/{instanceId} | (BETA) Get the specified AILake Database instance
*AILakeApi* | [**get_ai_lake_operation**](docs/AILakeApi.md#get_ai_lake_operation) | **GET** /api/v1/ailake/operations/{operationId} | (BETA) Get Long Running Operation details
*AILakeApi* | [**get_ai_lake_service_status**](docs/AILakeApi.md#get_ai_lake_service_status) | **GET** /api/v1/ailake/services/{serviceId}/status | (BETA) Get AI Lake service status
*AILakeApi* | [**list_ai_lake_database_instances**](docs/AILakeApi.md#list_ai_lake_database_instances) | **GET** /api/v1/ailake/database/instances | (BETA) List AI Lake Database instances
*AILakeApi* | [**list_ai_lake_services**](docs/AILakeApi.md#list_ai_lake_services) | **GET** /api/v1/ailake/services | (BETA) List AI Lake services
*AILakeApi* | [**provision_ai_lake_database_instance**](docs/AILakeApi.md#provision_ai_lake_database_instance) | **POST** /api/v1/ailake/database/instances | (BETA) Create a new AILake Database instance
Expand Down Expand Up @@ -416,11 +417,14 @@ Class | Method | HTTP request | Description
*SmartFunctionsApi* | [**generate_title**](docs/SmartFunctionsApi.md#generate_title) | **POST** /api/v1/actions/workspaces/{workspaceId}/ai/analyticsCatalog/generateTitle | Generate Title for Analytics Object
*SmartFunctionsApi* | [**get_quality_issues**](docs/SmartFunctionsApi.md#get_quality_issues) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/issues | Get Quality Issues
*SmartFunctionsApi* | [**get_quality_issues_calculation_status**](docs/SmartFunctionsApi.md#get_quality_issues_calculation_status) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/issues/status/{processId} | Get Quality Issues Calculation Status
*SmartFunctionsApi* | [**list_llm_provider_models**](docs/SmartFunctionsApi.md#list_llm_provider_models) | **POST** /api/v1/actions/ai/llmProvider/listModels | List LLM Provider Models
*SmartFunctionsApi* | [**list_llm_provider_models_by_id**](docs/SmartFunctionsApi.md#list_llm_provider_models_by_id) | **POST** /api/v1/actions/ai/llmProvider/{llmProviderId}/listModels | List LLM Provider Models By Id
*SmartFunctionsApi* | [**memory_created_by_users**](docs/SmartFunctionsApi.md#memory_created_by_users) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/memory/createdBy | Get AI Memory CreatedBy Users
*SmartFunctionsApi* | [**resolve_llm_endpoints**](docs/SmartFunctionsApi.md#resolve_llm_endpoints) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/resolveLlmEndpoints | Get Active LLM Endpoints for this workspace
*SmartFunctionsApi* | [**tags**](docs/SmartFunctionsApi.md#tags) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/analyticsCatalog/tags | Get Analytics Catalog Tags
*SmartFunctionsApi* | [**test_llm_provider**](docs/SmartFunctionsApi.md#test_llm_provider) | **POST** /api/v1/actions/ai/llmProvider/test | Test LLM Provider
*SmartFunctionsApi* | [**test_llm_provider_by_id**](docs/SmartFunctionsApi.md#test_llm_provider_by_id) | **POST** /api/v1/actions/ai/llmProvider/{llmProviderId}/test | Test LLM Provider By Id
*SmartFunctionsApi* | [**trending_objects**](docs/SmartFunctionsApi.md#trending_objects) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/analyticsCatalog/trendingObjects | Get Trending Analytics Catalog Objects
*SmartFunctionsApi* | [**trigger_quality_issues_calculation**](docs/SmartFunctionsApi.md#trigger_quality_issues_calculation) | **POST** /api/v1/actions/workspaces/{workspaceId}/ai/issues/triggerCheck | Trigger Quality Issues Calculation
*SmartFunctionsApi* | [**validate_llm_endpoint**](docs/SmartFunctionsApi.md#validate_llm_endpoint) | **POST** /api/v1/actions/ai/llmEndpoint/test | Validate LLM Endpoint
*SmartFunctionsApi* | [**validate_llm_endpoint_by_id**](docs/SmartFunctionsApi.md#validate_llm_endpoint_by_id) | **POST** /api/v1/actions/ai/llmEndpoint/{llmEndpointId}/test | Validate LLM Endpoint By Id
Expand Down Expand Up @@ -577,6 +581,8 @@ Class | Method | HTTP request | Description
*ActionsApi* | [**key_driver_analysis**](docs/ActionsApi.md#key_driver_analysis) | **POST** /api/v1/actions/workspaces/{workspaceId}/execution/computeKeyDrivers | (EXPERIMENTAL) Compute key driver analysis
*ActionsApi* | [**key_driver_analysis_result**](docs/ActionsApi.md#key_driver_analysis_result) | **GET** /api/v1/actions/workspaces/{workspaceId}/execution/computeKeyDrivers/result/{resultId} | (EXPERIMENTAL) Get key driver analysis result
*ActionsApi* | [**list_documents**](docs/ActionsApi.md#list_documents) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/knowledge/documents |
*ActionsApi* | [**list_llm_provider_models**](docs/ActionsApi.md#list_llm_provider_models) | **POST** /api/v1/actions/ai/llmProvider/listModels | List LLM Provider Models
*ActionsApi* | [**list_llm_provider_models_by_id**](docs/ActionsApi.md#list_llm_provider_models_by_id) | **POST** /api/v1/actions/ai/llmProvider/{llmProviderId}/listModels | List LLM Provider Models By Id
*ActionsApi* | [**list_workspace_user_groups**](docs/ActionsApi.md#list_workspace_user_groups) | **GET** /api/v1/actions/workspaces/{workspaceId}/userGroups |
*ActionsApi* | [**list_workspace_users**](docs/ActionsApi.md#list_workspace_users) | **GET** /api/v1/actions/workspaces/{workspaceId}/users |
*ActionsApi* | [**manage_dashboard_permissions**](docs/ActionsApi.md#manage_dashboard_permissions) | **POST** /api/v1/actions/workspaces/{workspaceId}/analyticalDashboards/{dashboardId}/managePermissions | Manage Permissions for a Dashboard
Expand Down Expand Up @@ -618,6 +624,7 @@ Class | Method | HTTP request | Description
*ActionsApi* | [**test_llm_provider**](docs/ActionsApi.md#test_llm_provider) | **POST** /api/v1/actions/ai/llmProvider/test | Test LLM Provider
*ActionsApi* | [**test_llm_provider_by_id**](docs/ActionsApi.md#test_llm_provider_by_id) | **POST** /api/v1/actions/ai/llmProvider/{llmProviderId}/test | Test LLM Provider By Id
*ActionsApi* | [**test_notification_channel**](docs/ActionsApi.md#test_notification_channel) | **POST** /api/v1/actions/notificationChannels/test | Test notification channel.
*ActionsApi* | [**trending_objects**](docs/ActionsApi.md#trending_objects) | **GET** /api/v1/actions/workspaces/{workspaceId}/ai/analyticsCatalog/trendingObjects | Get Trending Analytics Catalog Objects
*ActionsApi* | [**trigger_automation**](docs/ActionsApi.md#trigger_automation) | **POST** /api/v1/actions/workspaces/{workspaceId}/automations/trigger | Trigger automation.
*ActionsApi* | [**trigger_existing_automation**](docs/ActionsApi.md#trigger_existing_automation) | **POST** /api/v1/actions/workspaces/{workspaceId}/automations/{automationId}/trigger | Trigger existing automation.
*ActionsApi* | [**trigger_quality_issues_calculation**](docs/ActionsApi.md#trigger_quality_issues_calculation) | **POST** /api/v1/actions/workspaces/{workspaceId}/ai/issues/triggerCheck | Trigger Quality Issues Calculation
Expand Down Expand Up @@ -1527,6 +1534,7 @@ Class | Method | HTTP request | Description
- [GetAiLakeOperation200Response](docs/GetAiLakeOperation200Response.md)
- [GetImageExport202ResponseInner](docs/GetImageExport202ResponseInner.md)
- [GetQualityIssuesResponse](docs/GetQualityIssuesResponse.md)
- [GetServiceStatusResponse](docs/GetServiceStatusResponse.md)
- [GrainIdentifier](docs/GrainIdentifier.md)
- [GrantedPermission](docs/GrantedPermission.md)
- [GranularitiesFormatting](docs/GranularitiesFormatting.md)
Expand Down Expand Up @@ -2147,6 +2155,9 @@ Class | Method | HTTP request | Description
- [ListKnowledgeDocumentsResponseDto](docs/ListKnowledgeDocumentsResponseDto.md)
- [ListLinks](docs/ListLinks.md)
- [ListLinksAllOf](docs/ListLinksAllOf.md)
- [ListLlmProviderModelsRequest](docs/ListLlmProviderModelsRequest.md)
- [ListLlmProviderModelsRequestProviderConfig](docs/ListLlmProviderModelsRequestProviderConfig.md)
- [ListLlmProviderModelsResponse](docs/ListLlmProviderModelsResponse.md)
- [ListServicesResponse](docs/ListServicesResponse.md)
- [LlmModel](docs/LlmModel.md)
- [LlmProviderAuth](docs/LlmProviderAuth.md)
Expand Down Expand Up @@ -2306,8 +2317,8 @@ Class | Method | HTTP request | Description
- [TabularExportRequest](docs/TabularExportRequest.md)
- [TestDefinitionRequest](docs/TestDefinitionRequest.md)
- [TestDestinationRequest](docs/TestDestinationRequest.md)
- [TestLlmProviderByIdRequest](docs/TestLlmProviderByIdRequest.md)
- [TestLlmProviderDefinitionRequest](docs/TestLlmProviderDefinitionRequest.md)
- [TestLlmProviderDefinitionRequestProviderConfig](docs/TestLlmProviderDefinitionRequestProviderConfig.md)
- [TestLlmProviderResponse](docs/TestLlmProviderResponse.md)
- [TestNotification](docs/TestNotification.md)
- [TestNotificationAllOf](docs/TestNotificationAllOf.md)
Expand All @@ -2319,6 +2330,8 @@ Class | Method | HTTP request | Description
- [TotalDimension](docs/TotalDimension.md)
- [TotalExecutionResultHeader](docs/TotalExecutionResultHeader.md)
- [TotalResultHeader](docs/TotalResultHeader.md)
- [TrendingObjectItem](docs/TrendingObjectItem.md)
- [TrendingObjectsResult](docs/TrendingObjectsResult.md)
- [TriggerAutomationRequest](docs/TriggerAutomationRequest.md)
- [TriggerQualityIssuesCalculationResponse](docs/TriggerQualityIssuesCalculationResponse.md)
- [UpsertKnowledgeDocumentRequestDto](docs/UpsertKnowledgeDocumentRequestDto.md)
Expand Down
Loading
Loading