From 0c44fa1198f06e97698f02c55b78c53b3fe919f7 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Wed, 2 Sep 2026 21:39:59 +0200 Subject: [PATCH 1/2] Bump Proc to 0.14.0, fix release-notes CLI invocation, harden tool restore Proc was pinned at 0.9.1; the build scripts assumed 0.14+ semantics elsewhere (no shell expansion, throws on failure) so this just catches the pin up. release-notes was recently ported to a new Argh-based CLI (0.11.0): bare invocation is gone (needs an explicit `generate`/`create-release` command first) and `--label` takes a single `key=value` token instead of two. The build script still called the old CLI shape, which would have broken the next tagged release. Bumped the pinned version and fixed both call sites to match, verified against the real 0.11.0 package. Also retries `dotnet tool restore` once on failure: dotnet/sdk#53783 causes cold-cache restores of 2+ RID-specific tool packages (all of ours now are) to misattribute one package's DotnetToolSettings.xml to another. A retry always succeeds since the resolver cache is warm afterward. Co-authored-by: Cursor --- build/scripts/Targets.fs | 26 ++++++++++++++++++-------- build/scripts/scripts.fsproj | 2 +- dotnet-tools.json | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/build/scripts/Targets.fs b/build/scripts/Targets.fs index e11cb4f..d06ce2b 100644 --- a/build/scripts/Targets.fs +++ b/build/scripts/Targets.fs @@ -12,7 +12,16 @@ open ProcNet let exec binary args = Proc.Exec (binary, args |> List.toArray) -let private restoreTools = lazy(exec "dotnet" ["tool"; "restore"]) +/// dotnet/sdk#53783: on a cold tool-resolver cache (every fresh CI runner, every fresh container), +/// restoring 2+ RID-specific tool packages in one manifest can misattribute one package's +/// DotnetToolSettings.xml to another, failing with "The command ... is not contained in the +/// package ...". The cache is warm after the first attempt, so a bare retry always succeeds - +/// see https://github.com/dotnet/sdk/issues/53783. +let private restoreTools = + lazy( + try exec "dotnet" ["tool"; "restore"] + with _ -> exec "dotnet" ["tool"; "restore"] + ) let private currentVersion = lazy( restoreTools.Value |> ignore @@ -120,11 +129,12 @@ let private generateReleaseNotes (arguments:ParseResults) = | None -> [] | Some token -> ["--token"; token;] let releaseNotesArgs = - (Paths.Repository.Split("/") |> Seq.toList) + ["generate"] + @ (Paths.Repository.Split("/") |> Seq.toList) @ ["--version"; currentVersion - "--label"; "enhancement"; "New Features" - "--label"; "bug"; "Bug Fixes" - "--label"; "documentation"; "Docs Improvements" + "--label"; "enhancement=New Features" + "--label"; "bug=Bug Fixes" + "--label"; "documentation=Docs Improvements" ] @ tokenArgs @ ["--output"; output] @@ -139,9 +149,9 @@ let private createReleaseOnGithub (arguments:ParseResults) = let releaseNotes = Paths.RootRelative <| Path.Combine(Paths.Output.FullName, sprintf "release-notes-%s.md" currentVersion) let breakingChanges = Paths.RootRelative <| Path.Combine(Paths.Output.FullName, "github-breaking-changes-comments.md") let releaseArgs = - (Paths.Repository.Split("/") |> Seq.toList) - @ ["create-release" - "--version"; currentVersion + ["create-release"] + @ (Paths.Repository.Split("/") |> Seq.toList) + @ ["--version"; currentVersion "--body"; releaseNotes; "--body"; breakingChanges; ] @ tokenArgs diff --git a/build/scripts/scripts.fsproj b/build/scripts/scripts.fsproj index 461477f..066c031 100644 --- a/build/scripts/scripts.fsproj +++ b/build/scripts/scripts.fsproj @@ -8,7 +8,7 @@ - + diff --git a/dotnet-tools.json b/dotnet-tools.json index 75d5d13..e886ed7 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "release-notes": { - "version": "0.10.0", + "version": "0.11.0", "commands": [ "release-notes" ], From 116f7c2e7c3c655d6aef5c302740bd21f500c434 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Thu, 3 Sep 2026 10:44:18 +0200 Subject: [PATCH 2/2] Fix generateApiChanges diffing the empty root package instead of .any The plain "assembly-differ" package id is a DotnetToolSettings.xml v2 shim that maps RIDs to per-RID sub-packages (see generatePackages) - it ships no managed assembly of its own, so diffing against it finds 0 assemblies. This would have broken "Inspect public API changes" on the next release, the same way it just did in release-notes: https://github.com/nullean/release-notes/actions/runs/33674817669/job/100397363448 The portable, signed managed build lives in "assembly-differ.any" instead; point previous-nuget at that. Co-authored-by: Cursor --- build/scripts/Targets.fs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/scripts/Targets.fs b/build/scripts/Targets.fs index d06ce2b..5a6add8 100644 --- a/build/scripts/Targets.fs +++ b/build/scripts/Targets.fs @@ -113,7 +113,11 @@ let private generateApiChanges (arguments:ParseResults) = let args = [ "diff"; - sprintf "previous-nuget|%s|%s|net8.0" Paths.ToolName currentVersion; + // The plain "assembly-differ" package id is just a DotnetToolSettings.xml v2 shim pointing + // at per-RID sub-packages (see generatePackages below) - it ships no managed assembly of + // its own, so NuGetAssemblyProvider would find 0 assemblies there. The portable, signed + // managed build lives in "assembly-differ.any" instead. + sprintf "previous-nuget|%s.any|%s|net8.0" Paths.ToolName currentVersion; sprintf "directory|src/%s/bin/Release/net10.0" Paths.ToolName; "--target"; Paths.ToolName; "-f"; "github-comment"; "--output"; output ]