Merge pull request #354 from marius-bughiu/marius-bughiu-fix-issue-35… #591
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| jobs: | |
| build-and-test: | |
| name: build-and-test (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ ubuntu-latest, windows-latest, macos-latest ] | |
| defaults: | |
| run: | |
| working-directory: src | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| filter: tree:0 | |
| # All three target frameworks (#189). The SDKs provide the down-level | |
| # reference packs and the matching runtimes, so `dotnet test` exercises the | |
| # multi-targeted test project on net8.0, net9.0, and net10.0 in one pass. | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: | | |
| 8.0.x | |
| 9.0.x | |
| 10.0.x | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Build | |
| run: dotnet build --no-restore --configuration Release | |
| # The test project multi-targets net8.0;net9.0;net10.0, so a single | |
| # `dotnet test` run executes the full suite once per TFM on its own runtime. | |
| - name: Test | |
| run: dotnet test --no-build --configuration Release --verbosity normal --logger "trx;LogFileName=test-results.trx" --results-directory ./TestResults | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results-${{ matrix.os }} | |
| path: src/TestResults/*.trx | |
| if-no-files-found: warn | |
| retention-days: 7 | |
| # A dry run of the guards that stand between a tag and NuGet.org (#315). They | |
| # all live on the release path, which no PR exercises — so without this job a | |
| # breaking API change or a mis-packed package is only discovered by the nightly | |
| # preview or by the release itself, long after review. Publishing is | |
| # irreversible; the feedback belongs in the PR that causes it. | |
| release-gates: | |
| name: release-gates | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: src | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| filter: tree:0 | |
| # The CHANGELOG extraction is a shell script, so it sits outside | |
| # `dotnet test` and the coverage gate. Its size assertion is the one | |
| # guarding against an over-cap release body publishing every package and | |
| # only then failing to create the release. | |
| - name: Test the release-notes extraction gate | |
| working-directory: ${{ github.workspace }} | |
| run: ./.github/scripts/test-extract-release-notes.sh | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: | | |
| 8.0.x | |
| 9.0.x | |
| 10.0.x | |
| - name: Restore workloads | |
| run: dotnet workload restore | |
| # Packing is what runs package validation: each package is compared | |
| # against its published baseline across every TFM, and any breaking API | |
| # change fails here. See src/Directory.Build.props for the baseline-bump | |
| # ritual and the suppression escape hatch. | |
| - name: Pack (runs package validation against the published baseline) | |
| run: dotnet pack --configuration Release --output ${{ github.workspace }}/nuget -p:ContinuousIntegrationBuild=true | |
| - name: Validate packages | |
| shell: pwsh | |
| working-directory: ${{ github.workspace }} | |
| run: ./.github/scripts/validate-packages.ps1 -NuGetDirectory "${{ github.workspace }}/nuget" | |
| # The benchmark workflow only fires on `src/**`, so a dashboard-only change never | |
| # reaches the report-backed run of this same script in benchmarks.yml. These are the | |
| # structural checks, which need no measurements and cost seconds. | |
| dashboard-coverage: | |
| name: dashboard-coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| filter: tree:0 | |
| - name: Check dashboard wiring | |
| run: node scripts/check_dashboard_coverage.js | |
| # A link to an anchor that does not exist is well-formed markdown, so nothing else in | |
| # the pipeline notices it and review reliably misses it — the wrong anchor for an | |
| # entity-encoded generic heading is the *intuitive* one (#339). | |
| doc-anchors: | |
| name: doc-anchors | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| filter: tree:0 | |
| - name: Pin the slug rule against GitHub's rendering | |
| run: node scripts/check_doc_anchors.js --self-test | |
| - name: Check markdown anchors and relative links | |
| run: node scripts/check_doc_anchors.js | |
| # The benchmark relevance gate decides whether an expensive sharded A/B run happens at | |
| # all, so the C# lexer it rests on is pinned here rather than only exercised in the | |
| # workflow it gates — where a wrong answer costs either runner hours or an unmeasured | |
| # regression, and neither failure announces itself. The comment builder is pinned | |
| # alongside it for the same reason: it decides which rows are called a regression, and | |
| # a guard that is too permissive is indistinguishable from a clean report (#351). | |
| benchmark-gate: | |
| name: benchmark-gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| filter: tree:0 | |
| - name: Pin the comment-stripping lexer | |
| run: node scripts/benchmark_relevant_changes.js --self-test | |
| - name: Pin the regression-flag rule | |
| run: node scripts/benchmark_comment.js --self-test | |
| aot-publish: | |
| name: aot-publish (linux-x64, ${{ matrix.tfm }}) | |
| runs-on: ubuntu-latest | |
| # Native-AOT-publish and run the smoke test on every shipped TFM (#189), so | |
| # the AOT/trim verification covers net8.0, net9.0, and net10.0 — not just the | |
| # lowest target. | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| tfm: [ net8.0, net9.0, net10.0 ] | |
| defaults: | |
| run: | |
| working-directory: src | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| filter: tree:0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: | | |
| 8.0.x | |
| 9.0.x | |
| 10.0.x | |
| # Native AOT needs a platform linker; ubuntu-latest ships gcc/clang but the | |
| # ILCompiler links against clang + zlib, so install them explicitly. | |
| - name: Install Native AOT prerequisites | |
| run: sudo apt-get update && sudo apt-get install -y clang zlib1g-dev | |
| # Publishes the library + every generic instantiation the smoke test forces | |
| # down to a native binary, for this TFM. Fails on any AOT/trim incompatibility. | |
| - name: Publish AOT smoke test | |
| run: dotnet publish Celerity.AotSmokeTest/Celerity.AotSmokeTest.csproj -f ${{ matrix.tfm }} -r linux-x64 -c Release | |
| # Runs the native binary; its assertions exit non-zero on any behavioural | |
| # regression under AOT, so a green run proves the collections work end-to-end. | |
| - name: Run native AOT binary | |
| run: ./Celerity.AotSmokeTest/bin/Release/${{ matrix.tfm }}/linux-x64/publish/Celerity.AotSmokeTest |