ci: tag-triggered + multi-channel fan-out for release.yml - #288
Merged
Conversation
Refactors .github/workflows/release.yml from the workflow_dispatch-only stopgap (#268) into the proper release-branch model shape per RFC #267 and milestone #13. ## Trigger - push: tags 'v*' is the primary trigger. The new validate-ref job verifies the tag is reachable from a release/v* branch and fails fast otherwise. - workflow_dispatch with a required `tag` input remains as a fallback for re-runs after a transient API failure. --skip-duplicate on each publish step keeps re-runs idempotent. ## Job graph validate-ref (skipped on workflow_dispatch) ↓ test-and-pack (Test + Pack via `dotnet fallout`, uploads output/packages/*.nupkg as Actions artifact) ↓ ↓ ↓ (fan-out) publish-nuget-org (env: nuget-org, Fallout.*.nupkg → nuget.org, gated) publish-github-packages (env: github-packages, Nuke.*.nupkg → GH Packages, unguarded) publish-github-releases (env: github-releases, all *.nupkg → GH Release, unguarded) Each publish job declares `environment:` so a per-channel deployment record appears under the Deployments tab. The nuget-org env requires approval (set in #272); the other two are unguarded. ## Channel routing - nuget.org gets ONLY Fallout.* — Nuke.* shim IDs belong to the original NUKE maintainer on nuget.org (#47). - GitHub Packages gets the Nuke.* shims — preserves the existing behaviour from the previous workflow. - GitHub Releases gets all *.nupkg attached to the tag's release page, with auto-generated notes via `gh release create --generate-notes`. Idempotent — if the release already exists (workflow_dispatch retry), uploads/replaces assets via --clobber. ## Tag protection ruleset (applied separately via API) A repository ruleset now blocks creation/deletion/update of tags matching v* for non-admins. Bypass actors: RepositoryRole 5 (admin). Combined with the env approval gate on nuget-org, this gates production releases at two layers. The ruleset is configured via API rather than in this YAML (ruleset:17017817). It was created in the same change but lives in repo Settings → Rules, not in the workflow file. ## Build.cs not touched The existing `IPublish.Publish` target and `ICreateGitHubRelease` from Build.cs are bypassed by this workflow — CI now calls `dotnet nuget push` and `gh release create` directly. The targets are still available for local invocation; consolidating or removing them is a follow-up. ## Docs docs/agents/release-and-versioning.md "Release pipeline" section rewritten to describe the new shape (trigger, jobs, channel routing, tag protection, fallback dispatch). CHANGELOG entry deferred to the umbrella docs PR #276 per the pattern set in earlier sub-issues — one consolidated v11-restructure entry rather than fragmented per-PR entries. Refs #274, milestone #13. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 29, 2026
ChrisonSimtian
added a commit
that referenced
this pull request
May 29, 2026
…default channel (#299) Implements the v11-off-nuget direction. Tag pushes on release/v11 no longer auto-publish to nuget.org — they publish to GitHub Packages + GitHub Releases only. To publish Fallout.* to nuget.org you must invoke workflow_dispatch with `publish-to-nugetorg=true`, an explicit "this release is stabilised enough for nuget.org" switch. This *modifies* the routing originally documented in milestone #13's release.yml refactor (#288). The release-branch model, multi-channel fan-out, and CD gating are all unchanged — only the routing policy shifts. ## Workflow changes (`.github/workflows/release.yml`) - New `workflow_dispatch` input `publish-to-nugetorg` (boolean, default false). - `publish-nuget-org` job gains `if:` condition requiring both `github.event_name == 'workflow_dispatch'` and `inputs.publish-to-nugetorg == true`. Tag pushes skip this job. - `publish-github-packages` job changes its glob from `Nuke.*.nupkg` to `*.nupkg` — now publishes both Fallout.* and Nuke.* to GH Packages. GH Packages is the v11 release channel; Nuke.* shim routing per #47 is preserved (still goes here permanently). - Header comment + per-job comments rewritten to describe the new routing policy explicitly. Three layers of safety on the nuget.org path now: 1. Tag protection ruleset (only repo admins can create v* tags). 2. workflow_dispatch flag opt-in. 3. nuget-org env approval gate. ## Doc updates - `docs/agents/release-and-versioning.md` — Release pipeline section rewritten. Table updated. New "Why nuget.org is opt-in for v11" subsection. workflow_dispatch inputs documented. - `docs/branching-and-release.md` — Channel taxonomy table extended with "Current v11 use" column. "Cutting a release" split into two sub-runbooks: routine (GitHub Packages only) and stabilised (with the opt-in flag). - `docs/adr/0002-v11-off-nuget-by-default.md` — new ADR capturing the decision and three rejected alternatives. ## CHANGELOG Entry under [Unreleased] — 11.0 → Process explicitly noting this *modifies* the routing originally documented in the milestone #13 umbrella entry (rather than backdating that entry; preserves history of how the decision evolved). ## Out of scope - Unlisting existing 11.0.x on nuget.org — separate work (see worktree `unlist-10.3` for the parallel 10.3 unlisting). - When/how v11 transitions to "stabilised" and opts into nuget.org by default — a future ADR / decision when that moment arrives. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #274 per RFC #267. Replaces the
workflow_dispatch-only stopgap (#268) with the proper release-branch + multi-channel CD shape.Trigger
push: tags: ['v*']. Thevalidate-refjob verifies the tag is reachable from arelease/v*branch and fails fast otherwise. Random tags onmainor feature branches can't accidentally fire a release.workflow_dispatchwith a requiredtaginput — for re-running after a transient publish-API failure. The workflow checks out that tag and re-runs the publish chain.--skip-duplicatekeeps re-runs idempotent.Job graph
test-and-packrunsdotnet fallout Test Packonce and uploadsoutput/packages/*.nupkgas an Actions artifact. Each publish job downloads it and pushes its slice.Channel routing
Fallout.*.nupkgonlyhttps://api.nuget.org/v3/index.json(gated bynuget-orgenv approval)Nuke.*.nupkg(transition shims, per #47)https://nuget.pkg.github.com/ChrisonSimtian/index.json*.nupkgattached to tag's release pagegh release create --generate-notes(or--clobberif release exists)Nuke.*IDs are owned by the original NUKE maintainer on nuget.org — routing them to GitHub Packages instead preserves the existing behaviour (#47).Tag protection (applied separately, in scope of this issue)
Created a repository ruleset (id 17017817, visible at https://github.com/ChrisonSimtian/Fallout/rules/17017817):
refs/tags/v*RepositoryRole 5(admin) — currently only @ChrisonSimtianCombined with the env approval gate on
nuget-org, production releases are now gated at two layers: who-can-tag + who-can-approve-publish.Build.cs deliberately not touched
The existing
IPublish.Publishtarget andICreateGitHubReleasefrombuild/Build.csare bypassed by CI — the workflow now callsdotnet nuget pushandgh release createdirectly. Targets stay around for local invocation; cleanup/consolidation is a follow-up worth tracking once the model has settled.Test plan
Tricky because we can't really dry-run a publish without affecting the world. Verification approach:
current_user_can_bypass: alwaysfor Chris.workflow_dispatchwithtag: <some-existing-tag>. The validate-ref step is skipped on dispatch, so this exercisestest-and-pack → publish-*end-to-end. Approve at thenuget-orggate to confirm the wiring;--skip-duplicatemakes the nuget.org push safe even on an already-published tag.release/v11, push av11.0.Xtag, watch the fan-out.Open follow-ups
publicReleaseRefSpectweak — current finding is thatrelease/v11produces git-sha-suffixed versions (11.0.19-g4b19a8c1) instead of clean11.0.19. The first tag-triggered release will hit this. Decision deferred to you per the earlier discussion (apply onrelease/v11now vs fold into Bump main's version.json to 12.0 (next-major trunk) #271).CONTRIBUTING.md+ newdocs/branching-and-release.md.🤖 Generated with Claude Code