Port to C# and ship as a native-AOT tool - #28
Merged
Merged
Conversation
Argu's argument parsing leans on reflection over F# union case metadata, which NativeAOT trims away, so a published AOT build of the old F# tool silently failed to recognize any of its own arguments. Porting to C# and Nullean.Argh (a source generator, so no reflection at parse time) unblocks AOT packaging the same way curb and assembly-differ already ship it: one native-AOT package per RID plus a framework-dependent 'any' fallback, selected transparently by the root package's DotnetToolSettings.xml. SemVer parsing/comparison moves from Fake.Core.SemVer to NuGet.Versioning, and Octokit is bumped from 0.43.0 to 14.0.0, both reflection-free and AOT-friendly. Breaking change: Argh's dispatch model requires an explicit command name for every invocation (generate/apply-labels/find-previous/current-version/ create-release) - there is no bare `release-notes <owner> <repo>` shorthand for `generate` anymore. --label also moves from two tokens to one combined `<label>=<description>` token, and other flags move to kebab-case. Also fixes dotnet pack silently copying the unsigned obj/ build of this project's own assembly into the portable 'any' package instead of the correctly signed bin/ one (same fix as applied to assembly-differ and nupkg-validator). Co-authored-by: Cursor <cursoragent@cursor.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.
release-notesships as a self-contained native-AOT executable on five platforms, ported from F#/Arguto C#/Nullean.Argh.Prompt summary: Modernize this repo's build tooling the way
curbandmermaideralready do — package the tool as native-AOT dotnet tools per-RID with a framework-dependent fallback, moving CLI parsing ontoNullean.Arghwhere reflection-based parsers block AOT.Why
Argu's argument parsing leans on reflection over F# union case metadata, which native AOT trims away. A manual AOT publish of the old F# tool confirmed this: every flag came back asunrecognized argument. Porting to C#/Nullean.Argh, a Roslyn source generator with no reflection at parse time, unblocks AOT the same way it did for assembly-differ#41 and nupkg-validator#19.What
C# port
ReleaseNotesCommands.cs,ReleaseNotesRunner.cs,GithubScanner.cs,Labeler.cs,GitHubItem.cs, andOutputWriter.csreplace their F# counterparts (Program.fs,Arguments.fs,GithubScanner.fs,Labeler.fs,GithubItem.fs,OutputWriter.fs). Each subcommand (generate,apply-labels,find-previous,current-version,create-release) keeps its own explicit command name —MapAndRootAliasisn't used here because--versioncollides with Argh's own global--versionflag and silently prints the CLI version instead of running the command.Native-AOT packaging
release-notes.csprojgainslinux-x64,linux-arm64,win-x64,win-arm64, andosx-arm64asRuntimeIdentifiers, selected transparently through the root package'sDotnetToolSettings.xml(v2), plus a framework-dependentanyfallback.PublishAot,PublishSelfContained, andStripSymbolsapply only when a specific RID is targeted.Dependencies
Fake.Core.SemVeris replaced withNuGet.Versioning, andOctokitmoves from0.43.0to14.0.0— both reflection-free and AOT-friendly, where the F# tool's originals were not.Package staging and signing
generatePackagesstages a fulldotnet packand keeps only the root andanypackages, since the real per-RID packages come from CI. A signing fix replaces the unsignedobj/copy of this project's own assembly thatdotnet packputs inside theanypackage with the correctly signedbin/one.validatePackagesconfirms strong-name signing (PublicKeyToken=96c599bbe3e70f5d) on theanypackage for both TFMs.CI
.github/workflows/ci.ymladds anaot-packmatrix job building each RID on a matching runner, ahead of abuildjob that downloads and merges the artifacts before packages get published.Breaking
Argh's dispatch requires an explicit command name for every invocation — there's no bare
release-notes <owner> <repo> ...shorthand forgenerateanymore:--labelmoves from two tokens to one combined token (--label bug "Bug Fixes"becomes--label bug=Bug Fixes), and every other flag moves from a single word to kebab-case (--oldversionbecomes--old-version,--releaselabelbecomes--release-label-format). README updated with the full flag reference and examples for every command.Verify
./build.sh build generatepackages validatepackages generatereleasenotes -s true dotnet tool install --add-source build/output release-notes release-notes generate nullean release-notes --version 1.0.0