Created dedicated workflows for integration tests

This commit is contained in:
Dmytro Struk
2026-02-20 16:13:56 -08:00
Unverified
parent b41dd2b6c6
commit 93930eeea4
5 changed files with 227 additions and 50 deletions
+7 -24
View File
@@ -7,18 +7,6 @@ name: dotnet-build-and-test
on:
workflow_dispatch:
workflow_call:
inputs:
checkout-ref:
description: "Git ref to checkout (e.g., a commit SHA from a PR)"
required: false
type: string
default: ""
integration-only:
description: "Run only integration tests (skip unit tests, coverage, and non-integration matrix entries)"
required: false
type: boolean
default: false
pull_request:
branches: ["main", "feature*"]
merge_group:
@@ -47,14 +35,11 @@ jobs:
contents: read
pull-requests: read
outputs:
dotnetChanges: ${{ inputs.checkout-ref != '' && 'true' || steps.filter.outputs.dotnet }}
cosmosDbChanges: ${{ inputs.checkout-ref != '' && 'true' || steps.filter.outputs.cosmosdb }}
dotnetChanges: ${{ steps.filter.outputs.dotnet }}
cosmosDbChanges: ${{ steps.filter.outputs.cosmosdb }}
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
- uses: dorny/paths-filter@v3
if: ${{ inputs.checkout-ref == '' }}
id: filter
with:
filters: |
@@ -76,7 +61,7 @@ jobs:
dotnet-build-and-test:
needs: paths-filter
if: needs.paths-filter.outputs.dotnetChanges == 'true' && (inputs.integration-only != true || matrix.integration-tests)
if: needs.paths-filter.outputs.dotnetChanges == 'true'
strategy:
fail-fast: false
matrix:
@@ -91,7 +76,6 @@ jobs:
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
persist-credentials: false
sparse-checkout: |
.
@@ -125,7 +109,7 @@ jobs:
shell: bash
# All frameworks are only built for the release configuration, so we only run this step for the release configuration
# and dotnet new doesn't support net472
if: inputs.integration-only != true && matrix.configuration == 'Release' && matrix.targetFramework != 'net472'
if: matrix.configuration == 'Release' && matrix.targetFramework != 'net472'
run: |
TEMP_DIR=$(mktemp -d)
@@ -157,7 +141,6 @@ jobs:
rm -rf "$TEMP_DIR"
- name: Run Unit Tests
if: inputs.integration-only != true
shell: bash
run: |
export UT_PROJECTS=$(find ./dotnet -type f -name "*.UnitTests.csproj" | tr '\n' ' ')
@@ -239,7 +222,7 @@ jobs:
# Generate test reports and check coverage
- name: Generate test reports
if: inputs.integration-only != true && matrix.targetFramework == env.COVERAGE_FRAMEWORK
if: matrix.targetFramework == env.COVERAGE_FRAMEWORK
uses: danielpalme/ReportGenerator-GitHub-Action@5.5.1
with:
reports: "./TestResults/Coverage/**/coverage.cobertura.xml"
@@ -247,14 +230,14 @@ jobs:
reporttypes: "HtmlInline;JsonSummary"
- name: Upload coverage report artifact
if: inputs.integration-only != true && matrix.targetFramework == env.COVERAGE_FRAMEWORK
if: matrix.targetFramework == env.COVERAGE_FRAMEWORK
uses: actions/upload-artifact@v6
with:
name: CoverageReport-${{ matrix.os }}-${{ matrix.targetFramework }}-${{ matrix.configuration }} # Artifact name
path: ./TestResults/Reports # Directory containing files to upload
- name: Check coverage
if: inputs.integration-only != true && matrix.targetFramework == env.COVERAGE_FRAMEWORK
if: matrix.targetFramework == env.COVERAGE_FRAMEWORK
shell: pwsh
run: .github/workflows/dotnet-check-coverage.ps1 -JsonReportPath "TestResults/Reports/Summary.json" -CoverageThreshold $env:COVERAGE_THRESHOLD
@@ -0,0 +1,102 @@
#
# Dedicated .NET integration tests workflow, called from the manual integration test orchestrator.
# Only runs integration test matrix entries (net10.0 and net472). No unit tests, no coverage.
#
name: dotnet-integration-tests
on:
workflow_call:
inputs:
checkout-ref:
description: "Git ref to checkout (e.g., refs/pull/123/head)"
required: true
type: string
permissions:
contents: read
id-token: write
jobs:
dotnet-integration-tests:
strategy:
fail-fast: false
matrix:
include:
- { targetFramework: "net10.0", os: "ubuntu-latest", configuration: Release }
- { targetFramework: "net472", os: "windows-latest", configuration: Release }
runs-on: ${{ matrix.os }}
environment: integration
timeout-minutes: 60
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
persist-credentials: false
sparse-checkout: |
.
.github
dotnet
python
workflow-samples
- name: Start Azure Cosmos DB Emulator
if: runner.os == 'Windows'
shell: pwsh
run: |
Write-Host "Launching Azure Cosmos DB Emulator"
Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator"
Start-CosmosDbEmulator -NoUI -Key "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
echo "COSMOS_EMULATOR_AVAILABLE=true" >> $env:GITHUB_ENV
- name: Setup dotnet
uses: actions/setup-dotnet@v5.1.0
with:
global-json-file: ${{ github.workspace }}/dotnet/global.json
- name: Build dotnet solutions
shell: bash
run: |
export SOLUTIONS=$(find ./dotnet/ -type f -name "*.slnx" | tr '\n' ' ')
for solution in $SOLUTIONS; do
dotnet build $solution -c ${{ matrix.configuration }} --warnaserror
done
- name: Azure CLI Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Set up Durable Task and Azure Functions Integration Test Emulators
if: matrix.os == 'ubuntu-latest'
uses: ./.github/actions/azure-functions-integration-setup
- name: Run Integration Tests
shell: bash
run: |
export INTEGRATION_TEST_PROJECTS=$(find ./dotnet -type f -name "*IntegrationTests.csproj" | tr '\n' ' ')
for project in $INTEGRATION_TEST_PROJECTS; do
target_frameworks=$(dotnet msbuild $project -getProperty:TargetFrameworks -p:Configuration=${{ matrix.configuration }} -nologo 2>/dev/null | tr -d '\r')
if [[ "$target_frameworks" == *"${{ matrix.targetFramework }}"* ]]; then
dotnet test -f ${{ matrix.targetFramework }} -c ${{ matrix.configuration }} $project --no-build -v Normal --logger trx --filter "Category!=IntegrationDisabled"
else
echo "Skipping $project - does not support target framework ${{ matrix.targetFramework }} (supports: $target_frameworks)"
fi
done
env:
COSMOSDB_ENDPOINT: https://localhost:8081
COSMOSDB_KEY: C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==
OpenAI__ApiKey: ${{ secrets.OPENAI__APIKEY }}
OpenAI__ChatModelId: ${{ vars.OPENAI__CHATMODELID }}
OpenAI__ChatReasoningModelId: ${{ vars.OPENAI__CHATREASONINGMODELID }}
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: ${{ vars.AZUREOPENAI__CHATDEPLOYMENTNAME }}
AZURE_OPENAI_ENDPOINT: ${{ vars.AZUREOPENAI__ENDPOINT }}
AzureAI__Endpoint: ${{ secrets.AZUREAI__ENDPOINT }}
AzureAI__DeploymentName: ${{ vars.AZUREAI__DEPLOYMENTNAME }}
AzureAI__BingConnectionId: ${{ vars.AZUREAI__BINGCONECTIONID }}
FOUNDRY_PROJECT_ENDPOINT: ${{ vars.FOUNDRY_PROJECT_ENDPOINT }}
FOUNDRY_MEDIA_DEPLOYMENT_NAME: ${{ vars.FOUNDRY_MEDIA_DEPLOYMENT_NAME }}
FOUNDRY_MODEL_DEPLOYMENT_NAME: ${{ vars.FOUNDRY_MODEL_DEPLOYMENT_NAME }}
FOUNDRY_CONNECTION_GROUNDING_TOOL: ${{ vars.FOUNDRY_CONNECTION_GROUNDING_TOOL }}
@@ -2,7 +2,7 @@
# This workflow allows manually running integration tests against an open PR or a branch.
# Go to Actions → "Integration Tests (Manual)" → Run workflow → enter a PR number or branch name.
#
# It reuses the existing dotnet-build-and-test and python-merge-tests workflows,
# It calls dedicated integration-only workflows (dotnet-integration-tests and python-integration-tests),
# passing a ref so they check out and test the correct code.
# Changed paths are detected here so only the relevant test suites run.
#
@@ -119,18 +119,16 @@ jobs:
name: .NET Integration Tests
needs: resolve-ref
if: needs.resolve-ref.outputs.dotnet-changes == 'true'
uses: ./.github/workflows/dotnet-build-and-test.yml
uses: ./.github/workflows/dotnet-integration-tests.yml
with:
checkout-ref: ${{ needs.resolve-ref.outputs.checkout-ref }}
integration-only: true
secrets: inherit
python-integration-tests:
name: Python Integration Tests
needs: resolve-ref
if: needs.resolve-ref.outputs.python-changes == 'true'
uses: ./.github/workflows/python-merge-tests.yml
uses: ./.github/workflows/python-integration-tests.yml
with:
checkout-ref: ${{ needs.resolve-ref.outputs.checkout-ref }}
integration-only: true
secrets: inherit
@@ -0,0 +1,112 @@
#
# Dedicated Python integration tests workflow, called from the manual integration test orchestrator.
# Only runs integration tests (core + Azure AI). No sample tests, no paths filtering.
#
name: python-integration-tests
on:
workflow_call:
inputs:
checkout-ref:
description: "Git ref to checkout (e.g., refs/pull/123/head)"
required: true
type: string
permissions:
contents: read
id-token: write
env:
UV_CACHE_DIR: /tmp/.uv-cache
jobs:
python-tests-core:
name: Python Integration Tests - Core
runs-on: ubuntu-latest
environment: integration
timeout-minutes: 60
env:
UV_PYTHON: "3.10"
OPENAI_CHAT_MODEL_ID: ${{ vars.OPENAI__CHATMODELID }}
OPENAI_RESPONSES_MODEL_ID: ${{ vars.OPENAI__RESPONSESMODELID }}
OPENAI_API_KEY: ${{ secrets.OPENAI__APIKEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
ANTHROPIC_CHAT_MODEL_ID: ${{ vars.ANTHROPIC_CHAT_MODEL_ID }}
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: ${{ vars.AZUREOPENAI__CHATDEPLOYMENTNAME }}
AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME: ${{ vars.AZUREOPENAI__RESPONSESDEPLOYMENTNAME }}
AZURE_OPENAI_ENDPOINT: ${{ vars.AZUREOPENAI__ENDPOINT }}
LOCAL_MCP_URL: ${{ vars.LOCAL_MCP__URL }}
FUNCTIONS_WORKER_RUNTIME: "python"
DURABLE_TASK_SCHEDULER_CONNECTION_STRING: "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
AzureWebJobsStorage: "UseDevelopmentStorage=true"
defaults:
run:
working-directory: python
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
- name: Set up python and install the project
id: python-setup
uses: ./.github/actions/python-setup
with:
python-version: "3.10"
os: ${{ runner.os }}
env:
UV_CACHE_DIR: /tmp/.uv-cache
- name: Azure CLI Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Set up Azure Functions Integration Test Emulators
uses: ./.github/actions/azure-functions-integration-setup
id: azure-functions-setup
- name: Test with pytest
run: uv run poe all-tests -n logical --dist loadfile --dist worksteal --timeout=120 --session-timeout=900 --timeout_method thread --retries 2 --retry-delay 5
working-directory: ./python
python-tests-azure-ai:
name: Python Integration Tests - Azure AI
runs-on: ubuntu-latest
environment: integration
timeout-minutes: 60
env:
UV_PYTHON: "3.10"
AZURE_AI_PROJECT_ENDPOINT: ${{ secrets.AZUREAI__ENDPOINT }}
AZURE_AI_MODEL_DEPLOYMENT_NAME: ${{ vars.AZUREAI__DEPLOYMENTNAME }}
LOCAL_MCP_URL: ${{ vars.LOCAL_MCP__URL }}
defaults:
run:
working-directory: python
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
- name: Set up python and install the project
id: python-setup
uses: ./.github/actions/python-setup
with:
python-version: "3.10"
os: ${{ runner.os }}
env:
UV_CACHE_DIR: /tmp/.uv-cache
- name: Azure CLI Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Test with pytest
timeout-minutes: 15
run: uv run --directory packages/azure-ai poe integration-tests -n logical --dist loadfile --dist worksteal --timeout=120 --session-timeout=900 --timeout_method thread --retries 2 --retry-delay 5
working-directory: ./python
+3 -21
View File
@@ -2,18 +2,6 @@ name: Python - Merge - Tests
on:
workflow_dispatch:
workflow_call:
inputs:
checkout-ref:
description: "Git ref to checkout (e.g., a commit SHA from a PR)"
required: false
type: string
default: ""
integration-only:
description: "Run only integration tests (skip sample tests)"
required: false
type: boolean
default: false
pull_request:
branches: ["main"]
merge_group:
@@ -38,12 +26,10 @@ jobs:
contents: read
pull-requests: read
outputs:
pythonChanges: ${{ inputs.checkout-ref != '' && 'true' || steps.filter.outputs.python }}
pythonChanges: ${{ steps.filter.outputs.python }}
steps:
- uses: actions/checkout@v6
if: ${{ inputs.checkout-ref == '' }}
- uses: dorny/paths-filter@v3
if: ${{ inputs.checkout-ref == '' }}
id: filter
with:
filters: |
@@ -90,8 +76,6 @@ jobs:
working-directory: python
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
- name: Set up python and install the project
id: python-setup
uses: ./.github/actions/python-setup
@@ -116,7 +100,7 @@ jobs:
working-directory: ./python
- name: Test core samples
timeout-minutes: 10
if: inputs.integration-only != true && env.RUN_SAMPLES_TESTS == 'true'
if: env.RUN_SAMPLES_TESTS == 'true'
run: uv run pytest tests/samples/ -m "openai" -m "azure"
working-directory: ./python
- name: Surface failing tests
@@ -151,8 +135,6 @@ jobs:
working-directory: python
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.checkout-ref }}
- name: Set up python and install the project
id: python-setup
uses: ./.github/actions/python-setup
@@ -175,7 +157,7 @@ jobs:
working-directory: ./python
- name: Test Azure AI samples
timeout-minutes: 10
if: inputs.integration-only != true && env.RUN_SAMPLES_TESTS == 'true'
if: env.RUN_SAMPLES_TESTS == 'true'
run: uv run pytest tests/samples/ -m "azure-ai"
working-directory: ./python
- name: Surface failing tests