Skip to content

ci: adopt the consolidated .NET workflow - #229

Merged
matt-edmondson merged 1 commit into
mainfrom
claude/happy-rubin-w67sx1
Sep 14, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
claude/happy-rubin-w67sx1

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Every ktsu .NET repository carried its own copy of .github/workflows/dotnet.yml, and they had drifted into five different files. This adopts the one canonical workflow, byte-identical across the org — folding the drift in rather than flattening it.

variant repositories what was different
ed23a97 (18,495 b) 43, including this one the baseline
f59a33a (18,653 b) AppDataStorage, Extensions, KtsuTools stale comments — one repository's measurements presented as the shared rule
c47b195 (18,775 b) KtsuBuild half of the above
30fbfeb (19,681 b) Schema extra test runtimes; an extra coverage exclusion
cb1dbdc (25,807 b) ImGuiApp macOS matrix, Linux-only UI tests, coverage-path rewrite, Sonar outage probe

Sdk, VST and ByteSizeDotnet have no dotnet.yml and are untouched.

What this repository gains

  • macOS is back in the test matrix. It had been excluded org-wide because a macOS runner widened one repository's target frameworks to include a net10.0-ios head needing a workload this job does not install, so every macOS cell failed with NETSDK1147. That widening is now opt-in, so every other repository stops paying for a problem it never had — as the old comment itself prescribed: "excluded until the underlying problem is fixed rather than papered over".
  • The UI-test rule names Linux rather than Windows, so a platform added later gets the cheap treatment by default instead of silently inheriting the expensive one. A repository with no UI test project matches nothing here either way.
  • The Linux coverage report's paths are rewritten to the analysis job's workspace. Sonar matches coverage to source by path, so Linux-produced coverage was being dropped without a word. No-ops where there is no Linux report.
  • The test and release jobs install the 8.0 and 9.0 runtimes alongside the pinned SDK, because test projects commonly multi-target every framework their library publishes. global.json still pins the SDK, so this adds runtimes without changing what builds.
  • A SonarQube Cloud outage skips analysis instead of failing the build. The scanner fails in pre-processing, before anything is compiled, so an outage turned every pull request red while saying nothing about the change. The probe runs before the Sonar caches and the scanner install and gates all of them, so an outage does not pay for a dotnet tool install it is about to throw away. Skipping is never dressed up as a pass — no gate is produced, the check does not report, and a warning annotation and job summary say why.
  • A blocking quality gate no longer fails pull requests. Where SONAR_BLOCKING_GATE is set, an outage is still forgiven on a pull request (which cannot publish), and the Release step instead names the Sonar outputs explicitly so a release cannot go out ungated.
  • Coverage exclusions are extensible per repository through a new SONAR_COVERAGE_EXCLUSIONS_EXTRA variable, rather than one repository's paths living in everyone's file. Unset here, so nothing changes.

Nothing in the pipeline's shape changed: the same four jobs, the same steps, the same order.

Already proven

This file is merged and green in three repositories, piloted before this fan-out:

How it was checked

Anchored transforms that refuse to apply on a missing or ambiguous anchor, then 18 structural assertions over the parsed YAML; comment-stripped diffs against all five variants, so the executable delta for each is exactly the list above; and both Sonar scripts parsed with the PowerShell parser and exercised under pwsh 7.4 across nine cases, capturing process exit codes and written $GITHUB_OUTPUT rather than a pipeline's status.

🤖 Generated with Claude Code

https://claude.ai/code/session_015qxqZVzN8CJcDxTb5gtWua


Generated by Claude Code

Every ktsu .NET repository carried its own copy of dotnet.yml and they had
drifted into five different files. This replaces the local copy with one
canonical workflow that is byte-identical in every repository, folding in the
drift rather than flattening it.

The drift, and where it went:

* macOS is back in the test matrix. It had been excluded org-wide because a
  macOS runner widened one repository's target frameworks to include a
  net10.0-ios head needing a workload this job does not install. That widening
  is now opt-in, so every other repository stops paying for it. UI test
  projects still run on Linux only, so a macOS cell stays cheap.
* The UI-test rule is now "Linux runs them, every other platform does not",
  rather than naming Windows, so a platform added later gets the cheap
  treatment by default instead of silently inheriting the expensive one.
* The Linux coverage report's paths are rewritten to this job's workspace
  before analysis. Sonar matches coverage to source by path, so a Linux-only
  suite's coverage was being dropped without a word. The step no-ops where
  there is no Linux report.
* The test and release jobs install the 8.0 and 9.0 runtimes alongside the
  pinned SDK, because test projects commonly multi-target every framework
  their library publishes and the test host needs those runtimes present.
  global.json still pins the SDK, so this only adds runtimes.
* Coverage exclusions are extensible per repository through the
  SONAR_COVERAGE_EXCLUSIONS_EXTRA variable, so a repository with a file that
  cannot be executed rather than one nobody has tested yet can say so without
  editing this file and making every other repository carry its paths.
* A SonarQube Cloud outage skips analysis instead of failing the build, and is
  never dressed up as a pass. Where the gate is blocking, an outage still fails.
* Stale comments explaining one repository's circumstances are rewritten to
  explain the shared rule, with the measurements kept and attributed.

Nothing in the pipeline's shape changed: the same jobs, the same steps, the
same order.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015qxqZVzN8CJcDxTb5gtWua
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants