docs: accept ADR-0069 and repoint the cross-repository ADR links #965
Workflow file for this run
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: analyzers | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| # Cancel superseded runs on the same branch / PR. | |
| concurrency: | |
| group: analyzers-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| # Least privilege: this workflow only checks out and builds, so the token | |
| # needs nothing beyond read access to the repository contents. | |
| permissions: | |
| contents: read | |
| env: | |
| DOTNET_NOLOGO: 'true' | |
| DOTNET_CLI_TELEMETRY_OPTOUT: 'true' | |
| DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 'true' | |
| jobs: | |
| dogfood: | |
| name: Dogfood analyzers | |
| runs-on: ubuntu-latest | |
| # Dogfood build is ~30s; a generous cap over a hung run. | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 | |
| with: | |
| dotnet-version: '10.0.x' | |
| # Dogfood: build the sample with the analyzers wired in (FirstClassErrors.Usage.csproj references | |
| # them with OutputItemType=Analyzer). Fails the build on any Error-severity FCExxx diagnostic and | |
| # surfaces the warnings in the log. The analyzer unit-test suite itself runs as part of the ci | |
| # workflow, which builds and tests the whole solution. | |
| - name: Build usage (dogfood analyzers) | |
| run: dotnet build FirstClassErrors.Usage/FirstClassErrors.Usage.csproj -c Release | |
| floor: | |
| name: Dogfood analyzers on the Roslyn floor | |
| runs-on: ubuntu-latest | |
| # Downloads the floor SDK then builds (~1 min); cap a hung run. | |
| timeout-minutes: 15 | |
| env: | |
| # Single source of truth for the throwaway package version, passed to BOTH the pack (-p:Version) and | |
| # the consume (-p:FloorCheckVersion) steps. The run-number.attempt suffix makes every run produce a | |
| # version NuGet has never cached, so the consume step always restores the freshly packed .nupkg instead | |
| # of a stale copy from ~/.nuget/packages; run_attempt (which changes on a re-run, unlike run_number) | |
| # closes the door should a ~/.nuget cache ever be added to this job. Dot separators keep the numeric | |
| # identifiers ordered numerically per SemVer. FloorCheck.csproj pins this EXACT version (not a float), | |
| # so it can only resolve the local feed's package — never a future stable FirstClassErrors on nuget.org. | |
| FLOORCHECK_VERSION: 1.0.0-floorcheck.${{ github.run_number }}.${{ github.run_attempt }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup SDKs (release + floor) | |
| uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 | |
| with: | |
| # Two SDKs on purpose. 10.0.x is the SDK release.yml packs with, so the pack step below produces | |
| # the exact artifact consumers receive. 8.0.100 (Roslyn 4.8.0 == VS 2022 17.8) is the oldest | |
| # supported host; the consume step builds against that package under it. 8.0.x is avoided because a | |
| # later feature band bundles a Roslyn newer than the floor. The nested global.json (rollForward: | |
| # disable) pins the consume step to 8.0.100; the pack picks 10.0.x via the repo-root global.json. | |
| dotnet-version: | | |
| 10.0.x | |
| 8.0.100 | |
| - name: Pack FirstClassErrors (with bundled analyzer) under the RELEASE SDK | |
| # Pack from the repo root so the root global.json selects the .NET 10 SDK — the one release.yml packs | |
| # with — producing the exact artifact a consumer restores, analyzer bundled at analyzers/dotnet/cs by | |
| # FirstClassErrors.csproj's _AddAnalyzerToPackage target. Packing under the floor SDK instead would | |
| # test an analyzer nobody ships and would pin the whole library to C# 12 (LangVersion latest under | |
| # SDK 8). The feed and the project-local package cache (RestorePackagesPath in FloorCheck.csproj) | |
| # are wiped first so the consume step can only see this run's package — a no-op on a fresh CI | |
| # runner, but it keeps a reused/local workspace idempotent instead of accumulating stale packages. | |
| run: | | |
| rm -rf tools/floor-check/local-feed tools/floor-check/packages | |
| dotnet pack FirstClassErrors/FirstClassErrors.csproj -c Release -p:Version="$FLOORCHECK_VERSION" -o tools/floor-check/local-feed | |
| - name: Consume the package on the floor SDK | |
| # tools/floor-check/global.json selects the .NET 8 (Roslyn 4.8) SDK: SDK resolution is CWD-based, so | |
| # running from this directory is what makes the CLI pick the nested pin. This is the real test — the | |
| # shipped analyzer, loaded by the oldest supported compiler. -p:FloorCheckVersion pins the exact | |
| # package this run packed. ReportAnalyzer AND detailed verbosity are both required for Roslyn's | |
| # per-analyzer table to reach the log (silent at default verbosity); --no-incremental guarantees a | |
| # real compilation so that table is always produced. The (verbose) log is echoed only on failure. | |
| working-directory: tools/floor-check | |
| run: dotnet build -c Release --no-incremental -p:FloorCheckVersion="$FLOORCHECK_VERSION" -p:ReportAnalyzer=true -v detailed > build.log 2>&1 || { cat build.log; exit 1; } | |
| - name: Prove the analyzer actually loaded | |
| # A never-loaded analyzer would otherwise leave the build green: CS8032 is emitted only when loading | |
| # is attempted. The assembly name alone appears in ordinary build lines ("FirstClassErrors.Analyzers -> | |
| # ...dll" / paths), so match a fully-qualified analyzer *type* (`...<Name>Analyzer`): it appears only in | |
| # the ReportAnalyzer table, i.e. only if the analyzer really loaded and ran. The pattern deliberately | |
| # does not depend on the trailing diagnostic-id list, which is a Roslyn-version formatting detail. | |
| working-directory: tools/floor-check | |
| run: grep -qE 'FirstClassErrors\.Analyzers\.[A-Za-z]+Analyzer' build.log | |
| readme-count: | |
| name: Guard the advertised analyzer count | |
| runs-on: ubuntu-latest | |
| # Reads two tracked files with a POSIX shell; seconds. Cap a stuck runner. | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| # Derive the count and FCExxx range from DiagnosticIds.cs (the source of | |
| # truth) and fail if the package README's flagship "N Roslyn analyzers in | |
| # the box (FCE001-FCENNN)" bullet disagrees — the claim that drifted to a | |
| # stale 16 while the code shipped 22. | |
| - name: Check the package README count against DiagnosticIds.cs | |
| run: tools/analyzer-count-check/check-analyzer-count.sh |