From 83601a64303d70d69978989f177e67d89f380296 Mon Sep 17 00:00:00 2001 From: Chrison Simtian Date: Thu, 21 May 2026 20:03:43 +1200 Subject: [PATCH 1/2] feat: ship Nuke.Common MVP transition shim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes part of #47 — see #69 for the source-generator follow-up that expands coverage to the full public API surface. ## What this is A hand-written package named `Nuke.Common` that re-exports the most common Nuke.* types as subclasses of the canonical Fallout.* types. For projects mid-migration from NUKE to Fallout — adds our GH Packages feed, bumps Nuke.Common version, and a `class Build : NukeBuild` with [Parameter] / [Secret] / [Solution] / [GitRepository] compiles unchanged. ## Coverage | Old (Nuke.Common) | New (Fallout.Common) | Mechanism | |---|---|---| | NukeBuild | FalloutBuild | Subclass | | INukeBuild | IFalloutBuild | Sub-interface | | [Parameter] | ParameterAttribute | Subclass | | [Secret] | SecretAttribute | Subclass | | [Solution] (in .ProjectModel) | SolutionAttribute | Subclass | | [GitRepository] (in .Git) | GitRepositoryAttribute | Subclass | ## NOT in this MVP (tracked in #69) - Source generator for the remaining ~150 types in Common alone - Other shim packages (Nuke.Build, Nuke.Components, etc.) - CI attributes ([GitHubActions] etc.) — block on enums (GitHubActionsImage), can't bridge without source generator - Target delegate — C# can't implicitly convert between delegate types, needs `fallout-migrate` for the source-level rename - Static helper classes (DotNetTasks etc.) — need method-by-method delegation, scale-only-with-generator ## Packaging The shim is `IsPackable=false` by default to keep the standard release pipeline (which targets nuget.org) from trying to push `Nuke.Common` there — that ID belongs to the original NUKE maintainer. To produce the nupkg for GH-Packages publish: dotnet pack src/Shims/Nuke.Common/Nuke.Common.csproj -p:PackShims=true A dedicated publish target for GH Packages is part of #69. ## Tests - `tests/Nuke.Common.Shim.Tests/SampleConsumerBuild.cs` — compile-only test mirroring a typical consumer Build.cs. If it compiles, the shim covers what it claims to cover. ## Side-effect StronglyTypedSolutionGeneratorTest verify snapshot regenerated — solution generator picks up the two new projects (Nuke.Common, Nuke.Common.Shim.Tests). ## Verification - dotnet build src/Shims/Nuke.Common: 0 errors, 0 warnings - dotnet build tests/Nuke.Common.Shim.Tests: 0 errors (sample consumer compiles) - dotnet pack -p:PackShims=true: produces Nuke.Common.10.2.20-*.nupkg - dotnet pack without the flag: skips the shim (release pipeline safe) - dotnet test fallout.slnx: 408 passed (was 408; verify snapshot updated) Co-Authored-By: Claude Opus 4.7 (1M context) --- fallout.slnx | 2 + src/Shims/Nuke.Common/Attributes.cs | 23 +++++++++ src/Shims/Nuke.Common/GitAttributes.cs | 14 ++++++ src/Shims/Nuke.Common/Nuke.Common.csproj | 27 +++++++++++ src/Shims/Nuke.Common/NukeBuild.cs | 22 +++++++++ .../Nuke.Common/ProjectModelAttributes.cs | 16 +++++++ src/Shims/Nuke.Common/README.md | 47 +++++++++++++++++++ ...nGeneratorTest.Test#Solution.g.verified.cs | 2 + .../Nuke.Common.Shim.Tests.csproj | 11 +++++ .../SampleConsumerBuild.cs | 30 ++++++++++++ 10 files changed, 194 insertions(+) create mode 100644 src/Shims/Nuke.Common/Attributes.cs create mode 100644 src/Shims/Nuke.Common/GitAttributes.cs create mode 100644 src/Shims/Nuke.Common/Nuke.Common.csproj create mode 100644 src/Shims/Nuke.Common/NukeBuild.cs create mode 100644 src/Shims/Nuke.Common/ProjectModelAttributes.cs create mode 100644 src/Shims/Nuke.Common/README.md create mode 100644 tests/Nuke.Common.Shim.Tests/Nuke.Common.Shim.Tests.csproj create mode 100644 tests/Nuke.Common.Shim.Tests/SampleConsumerBuild.cs diff --git a/fallout.slnx b/fallout.slnx index 7e66400fd..64f92ba76 100644 --- a/fallout.slnx +++ b/fallout.slnx @@ -16,6 +16,7 @@ + @@ -32,6 +33,7 @@ + diff --git a/src/Shims/Nuke.Common/Attributes.cs b/src/Shims/Nuke.Common/Attributes.cs new file mode 100644 index 000000000..626ad5d28 --- /dev/null +++ b/src/Shims/Nuke.Common/Attributes.cs @@ -0,0 +1,23 @@ +// Copyright 2026 Maintainers of Fallout. +// Originally based on NUKE by Matthias Koch and contributors. +// Distributed under the MIT License. +// https://github.com/ChrisonSimtian/Fallout/blob/main/LICENSE + +using System; + +namespace Nuke.Common; + +// Parameter / Secret injection attributes — most consumer Build.cs files use these. + +/// Transition shim for . +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] +public sealed class ParameterAttribute : Fallout.Common.ParameterAttribute +{ + public ParameterAttribute(string description = null) : base(description) { } +} + +/// Transition shim for . +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public sealed class SecretAttribute : Fallout.Common.SecretAttribute +{ +} diff --git a/src/Shims/Nuke.Common/GitAttributes.cs b/src/Shims/Nuke.Common/GitAttributes.cs new file mode 100644 index 000000000..5258bae0d --- /dev/null +++ b/src/Shims/Nuke.Common/GitAttributes.cs @@ -0,0 +1,14 @@ +// Copyright 2026 Maintainers of Fallout. +// Originally based on NUKE by Matthias Koch and contributors. +// Distributed under the MIT License. +// https://github.com/ChrisonSimtian/Fallout/blob/main/LICENSE + +using System; + +namespace Nuke.Common.Git; + +/// Transition shim for . +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public sealed class GitRepositoryAttribute : Fallout.Common.Git.GitRepositoryAttribute +{ +} diff --git a/src/Shims/Nuke.Common/Nuke.Common.csproj b/src/Shims/Nuke.Common/Nuke.Common.csproj new file mode 100644 index 000000000..be068a926 --- /dev/null +++ b/src/Shims/Nuke.Common/Nuke.Common.csproj @@ -0,0 +1,27 @@ + + + + net10.0 + Nuke.Common + Nuke.Common + Nuke.Common + Nuke.Common (Fallout transition shim) + + false + Transition shim that re-exports the most common Nuke.* types as subclasses/wrappers of the canonical Fallout.* types. For projects mid-migration from NUKE to Fallout. Published only to GitHub Packages (nuget.org's Nuke.Common is owned by the original NUKE maintainer). + build automation continuous-integration tools orchestration nuke shim transition + + false + + + + + + + + diff --git a/src/Shims/Nuke.Common/NukeBuild.cs b/src/Shims/Nuke.Common/NukeBuild.cs new file mode 100644 index 000000000..bf3e673c9 --- /dev/null +++ b/src/Shims/Nuke.Common/NukeBuild.cs @@ -0,0 +1,22 @@ +// Copyright 2026 Maintainers of Fallout. +// Originally based on NUKE by Matthias Koch and contributors. +// Distributed under the MIT License. +// https://github.com/ChrisonSimtian/Fallout/blob/main/LICENSE + +namespace Nuke.Common; + +/// +/// Transition shim. Inherits from . Replace your +/// using Nuke.Common; with using Fallout.Common; and NukeBuild with +/// FalloutBuild when you're ready — see fallout-migrate. +/// +public abstract class NukeBuild : Fallout.Common.FalloutBuild +{ +} + +/// +/// Transition shim. Extends . +/// +public interface INukeBuild : Fallout.Common.IFalloutBuild +{ +} diff --git a/src/Shims/Nuke.Common/ProjectModelAttributes.cs b/src/Shims/Nuke.Common/ProjectModelAttributes.cs new file mode 100644 index 000000000..2d4ffaa97 --- /dev/null +++ b/src/Shims/Nuke.Common/ProjectModelAttributes.cs @@ -0,0 +1,16 @@ +// Copyright 2026 Maintainers of Fallout. +// Originally based on NUKE by Matthias Koch and contributors. +// Distributed under the MIT License. +// https://github.com/ChrisonSimtian/Fallout/blob/main/LICENSE + +using System; + +namespace Nuke.Common.ProjectModel; + +/// Transition shim for . +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public sealed class SolutionAttribute : Fallout.Common.ProjectModel.SolutionAttribute +{ + public SolutionAttribute() { } + public SolutionAttribute(string relativePath) : base(relativePath) { } +} diff --git a/src/Shims/Nuke.Common/README.md b/src/Shims/Nuke.Common/README.md new file mode 100644 index 000000000..cd6c0db7f --- /dev/null +++ b/src/Shims/Nuke.Common/README.md @@ -0,0 +1,47 @@ +# Nuke.Common transition shim + +This package is a **partial transition shim** for projects mid-migration from NUKE to Fallout. Published only to GitHub Packages — `Nuke.Common` on nuget.org is owned by the original NUKE maintainer. + +## What's covered + +| Old (`Nuke.Common`) | New (`Fallout.Common`) | Shim mechanism | +|---|---|---| +| `NukeBuild` | `FalloutBuild` | Subclass | +| `INukeBuild` | `IFalloutBuild` | Sub-interface | +| `[Parameter]` | `Fallout.Common.ParameterAttribute` | Subclass | +| `[Secret]` | `Fallout.Common.SecretAttribute` | Subclass | +| `[Solution]` | `Fallout.Common.ProjectModel.SolutionAttribute` | Subclass | +| `[GitRepository]` | `Fallout.Common.Git.GitRepositoryAttribute` | Subclass | + +The MVP unblocks a `class Build : NukeBuild` declaration with parameter/secret/solution/git injection — the entry-point surface of most consumer Build.cs files. + +## What's NOT covered (yet) + +- **CI attributes** (`[GitHubActions]`, `[AzurePipelines]`, `[TeamCity]`, `[AppVeyor]`, ...) — these take enum parameters (`GitHubActionsImage`, etc.) that the shim doesn't re-export. C# can't subclass enums; bridging them needs a source generator. Tracked in the follow-up issue. +- **The `Target` delegate** — delegates can't be implicitly converted across types in C#, so the shim can't bridge `Nuke.Common.Target Compile => _ => _` cleanly. Use `fallout-migrate` for the source-level rename. +- **Static helper classes** — `DotNetTasks`, `MSBuildTasks`, etc. require method-by-method delegation. Tracked for the source-generator follow-up. +- **IO types** — `AbsolutePath`, file globbing helpers — also need wrapper classes with mirrored members. + +## Migration path + +For projects that just want their `class Build : NukeBuild { ... }` to compile against our framework: + +1. Add `https://nuget.pkg.github.com/ChrisonSimtian/index.json` as a NuGet source (`nuget.config`). +2. Bump the `Nuke.Common` package version to the latest published here. +3. Build. If the shim covers what you use, you're done. Otherwise: +4. Run `fallout-migrate` to rewrite the remaining references. + +## What this shim is NOT + +- Not a permanent dependency — designed for a transition window. +- Not a replacement for the migration story — most consumers should run `fallout-migrate` and target `Fallout.Common` directly. +- Not on nuget.org — only on this fork's GitHub Packages feed. + +## Future work + +Source-generator-based expansion to cover the full public API is tracked in the issue tracker. The architectural decision is between: + +1. **Per-package shims** with hand-written wrappers (this approach, doesn't scale to all 158 public types in Common alone). +2. **Generated wrappers** from a Roslyn source generator that reflects the canonical assembly metadata — single source of truth, mechanical regeneration. + +(2) is the long-term answer. (1) is what shipped first. diff --git a/tests/Fallout.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.Test#Solution.g.verified.cs b/tests/Fallout.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.Test#Solution.g.verified.cs index 50c3206f6..8dd22b8ae 100644 --- a/tests/Fallout.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.Test#Solution.g.verified.cs +++ b/tests/Fallout.SourceGenerators.Tests/StronglyTypedSolutionGeneratorTest.Test#Solution.g.verified.cs @@ -36,6 +36,8 @@ internal class Solution(SolutionModel model, AbsolutePath path) : Fallout.Common public Fallout.Common.ProjectModel.Project Fallout_Utilities_Tests => this.GetProject("Fallout.Utilities.Tests"); public Fallout.Common.ProjectModel.Project Fallout_Utilities_Text_Json => this.GetProject("Fallout.Utilities.Text.Json"); public Fallout.Common.ProjectModel.Project Fallout_Utilities_Text_Yaml => this.GetProject("Fallout.Utilities.Text.Yaml"); + public Fallout.Common.ProjectModel.Project Nuke_Common => this.GetProject("Nuke.Common"); + public Fallout.Common.ProjectModel.Project Nuke_Common_Shim_Tests => this.GetProject("Nuke.Common.Shim.Tests"); public _misc misc => Unsafe.As<_misc>(this.GetSolutionFolder("misc")); diff --git a/tests/Nuke.Common.Shim.Tests/Nuke.Common.Shim.Tests.csproj b/tests/Nuke.Common.Shim.Tests/Nuke.Common.Shim.Tests.csproj new file mode 100644 index 000000000..abbd8431e --- /dev/null +++ b/tests/Nuke.Common.Shim.Tests/Nuke.Common.Shim.Tests.csproj @@ -0,0 +1,11 @@ + + + + net10.0 + + + + + + + diff --git a/tests/Nuke.Common.Shim.Tests/SampleConsumerBuild.cs b/tests/Nuke.Common.Shim.Tests/SampleConsumerBuild.cs new file mode 100644 index 000000000..eccd10089 --- /dev/null +++ b/tests/Nuke.Common.Shim.Tests/SampleConsumerBuild.cs @@ -0,0 +1,30 @@ +// Copyright 2026 Maintainers of Fallout. +// Originally based on NUKE by Matthias Koch and contributors. +// Distributed under the MIT License. +// https://github.com/ChrisonSimtian/Fallout/blob/main/LICENSE +// +// This file is the **compile-only test** for the Nuke.Common shim. It mirrors what a +// typical NUKE-era consumer Build.cs imports. If this file compiles, the MVP shim covers +// the surface it claims to cover. Nothing here is executed. + +#pragma warning disable CS0649 // unassigned readonly — these are injected at runtime +#pragma warning disable CS0169 // unused fields — same reason + +using Nuke.Common; +using Nuke.Common.Git; +using Nuke.Common.ProjectModel; + +namespace Nuke.Common.Shim.Tests; + +// Consumer's typical Build.cs entry-point — inherits the shim's NukeBuild, +// uses the canonical Fallout types via `Fallout.Common.Target` (shim doesn't +// bridge delegates; that's `fallout-migrate`'s job). +public abstract class SampleConsumerBuild : NukeBuild, INukeBuild +{ + [Parameter("Configuration to build")] readonly string Configuration; + [Parameter] readonly bool RunTests; + [Secret] readonly string NuGetApiKey; + [Solution] readonly Fallout.Common.ProjectModel.Solution Solution; + [Solution("path/to/explicit.slnx")] readonly Fallout.Common.ProjectModel.Solution ExplicitSolution; + [GitRepository] readonly Fallout.Common.Git.GitRepository GitRepository; +} From 6a5b2bfbae382f2a64fb90685171275649af6f9b Mon Sep 17 00:00:00 2001 From: Chrison Simtian Date: Thu, 21 May 2026 20:14:49 +1200 Subject: [PATCH 2/2] chore(shim): pack normally + filter Nuke.* out of nuget.org push instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per review: gating shim packaging behind a property was clunky. The cleaner separation is "pack everything as build artifacts; filter at the publish step." Changes: - src/Shims/Nuke.Common/Nuke.Common.csproj: drop the IsPackable=$(PackShims) gate, IsPackable=true unconditionally. The shim packs on every build like any other library project. - build/Build.cs: override IPublish.PushPackageFiles to filter out files whose name starts with "Nuke." — that ID belongs to the original NUKE maintainer on nuget.org. Fallout.* keeps publishing normally; Nuke.Common.nupkg ends up in the packages directory as a build artifact to upload to GitHub Packages or attach to a release. - src/Shims/Nuke.Common/README.md: document the manual GH Packages push command for the transition window. Verified locally: `dotnet pack` on the shim project produces the nupkg without any opt-in flag. Co-Authored-By: Claude Opus 4.7 (1M context) --- build/Build.cs | 7 +++++++ src/Shims/Nuke.Common/Nuke.Common.csproj | 9 +++++---- src/Shims/Nuke.Common/README.md | 13 +++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/build/Build.cs b/build/Build.cs index 5e4630d9a..811b629f4 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -134,6 +134,13 @@ from framework in project.GetTargetFrameworks() .Requires(() => GitRepository.IsOnMainBranch() && Host is GitHubActions && GitHubActions.Workflow == ReleaseWorkflow) .WhenSkipped(DependencyBehavior.Execute); + // Filter `Nuke.*` shim packages out of the nuget.org push — that ID is owned by + // the original NUKE maintainer. The shims still build and pack as artifacts; they + // get pushed to GitHub Packages via a separate (manual / future-automated) step. + IEnumerable IPublish.PushPackageFiles + => From().PackagesDirectory.GlobFiles("*.nupkg") + .Where(x => !x.NameWithoutExtension.StartsWith("Nuke.", StringComparison.OrdinalIgnoreCase)); + IEnumerable NuGetPackageFiles => From().PackagesDirectory.GlobFiles("*.nupkg"); diff --git a/src/Shims/Nuke.Common/Nuke.Common.csproj b/src/Shims/Nuke.Common/Nuke.Common.csproj index be068a926..c7d48783e 100644 --- a/src/Shims/Nuke.Common/Nuke.Common.csproj +++ b/src/Shims/Nuke.Common/Nuke.Common.csproj @@ -7,11 +7,12 @@ Nuke.Common Nuke.Common (Fallout transition shim) - false + true Transition shim that re-exports the most common Nuke.* types as subclasses/wrappers of the canonical Fallout.* types. For projects mid-migration from NUKE to Fallout. Published only to GitHub Packages (nuget.org's Nuke.Common is owned by the original NUKE maintainer). build automation continuous-integration tools orchestration nuke shim transition