name: Build and Test .NET 10.0 on: push: branches: [ master, main, develop/* ] pull_request: branches: [ master, main, develop/* ] paths: - '**.cs' - '**.csproj' permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: discover: name: Discover test projects runs-on: ubuntu-latest outputs: csprojs: ${{ steps.list.outputs.csprojs }} steps: - uses: actions/checkout@v6 - name: Enumerate Tests/Opc.Ua.*.Tests projects id: list shell: pwsh run: | # Discover test projects from the filesystem so this matrix does # not have to be hand-maintained as projects are added/renamed. # Projects whose name is in EXCLUDE are run by other workflows # (AOT has its own workflow; the Stress suite is opt-in via the # stress-test workflow). $exclude = @('Aot', 'Stress') $projects = Get-ChildItem -Path Tests -Directory -Filter 'Opc.Ua.*.Tests' | Where-Object { Test-Path (Join-Path $_.FullName "$($_.Name).csproj") } | ForEach-Object { $_.Name -replace '^Opc\.Ua\.', '' -replace '\.Tests$', '' } | Where-Object { $exclude -notcontains $_ } | Sort-Object $json = ConvertTo-Json -InputObject @($projects) -Compress Write-Host "Discovered $(@($projects).Count) project(s): $json" "csprojs=$json" | Out-File -FilePath $env:GITHUB_OUTPUT -Append build-and-test: needs: discover name: test-${{matrix.os}}-${{matrix.csproj}} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: # os: [ubuntu-latest, windows-latest, macOS-latest] - disable mac os due to cost os: [ubuntu-latest, windows-latest] csproj: ${{ fromJSON(needs.discover.outputs.csprojs) }} include: - framework: 'net10.0' dotnet-version: '10.0.x' configuration: 'Release' customtesttarget: net10.0 env: OS: ${{ matrix.os }} DOTNET_VERSION: ${{ matrix.dotnet-version }} CONFIGURATION: ${{ matrix.configuration }} CSPROJ: ${{ matrix.csproj }} CSPROJECT: "./Tests/Opc.Ua.${{ matrix.csproj }}.Tests/Opc.Ua.${{ matrix.csproj }}.Tests.csproj" TESTRESULTS: "TestResults-${{matrix.csproj}}-${{matrix.os}}-${{matrix.framework}}-${{matrix.configuration}}" steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Setup .NET ${{ matrix.dotnet-version }} uses: actions/setup-dotnet@v5 with: dotnet-version: ${{ matrix.dotnet-version }} - name: Set Cloud Version shell: pwsh run: ./.azurepipelines/set-version.ps1 - name: Build run: dotnet build ${{ env.CSPROJECT }} --framework ${{ matrix.framework }} --configuration ${{ matrix.configuration }} /p:CustomTestTarget=${{ matrix.customtesttarget }} /p:UseSharedCompilation=false -maxcpucount:1 - name: Test # note: /p:CollectCoverage=true is only used to disable deterministic builds shell: pwsh run: | $testArgs = @( '${{ env.CSPROJECT }}', '--no-build', '--framework', '${{ matrix.framework }}', '--logger', 'trx', '--configuration', '${{ matrix.configuration }}', '/p:CollectCoverage=true', '/p:CustomTestTarget=${{ matrix.customtesttarget }}', '--collect:XPlat Code Coverage', '--settings', './Tests/coverlet.runsettings.xml', '--results-directory', '${{ env.TESTRESULTS }}') if ('${{ matrix.csproj }}' -eq 'Channels.Stress') { $testArgs += @('--filter', '(Category=Contract|Category=Integration)&Category!=ChaosTCP&Category!=Soak') } dotnet test @testArgs - name: Upload test results uses: actions/upload-artifact@v7 with: name: dotnet-results-${{matrix.csproj}}-${{matrix.os}}-${{matrix.framework}}-${{matrix.configuration}} path: ${{ env.TESTRESULTS }} # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} - name: Upload to Codecov uses: codecov/codecov-action@v6 with: name: codecov-umbrella token: ${{ secrets.CODECOV_TOKEN }} directory: ${{ env.TESTRESULTS }} env_vars: CSPROJ,OS,DOTNET_VERSION,CONFIGURATION fail_ci_if_error: false #path_to_write_report: "./coverage/codecov_report-${{matrix.os}}-${{matrix.framework}}-${{matrix.configuration}}/" verbose: true # Use always() to always run this step to publish test results when there are test failures if: ${{ always() }} aot-test: name: aot-${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] include: - dotnet-version: '10.0.x' configuration: 'Release' env: AOTPROJECT: './Tests/Opc.Ua.Aot.Tests/Opc.Ua.Aot.Tests.csproj' steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Setup .NET ${{ matrix.dotnet-version }} uses: actions/setup-dotnet@v5 with: dotnet-version: ${{ matrix.dotnet-version }} - name: Set Cloud Version shell: pwsh run: ./.azurepipelines/set-version.ps1 - name: Publish NativeAOT run: dotnet publish ${{ env.AOTPROJECT }} --configuration ${{ matrix.configuration }} - name: Run NativeAOT Tests (Linux) if: runner.os == 'Linux' run: ./Tests/Opc.Ua.Aot.Tests/bin/${{ matrix.configuration }}/net10.0/linux-x64/publish/Opc.Ua.Aot.Tests - name: Run NativeAOT Tests (Windows) if: runner.os == 'Windows' run: ./Tests/Opc.Ua.Aot.Tests/bin/${{ matrix.configuration }}/net10.0/win-x64/publish/Opc.Ua.Aot.Tests.exe - name: Upload test results uses: actions/upload-artifact@v7 with: name: aot-results-${{ matrix.os }} path: '**/TestResults/**' if: ${{ always() }} - name: Upload HTML Test Report uses: actions/upload-artifact@v7 with: name: TestReport-aot-${{ matrix.os }} path: '**/*-report.html' if: ${{ always() }}