name: CI on: push: branches: - master - release-* pull_request: workflow_dispatch: env: DOTNET_NOLOGO: true defaults: run: shell: pwsh concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: name: ${{ matrix.os-name }}-${{ matrix.test-category }} runs-on: ${{ matrix.os }} strategy: matrix: os: [windows-latest, ubuntu-latest] # Categories are declared by the property in each test project. A category can # span several projects that share infrastructure, so that the container is provisioned once # and the union of their build closures is compiled once. test-category: [ DefaultCore, DefaultMonitoring, Raven, SqlServer, PostgreSql, RabbitMQ, AzureServiceBus, AzureStorageQueues, MSMQ, SQS, IBMMQ ] include: - os: windows-latest os-name: Windows - os: ubuntu-latest os-name: Linux # How many of a category's assemblies run at once, so that a multi-project category costs the # slowest of them rather than the sum. Defaults to 1 where unset. Dial down if the shared # infrastructure turns out not to tolerate the concurrency. - test-category: Raven max-parallel: 3 - test-category: RabbitMQ max-parallel: 4 - test-category: SqlServer max-parallel: 3 - test-category: PostgreSql max-parallel: 3 exclude: - os: ubuntu-latest test-category: MSMQ fail-fast: false steps: - name: Check for secrets env: SECRETS_AVAILABLE: ${{ secrets.SECRETS_AVAILABLE }} run: exit $(If ($env:SECRETS_AVAILABLE -eq 'true') { 0 } Else { 1 }) - name: Checkout uses: actions/checkout@v7.0.1 with: fetch-depth: 0 - name: Setup .NET SDK uses: actions/setup-dotnet@v6.0.0 with: global-json-file: global.json - name: Determine runtime version shell: pwsh run: | # Read settings from Custom.Build.props [xml]$xml = Get-Content ./src/Custom.Build.props $runtimeVersion = $xml.selectNodes('/Project/PropertyGroup/RuntimeFrameworkVersion').InnerText if (-not ($runtimeVersion)) { throw "Missing RuntimeFrameworkVersion setting in Custom.Build.props" } echo "RuntimeVersion=$runtimeVersion" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append - name: Install .NET Runtime on Windows if: matrix.os-name == 'Windows' run: | ./tools/dotnet-install.ps1 -SkipNonVersionedFiles -InstallDir "C:\Program Files\dotnet" -Runtime dotnet -Version ${{ env.RuntimeVersion }} ./tools/dotnet-install.ps1 -SkipNonVersionedFiles -InstallDir "C:\Program Files\dotnet" -Runtime aspnetcore -Version ${{ env.RuntimeVersion }} ./tools/dotnet-install.ps1 -SkipNonVersionedFiles -InstallDir "C:\Program Files\dotnet" -Runtime windowsdesktop -Version ${{ env.RuntimeVersion }} - name: Install .NET Runtime on Linux if: matrix.os-name == 'Linux' shell: bash run: | ./tools/dotnet-install.sh --skip-non-versioned-files --install-dir /usr/share/dotnet --runtime dotnet --version ${{ env.RuntimeVersion }} ./tools/dotnet-install.sh --skip-non-versioned-files --install-dir /usr/share/dotnet --runtime aspnetcore --version ${{ env.RuntimeVersion }} - name: Select test projects id: select run: ./tools/select-test-projects.ps1 -Category ${{ matrix.test-category }} - name: Download RavenDB Server if: matrix.test-category == 'DefaultCore' run: ./tools/download-ravendb-server.ps1 - name: Build id: build background: true run: dotnet build tests.proj --configuration Release -graph # Provisions the WSL2 Docker host that the SQL Server, PostgreSQL, RabbitMQ and IBM MQ containers # run in on Windows. A no-op on Linux, but still run there so those actions see the same # environment variables on both runners. - name: Setup WSL if: contains(fromJSON('["RabbitMQ", "SqlServer", "PostgreSql", "IBMMQ"]'), matrix.test-category) uses: Particular/setup-wsl-action@v1.2.0 with: # The action defaults to 4GB. The runner has 16GB and the build runs concurrently with the # container starting up, so give the VM real headroom. memory: 8GB # there is an issue with az cli and python 3.14, so for now we need to pin it # once the issue is resolved it should be able to be re-floated # https://github.com/Azure/azure-cli/issues/32980. # This can be removed once https://github.com/Azure/azure-cli/issues/32869 is supported. - name: Set Python 3.13 (Linux) if: matrix.os-name == 'Linux' && matrix.test-category == 'AzureServiceBus' uses: actions/setup-python@v5 with: python-version: '3.13' - name: Install pinned Azure CLI on Python 3.13 (Linux) if: matrix.os-name == 'Linux' && matrix.test-category == 'AzureServiceBus' shell: bash run: | python -m pip install --upgrade pip python -m pip install --user "azure-cli==2.64.0" echo "$HOME/.local/bin" >> "$GITHUB_PATH" - name: Setup SQL Server uses: Particular/install-sql-server-action@v3.0.0 if: matrix.test-category == 'SqlServer' with: connection-string-env-var: ServiceControl_Persistence_SqlServer_ConnectionString catalog: ServiceControl enable-full-text-search: true - name: Point the SQL Server transport tests at the same server if: matrix.test-category == 'SqlServer' run: echo "ServiceControl_TransportTests_SQL_ConnectionString=$Env:ServiceControl_Persistence_SqlServer_ConnectionString" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append - name: Setup PostgreSQL uses: Particular/setup-postgres-action@v3.0.0 if: matrix.test-category == 'PostgreSql' with: connection-string-name: ServiceControl_Persistence_PostgreSql_ConnectionString registry-username: ${{ secrets.DOCKERHUB_USERNAME }} registry-password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Point the PostgreSQL transport tests at the same server if: matrix.test-category == 'PostgreSql' run: echo "ServiceControl_TransportTests_PostgreSQL_ConnectionString=$Env:ServiceControl_Persistence_PostgreSql_ConnectionString" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append - name: Setup RabbitMQ uses: Particular/setup-rabbitmq-action@v2.0.0 if: matrix.test-category == 'RabbitMQ' with: connection-string-name: ServiceControl_TransportTests_RabbitMQ_ConnectionString registry-username: ${{ secrets.DOCKERHUB_USERNAME }} registry-password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Setup IBM MQ uses: Particular/setup-ibmmq-action@v1.0.0 if: matrix.test-category == 'IBMMQ' with: connection-string-name: ServiceControl_TransportTests_IBMMQ_ConnectionString - name: Setup SQS environment variables if: matrix.test-category == 'SQS' run: | echo "AWS_REGION=${{ secrets.AWS_REGION }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append # Cleanup of queues starting with `GHA-` handled by https://github.com/Particular/NServiceBus.AmazonSQS/blob/master/.github/workflows/tests-cleanup.yml $connectString = "AccessKeyId=${{ secrets.AWS_ACCESS_KEY_ID }};SecretAccessKey=${{ secrets.AWS_SECRET_ACCESS_KEY }};Region=${{ secrets.AWS_REGION }};QueueNamePrefix=GHA-${{ github.run_id }}" echo "ServiceControl_TransportTests_SQS_ConnectionString=$connectString" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append # Everything above provisions local containers, so it overlaps the build freely. The Azure steps # below create real cloud resources, so they sit behind the wait too. - name: Wait for build wait: build - name: Azure login uses: azure/login@v3.0.2 if: matrix.test-category == 'AzureServiceBus' || matrix.test-category == 'AzureStorageQueues' with: creds: ${{ secrets.AZURE_ACI_CREDENTIALS }} - name: Setup Azure Service Bus uses: Particular/setup-azureservicebus-action@v2.5.0 if: matrix.test-category == 'AzureServiceBus' with: connection-string-name: ServiceControl_TransportTests_ASBS_ConnectionString azure-credentials: ${{ secrets.AZURE_ACI_CREDENTIALS }} tag: ServiceControl - name: Setup Azure Storage Queues uses: Particular/setup-azurestorage-action@v2.0.0 if: matrix.test-category == 'AzureStorageQueues' with: connection-string-name: ServiceControl_TransportTests_ASQ_ConnectionString azure-credentials: ${{ secrets.AZURE_ACI_CREDENTIALS }} tag: ServiceControl - name: Run tests run: ./tools/run-tests.ps1 -Projects $Env:TEST_PROJECTS -MaxParallel ${{ matrix.max-parallel || 1 }} env: TEST_PROJECTS: ${{ steps.select.outputs.test-projects }} ServiceControl_TESTS_FILTER: ${{ matrix.test-category }} PARTICULARSOFTWARE_LICENSE: ${{ secrets.LICENSETEXT }} AZURE_ACI_CREDENTIALS: ${{ secrets.AZURE_ACI_CREDENTIALS }} compile: name: ${{ matrix.os-name }}-Compile runs-on: ${{ matrix.os }} strategy: matrix: include: - os: windows-latest os-name: Windows - os: ubuntu-latest os-name: Linux fail-fast: false steps: - name: Check for secrets env: SECRETS_AVAILABLE: ${{ secrets.SECRETS_AVAILABLE }} run: exit $(If ($env:SECRETS_AVAILABLE -eq 'true') { 0 } Else { 1 }) - name: Checkout uses: actions/checkout@v7.0.1 with: fetch-depth: 0 - name: Setup .NET SDK uses: actions/setup-dotnet@v6.0.0 with: global-json-file: global.json - name: Download RavenDB Server run: ./tools/download-ravendb-server.ps1 - name: Build run: dotnet build src --configuration Release -graph windows-installers: uses: ./.github/workflows/build-windows.yml secrets: inherit containers: uses: ./.github/workflows/build-containers.yml secrets: inherit db-container: uses: ./.github/workflows/build-db-container.yml secrets: inherit # See /src/container-integration-test/README.md container-test: needs: [ 'containers', 'db-container' ] uses: ./.github/workflows/container-integration-test.yml secrets: inherit