Skip to content

feat(publish): multi-channel, package-ID-aware publishing + dogfood the lanes (#333)#339

Merged
ChrisonSimtian merged 4 commits into
experimentalfrom
feature/multichannel-publish
May 31, 2026
Merged

feat(publish): multi-channel, package-ID-aware publishing + dogfood the lanes (#333)#339
ChrisonSimtian merged 4 commits into
experimentalfrom
feature/multichannel-publish

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

Implements the framework half of epic #332's first step (#333), on the experimental lane (it touches the shipped Fallout.Components public surface, gated behind [Experimental("FALLOUT001")]).

What

  • PublishTarget + PublishPackageRouter (Fallout.Components) — a routable feed (name, source, key, include/exclude package-name globs, skip-duplicate) and pure, dependency-free glob routing. 10 unit tests in the new tests/Fallout.Components.Tests.
  • IPublish gains [Experimental("FALLOUT001")] PublishTargets + --publish-toPublish fans one Pack output across the selected feeds via the router. Existing single-feed members (NuGetSource/NuGetApiKey/PushSettings/PackagePushSettings/PushSettingsBase) retained → the change is additive, not breaking.
  • Build.cs wires the two real channels: github-packages (every package incl. Nuke.*, GitHub-token keyed) and nuget.org (Fallout.* only, never Nuke.*, NUGET_API_KEY keyed).
  • Dogfood: experimental.yml / preview.yml now dotnet fallout Publish --publish-to github-packages instead of hand-rolled dotnet nuget push. One invocation = Test → Pack → Publish (NUKE stages); nothing publishes if tests fail.
  • FALLOUT001 registered in docs/experimental-apis.md.

Verified

  • Fallout.Components + build/_build compile 0 errors; router tests 10/10; all workflow YAML valid; no generated-workflow drift.

Scope / deferred

Substantially closes #333 (release.yml lane → #336).

🤖 Generated with Claude Code

ChrisonSimtian and others added 2 commits May 31, 2026 12:49
…, FALLOUT001)

IPublish gains [Experimental("FALLOUT001")] PublishTargets + a --publish-to selector;
Publish now routes one Pack output across multiple feeds via the pure, unit-tested
PublishPackageRouter (glob include/exclude by package name). Existing single-source
members stay as a back-compat default target.

Build.cs wires the two real channels: github-packages (every package incl Nuke.*,
keyed by the GitHub token) and nuget.org (Fallout.* only, never Nuke.*, keyed by
NUGET_API_KEY) — replacing the legacy single-feed push.

- src/Fallout.Components/PublishTarget.cs — PublishTarget record + PublishPackageRouter
- tests/Fallout.Components.Tests — 10 router tests (added to fallout.slnx)
- docs/experimental-apis.md — FALLOUT001 registered

Framework compiles clean (0 errors); router tests green. Workflow rewire to
`dotnet fallout Publish --publish-to …` follows once experimental is synced with main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nes (#333)

experimental.yml and preview.yml now publish via `dotnet fallout Publish --publish-to
github-packages` instead of a hand-rolled `dotnet nuget push` loop. Publish depends on
Test + Pack, so one invocation runs Restore → Compile → Test → Pack → Publish as NUKE
stages; package routing (Fallout.* + Nuke.* → GitHub Packages) lives in Build.cs
IPublish.PublishTargets. The GitHub token is passed via the GitHubToken env.

Also restore IPublish.PackagePushSettings + PushSettingsBase (kept for back-compat) so the
multi-channel reshape stays additive — the new PublishTargets/PublishTo surface is the only
opt-in change, behind [Experimental("FALLOUT001")].

release.yml's publish jobs still use raw nuget push (they're coupled to the artifact
handoff + nuget-org approval gate) — dogfooding those is folded into #336.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian ChrisonSimtian added the target/vCurrent Targets the current version label May 31, 2026
ChrisonSimtian and others added 2 commits May 31, 2026 13:03
… skips it

CI caught CS0509: the TransitionShimGenerator tried to derive a Nuke.Components
shim from the sealed *record* PublishTarget. Sealed classes are skipped by design
(SHIM001), but the sealed-record shape slipped past that guard. PublishTarget is a
new type with no pre-rename consumers, so skipping its shim is correct; switching
record→sealed class hits the documented skip path. We don't use record equality/`with`.

Verified: Nuke.Components builds 0 errors (SHIM001 warning only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Components.Tests

Adding tests/Fallout.Components.Tests to fallout.slnx makes the StronglyTypedSolution
generator emit a Fallout_Components_Tests accessor; update the Verify snapshot to match
(one added line — the new project's strongly-typed Solution property).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian
ChrisonSimtian merged commit 8fa4b95 into experimental May 31, 2026
1 check passed
@ChrisonSimtian
ChrisonSimtian deleted the feature/multichannel-publish branch May 31, 2026 01:16
ChrisonSimtian added a commit that referenced this pull request Jun 9, 2026
…he lanes (#333) (#339)

* feat(publish): multi-channel, package-ID-aware publishing surface (#333, FALLOUT001)

IPublish gains [Experimental("FALLOUT001")] PublishTargets + a --publish-to selector;
Publish now routes one Pack output across multiple feeds via the pure, unit-tested
PublishPackageRouter (glob include/exclude by package name). Existing single-source
members stay as a back-compat default target.

Build.cs wires the two real channels: github-packages (every package incl Nuke.*,
keyed by the GitHub token) and nuget.org (Fallout.* only, never Nuke.*, keyed by
NUGET_API_KEY) — replacing the legacy single-feed push.

- src/Fallout.Components/PublishTarget.cs — PublishTarget record + PublishPackageRouter
- tests/Fallout.Components.Tests — 10 router tests (added to fallout.slnx)
- docs/experimental-apis.md — FALLOUT001 registered

Framework compiles clean (0 errors); router tests green. Workflow rewire to
`dotnet fallout Publish --publish-to …` follows once experimental is synced with main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(publish): dogfood `dotnet fallout Publish` on the alpha/preview lanes (#333)

experimental.yml and preview.yml now publish via `dotnet fallout Publish --publish-to
github-packages` instead of a hand-rolled `dotnet nuget push` loop. Publish depends on
Test + Pack, so one invocation runs Restore → Compile → Test → Pack → Publish as NUKE
stages; package routing (Fallout.* + Nuke.* → GitHub Packages) lives in Build.cs
IPublish.PublishTargets. The GitHub token is passed via the GitHubToken env.

Also restore IPublish.PackagePushSettings + PushSettingsBase (kept for back-compat) so the
multi-channel reshape stays additive — the new PublishTargets/PublishTo surface is the only
opt-in change, behind [Experimental("FALLOUT001")].

release.yml's publish jobs still use raw nuget push (they're coupled to the artifact
handoff + nuget-org approval gate) — dogfooding those is folded into #336.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(publish): make PublishTarget a sealed class so the shim generator skips it

CI caught CS0509: the TransitionShimGenerator tried to derive a Nuke.Components
shim from the sealed *record* PublishTarget. Sealed classes are skipped by design
(SHIM001), but the sealed-record shape slipped past that guard. PublishTarget is a
new type with no pre-rename consumers, so skipping its shim is correct; switching
record→sealed class hits the documented skip path. We don't use record equality/`with`.

Verified: Nuke.Components builds 0 errors (SHIM001 warning only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(generators): accept solution-generator snapshot for new Fallout.Components.Tests

Adding tests/Fallout.Components.Tests to fallout.slnx makes the StronglyTypedSolution
generator emit a Fallout_Components_Tests accessor; update the Verify snapshot to match
(one added line — the new project's strongly-typed Solution property).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian added a commit that referenced this pull request Jun 14, 2026
…he lanes (#333) (#339)

* feat(publish): multi-channel, package-ID-aware publishing surface (#333, FALLOUT001)

IPublish gains [Experimental("FALLOUT001")] PublishTargets + a --publish-to selector;
Publish now routes one Pack output across multiple feeds via the pure, unit-tested
PublishPackageRouter (glob include/exclude by package name). Existing single-source
members stay as a back-compat default target.

Build.cs wires the two real channels: github-packages (every package incl Nuke.*,
keyed by the GitHub token) and nuget.org (Fallout.* only, never Nuke.*, keyed by
NUGET_API_KEY) — replacing the legacy single-feed push.

- src/Fallout.Components/PublishTarget.cs — PublishTarget record + PublishPackageRouter
- tests/Fallout.Components.Tests — 10 router tests (added to fallout.slnx)
- docs/experimental-apis.md — FALLOUT001 registered

Framework compiles clean (0 errors); router tests green. Workflow rewire to
`dotnet fallout Publish --publish-to …` follows once experimental is synced with main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(publish): dogfood `dotnet fallout Publish` on the alpha/preview lanes (#333)

experimental.yml and preview.yml now publish via `dotnet fallout Publish --publish-to
github-packages` instead of a hand-rolled `dotnet nuget push` loop. Publish depends on
Test + Pack, so one invocation runs Restore → Compile → Test → Pack → Publish as NUKE
stages; package routing (Fallout.* + Nuke.* → GitHub Packages) lives in Build.cs
IPublish.PublishTargets. The GitHub token is passed via the GitHubToken env.

Also restore IPublish.PackagePushSettings + PushSettingsBase (kept for back-compat) so the
multi-channel reshape stays additive — the new PublishTargets/PublishTo surface is the only
opt-in change, behind [Experimental("FALLOUT001")].

release.yml's publish jobs still use raw nuget push (they're coupled to the artifact
handoff + nuget-org approval gate) — dogfooding those is folded into #336.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(publish): make PublishTarget a sealed class so the shim generator skips it

CI caught CS0509: the TransitionShimGenerator tried to derive a Nuke.Components
shim from the sealed *record* PublishTarget. Sealed classes are skipped by design
(SHIM001), but the sealed-record shape slipped past that guard. PublishTarget is a
new type with no pre-rename consumers, so skipping its shim is correct; switching
record→sealed class hits the documented skip path. We don't use record equality/`with`.

Verified: Nuke.Components builds 0 errors (SHIM001 warning only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(generators): accept solution-generator snapshot for new Fallout.Components.Tests

Adding tests/Fallout.Components.Tests to fallout.slnx makes the StronglyTypedSolution
generator emit a Fallout_Components_Tests accessor; update the Verify snapshot to match
(one added line — the new project's strongly-typed Solution property).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian added a commit that referenced this pull request Jun 14, 2026
…et.org at the same time (plus gating) (#342)

Promotes #333 from `experimental` → `main` (the `-preview` trunk) for
human review ahead of becoming an RC feature. Curated cherry-pick of the
feature commits (#339 + #340) — deliberately not a branch merge, so
`main`'s `version.json` stays `-preview` (experimental's `-alpha`
identity is left behind).

## What's promoted
- `PublishTarget` + pure `PublishPackageRouter` (10 unit tests,
`Fallout.Components.Tests`)
- `IPublish` `[Experimental("FALLOUT001")]` `PublishTargets` +
`--publish-to` — fans one `Pack` across feeds
- `Build.cs` channels: `github-packages` (all, incl. `Nuke.*`) +
`nuget.org` (`Fallout.*` only)
- `experimental.yml` / `preview.yml` now dogfood `dotnet fallout
Publish` instead of hand-rolled `dotnet nuget push`

## Why it's safe to promote
- **Non-breaking:** purely additive. The new surface is
`[Experimental("FALLOUT001")]`-gated, and the legacy single-feed members
are retained.
- **Validated on `experimental`:** full Test+Pack green, and the
post-merge `experimental` publish ran for real — `dotnet fallout Publish
--publish-to github-packages` published `-alpha` packages successfully
(the token-env fix #340 came out of that live run).

## Reviewer notes
- The `[Experimental]` attribute stays until the surface is promoted to
stable (attribute removed) once the CD model (#334) settles — this is
the preview/RC staging step, not stabilization.
- `release.yml` still uses raw `dotnet nuget push` (coupled to the
artifact handoff + `nuget-org` approval gate) → folded into #336.

Part of epic #332. Issue #333 stays open until this merges to `main`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

target/vCurrent Targets the current version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant