Repository navigation
Adopt the shared CI pipeline - #46
Conversation
Replace this repository's 28.7 KB copy of dotnet.yml with a ci.yml that calls ktsu-dev/.github's ci-shared.yml. The dispatcher works out what kind of repository this is -- the dotnet topic plus a global.json -- and selects the pipeline, so changing how ktsu builds .NET repositories stops being a change here. The Dependabot gate moves in the same commit, not a later one. It lists the workflows whose completion re-opens the merge question by NAME, so a repository whose CI is called `CI` while its gate still lists `.NET Workflow` never re-evaluates: a genuinely green Dependabot PR would sit unmerged with nothing reporting a failure. Both refs also move to @Release, which is promoted deliberately rather than following main. This is the canary for the org-wide migration. It is a pull request rather than a push so that the new pipeline runs here, on this change, before main stops carrying a pipeline of its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RABe2NufFc9hwm94iB3Rf
Two findings on this pull request, one root cause. The CI run ended in startup_failure with no jobs: a called workflow cannot elevate above what its caller granted, and neither this caller nor the dispatcher granted enough for dotnet.yml's release job, which asks for `contents: write` and `packages: write`. CodeQL flagged the same file for having no permissions block at all, which is the other half of it -- without one the caller silently takes the repository default, which is both unstated and, here, insufficient. Grant the union the shared pipelines request. The file stays byte-identical to the template published in ktsu-dev/.github's docs/shared-ci.md, so the fan-out remains a copy rather than a per-repository edit. This alone does not turn the run green: the dispatcher also caps its callees at `contents: read`, fixed in ktsu-dev/.github#21. The tag this repository resolves, @Release, still points at the version with that cap, so CI here stays red until #21 merges and the tag is re-promoted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RABe2NufFc9hwm94iB3Rf
|
Status: CI here stays red until ktsu-dev/.github#21 merges. Naming the blocker rather than leaving it to be rediscovered. What this canary has already establishedThe first run failed, but not before proving the assumption the whole shared-CI design rests on. It recorded its A relative What is still broken
The second one is not fixable from this repository. Sequence to green
No further pushes to this branch are planned before then. Generated by Claude Code |
|
|
Green.
SonarQube Quality Gate passed. What this canary establishedEverything the org-wide migration depends on, observed rather than inferred:
What it cost to find outTwo defects, both on this one repository with
Both would have hit all fifty repositories simultaneously had this gone out as a fan-out. Net effect here
Generated by Claude Code |



What
The canary for the org-wide shared-CI migration. Three changes:
.github/workflows/ci.yml— 36 lines, callsktsu-dev/.github/.github/workflows/ci-shared.yml@release.github/workflows/dotnet.yml— 618 lines, the local copy of the pipeline.github/workflows/dependabot-merge.yml—workflows: [".NET Workflow"]→["CI"], ref@main→@releaseNet
+38 / −620.Why the Dependabot change is in the same commit
dependabot-merge.ymllists the workflows whose completion re-opens the merge question by workflow name. A repository whose CI is calledCIwhile its gate still lists.NET Workflownever re-evaluates — a genuinely green Dependabot PR would sit unmerged with nothing reporting a failure. Splitting these into two commits would open exactly that window.Why this is a pull request and not a push
This PR is the test.
ci.ymltriggers onpull_request, so the new pipeline runs here, on this change, beforemainstops carrying a pipeline of its own. If it doesn't work,mainis untouched.What it proves, in order:
ci-shared.yml@releaseresolves cross-repo from a caller.detectclassifies this repository —dotnettopic andglobal.jsonpresent, public — and selectsdotnet-public.uses: ./.github/workflows/dotnet.ymlinsideci-shared.ymlresolves withinktsu-dev/.github, not against this repository. This is the one genuinely unverified assumption in the whole design. GitHub's docs say the relative form resolves to "the same commit as the caller workflow", which in the nested case should meanci-shared.yml's own repository — but the docs don't address nesting explicitly. If it resolves against the caller instead, this PR fails here with a missing-workflow error andci-shared.ymlneeds absolute@releaserefs before anything else migrates.secrets: inheritchains two levels deep.Expected check names
Checks will be nested one level deeper:
ci / dotnet-public / Test on ubuntu-latestrather thanTest on ubuntu-latest. Harmless for the Dependabot gate, which enumerates check runs rather than matching names, and whose self-exclusion is already suffix-based.Not in this PR
update-sdks.ymlstays as-is for now — it has a separate, unrelated defect (a[System.Version]::Parsefailure on prerelease versions) being handled on its own.Blast radius
One repository. If CI here is green, the same change fans out to the rest; if not, nothing else has moved.
🤖 Generated with Claude Code
https://claude.ai/code/session_014RABe2NufFc9hwm94iB3Rf
Generated by Claude Code