Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"commands": [
"dotnet-gitreleasemanager"
],
"rollForward": false
"rollForward": true
}
}
}
}
7 changes: 4 additions & 3 deletions .github/workflows/NUnit.Cake.Recipe.CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ jobs:
- name: 🛠️ Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
dotnet-version: 10.0.x

- name: 🛠️ Install dotnet tools
run: dotnet tool restore

- name: 🧪 Check Release Tool Startup
run: dotnet tool run dotnet-gitreleasemanager -- showconfig --no-logo

- name: 🧪 Test Recipe Sources
run: dotnet cake harness/tests.cake --target=Harness --packageVersion=1.0.0 --nopush

Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ jobs:
- name: 🛠️ Setup .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
7.0.x
dotnet-version: 10.0.x

- name: 🛠️ Install dotnet tools
run: dotnet tool restore

- name: 🧪 Check Release Tool Startup
run: dotnet tool run dotnet-gitreleasemanager -- showconfig --no-logo

- name: 🔨 Create Draft Release
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GH_ACCESS_CP }}
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.0",
"version": "10.0.0",
"rollForward": "latestFeature"
}
}
10 changes: 8 additions & 2 deletions harness/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Recipe source harness

This harness loads `../recipe/*.cake` directly. No published recipe package or
copied implementation is used. It runs under the repository's .NET 8 SDK policy
copied implementation is used. It runs under the repository's .NET 10 SDK policy
and pinned Cake.Tool 6.3.0, with Cake.Testing 6.3.0 for its test doubles.

From the repository root:
Expand All @@ -28,7 +28,7 @@ recipe's normal setup; no packaging or publishing target runs.
| Target | Coverage | Report |
| --- | --- | --- |
| `Harness-Tests` | Deferred dependency checks, exact package IDs and versions, source/prerelease options, extension selectors, unresolved lookups, tool failures, unversioned checks and package-verification failure propagation | `harness/artifacts/tests.xml` |
| `Harness-Smoke` | Full source loading, recipe setup, Cake target execution and `PackageDefinition.VerifyPackage()` using actual filesystem/globbing operations, including an expected missing-file failure | `harness/artifacts/smoke.xml` |
| `Harness-Smoke` | Full source loading, recipe setup, Cake target execution, real filesystem package verification (including expected failure), and read-only startup of the Cake-installed release tool | `harness/artifacts/smoke.xml` |

Reports use JUnit XML. Every behavior case runs before the target fails for any
assertions. A failed target returns a nonzero exit code. Compilation/setup failures
Expand All @@ -47,6 +47,12 @@ log and asserts both the exception and the specific error diagnostic. A successf
run prints `Expected missing-file failure verified (payload.txt).` Unexpected
exceptions or diagnostics still fail the target and appear in the XML report.

The release-tool smoke case executes only `showconfig --no-logo`; it performs no
release operation. Both CI workflows also check the local-manifest release tool
after restore. GitReleaseManager 0.20.0 still targets older runtimes, so its local
manifest enables roll-forward and recipe calls supply `DOTNET_ROLL_FORWARD=Major`
only to that tool's child process. No job-wide runtime override is used.

## Regression history

The original six diagnostic cases are represented here by deferred construction,
Expand Down
23 changes: 23 additions & 0 deletions harness/tests.cake
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Task("Harness-Smoke").Does(() =>
{
var suite = new RecipeTestSuite(Context);
suite.Add("real-cake/package-verification-and-failure", () => RunSmoke());
suite.Add("real-cake/release-tool-startup", () => RunReleaseToolSmoke());
suite.Run("artifacts/smoke.xml");
});
Task("Harness").IsDependentOn("Harness-Tests").IsDependentOn("Harness-Smoke");
Expand Down Expand Up @@ -232,3 +233,25 @@ void RunSmoke()
}
HarnessAssert.True(!DirectoryExists(root), "smoke fixture cleanup");
}

void RunReleaseToolSmoke()
{
var executable = Context.Tools.Resolve(IsRunningOnWindows()
? "dotnet-gitreleasemanager.exe" : "dotnet-gitreleasemanager");
HarnessAssert.True(executable != null, "Cake-installed GitReleaseManager tool was not found");
using (var process = Context.ProcessRunner.Start(executable, new ProcessSettings
{
Arguments = "showconfig --no-logo",
EnvironmentVariables = ReleaseManager.ToolEnvironment,
RedirectStandardOutput = true,
RedirectStandardError = true
}))
{
process.WaitForExit();
string output = string.Join(Environment.NewLine, process.GetStandardOutput());
string error = string.Join(Environment.NewLine, process.GetStandardError());
HarnessAssert.Equal(0, process.GetExitCode(), "release-tool startup: " + error);
HarnessAssert.True(output.Contains("create:") && output.Contains("export:"), "release-tool configuration output");
Information("Release-tool startup verified (read-only configuration).");
}
}
23 changes: 18 additions & 5 deletions recipe/ReleaseManager.cake
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ public static class ReleaseManager
_context = BuildSettings.Context;
}

/// <summary>
/// Allows the pinned GitReleaseManager tool to run when only a newer major
/// runtime is installed. Apply only to that tool's child process.
/// </summary>
internal static IDictionary<string, string> ToolEnvironment => new Dictionary<string, string>
{
{ "DOTNET_ROLL_FORWARD", "Major" }
};

public static void Publish()
{
bool hadErrors = false;
Expand Down Expand Up @@ -189,7 +198,8 @@ public static class ReleaseManager
_context.GitReleaseManagerCreate(BuildSettings.GitHubAccessToken, BuildSettings.GitHubOwner, BuildSettings.GitHubRepository, new GitReleaseManagerCreateSettings()
{
Name = releaseName,
Milestone = releaseVersion
Milestone = releaseVersion,
EnvironmentVariables = ToolEnvironment
});
}
catch
Expand Down Expand Up @@ -231,7 +241,8 @@ public static class ReleaseManager
_context.GitReleaseManagerCreate(BuildSettings.GitHubAccessToken, BuildSettings.GitHubOwner, BuildSettings.GitHubRepository, new GitReleaseManagerCreateSettings()
{
Name = releaseName,
Milestone = releaseVersion
Milestone = releaseVersion,
EnvironmentVariables = ToolEnvironment
});
}
catch
Expand All @@ -253,7 +264,7 @@ public static class ReleaseManager
string milestone = BuildSettings.BranchName.Substring(8);

_context.GitReleaseManagerExport(BuildSettings.GitHubAccessToken, BuildSettings.GitHubOwner, BuildSettings.GitHubRepository, "DraftRelease.md",
new GitReleaseManagerExportSettings() { TagName = milestone });
new GitReleaseManagerExportSettings() { TagName = milestone, EnvironmentVariables = ToolEnvironment });
}

public static void CreateProductionRelease()
Expand All @@ -279,8 +290,10 @@ public static class ReleaseManager
_context.Information($"Publishing release {tagName} to GitHub");
_context.Information($" Assets: {assets}");

_context.GitReleaseManagerAddAssets(token, owner, repository, tagName, assets);
_context.GitReleaseManagerClose(token, owner, repository, tagName);
_context.GitReleaseManagerAddAssets(token, owner, repository, tagName, assets,
new GitReleaseManagerAddAssetsSettings() { EnvironmentVariables = ToolEnvironment });
_context.GitReleaseManagerClose(token, owner, repository, tagName,
new GitReleaseManagerCloseMilestoneSettings() { EnvironmentVariables = ToolEnvironment });
}
}
}