git-nuget-release-notes
Skill3 starsChanged 40 days agoMITView on GitHub
Use when the user wants per-package NuGet release notes in cumulative `.nuget/{ProjectName}/PackageReleaseNotes.txt` files, including creating missing files for packable `src/` projects. Do not use for repository `CHANGELOG.md`, GitHub releases, or package README work.
In this repository22 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agent-smithSkill
- dotnet-benchmarkSkill
- dotnet-change-impactSkill
- dotnet-docfx-digestSkill
- dotnet-new-app-slnxSkill
- dotnet-new-lib-slnxSkill
- dotnet-nuget-updateSkill
- dotnet-remote-testingSkill
- dotnet-segregated-assetsSkill
- dotnet-strong-name-signingSkill
- dotnet-testSkill
- git-keep-a-changelogSkill
- git-nuget-readmeSkill
- git-remote-prSkill
- git-remote-releaseSkill
- git-repo-digestSkill
- git-visual-commitsSkill
- git-visual-squash-summarySkill
- markdown-illustratorSkill
- skill-creator-agnosticSkill
- trunk-first-repoSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
38 rules. About 0 are common, 23 are distinctive, and 15 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈23
Distinctive · estimate
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 13
Read references/package-release-notes-format.md before writing any release-note block.
- Very specific: line 17
Create or update .nuget/{ProjectName}/PackageReleaseNotes.txt directly, then stop for user review.
- Distinctive: line 19
Treat a same-named tracking branch as a synchronization target, not the default release-note base.
- Very specific: line 21
Prefer an existing .nuget/{ProjectName}/ folder when one already exists for the packable project.
- Very specific: line 23
Every selected package must receive a complete target-version block with Version:, resolved Availability:, and a non-empty # ALM section, …
- Very specific: line 24
Treat the package's base-to-HEAD state as truth.
- Distinctive: line 28
Read full commit subjects and bodies before writing the package notes.
- Distinctive: line 30
Use cumulative newest-first history.
- Distinctive: line 31
If the target version already exists at the top of the file, rewrite that block in place instead of duplicating it.
- Distinctive: line 32
If the target version is not present, prepend the new block above the older history.
- Very specific: line 34
Always include # ALM and at least one ALM bullet in the block you write.
- Very specific: line 35
Use only this section order when sections are populated: ALM, Breaking Changes, New Features, Improvements, Bug Fixes, References.
- Very specific: line 37
Start every bullet with an all-caps action verb such as ADDED, CHANGED, REMOVED, FIXED, EXTENDED, OPTIMIZED, MOVED, RENAMED, DEPRECATED, or …
- Very specific: line 38
Keep package/type/member identifiers exact where possible.
- Distinctive: line 39
Do not dump commit subjects verbatim into the release notes.
- Distinctive: line 40
Do not invent unsupported changes, package references, or availability.
- Distinctive: line 65
When a scope is resolved, use this model for each target package:
- Distinctive: line 81
Read chronological commit subjects and bodies as supporting context.
- Distinctive: line 82
Use history to explain the surviving outcomes, then map them into the package-note sections.
- Distinctive: line 84
Do not accumulate bullets from individual commits and deduplicate them afterward.
- Very specific: line 109
If the user named a range, branch comparison, base branch, or PR range, use that.
- Very specific: line 111
Treat a same-named tracking branch such as origin/v10.8.0/options-enhancement for v10.8.0/options-enhancement as a synchronization target …
- Distinctive: line 114
If no safe integration branch or merge-base can be established, or the current branch is itself the integration branch, stop and ask for a …
- Very specific: line 140
Keep project identity anchored to the packable project name or the existing .nuget/{ProjectName}/ folder already used by the repo.
- Distinctive: line 161
If you cannot determine a safe concrete version, stop and ask instead of guessing.
- Distinctive: line 163
Do not infer a version by bumping the previous entry manually unless the user explicitly asked you to choose the next version.
- Very specific: line 169
Read TargetFramework or TargetFrameworks from the project and any inherited repo-level props when needed.
- Distinctive: line 181
Do not guess availability from memory if the project file or evaluated MSBuild properties can answer it.
- Distinctive: line 193
Read the full commit bodies only after the cumulative delta is clear.
- Very specific: line 207
Use the normalized section order from references/package-release-notes-format.md.
- Distinctive: line 218
Prefer a minimal complete block over an inflated one.
- Distinctive: line 224
Write the block in this normalized shape:
- Distinctive: line 240
If the file is missing, create it with the new block only.
- Distinctive: line 241
If the top block already targets the resolved version, replace that top block in place from the full resolved delta and leave older history …
- Distinctive: line 242
If the top block targets an older version, prepend the new block and a blank line before the existing history.
- Distinctive: line 245
Keep each bullet on one physical line regardless of length.
- Distinctive: line 246
Do not add decorative Markdown, tables, or changelog callouts.
- Very specific: line 252
After updating the relevant PackageReleaseNotes.txt files, stop and let the user review them.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Git NuGet Release Notes
Image: Git NuGet Release Notes
This skill creates or updates cumulative .nuget/{ProjectName}/PackageReleaseNotes.txt files for packable .NET projects by reading git history and the actual project/package metadata. It is intentionally closer to the package-note style used in codebelt repositories than to a repo-wide CHANGELOG.md.
Read references/package-release-notes-format.md before writing any release-note block.
Critical
- Create or update
.nuget/{ProjectName}/PackageReleaseNotes.txtdirectly, then stop for user review. - A bare invocation with a concrete version is a complete edit request. Resolve the full current branch against its integration branch and continue without asking for range confirmation when that default is safe.
- Treat a same-named tracking branch as a synchronization target, not the default release-note base. Pushing a branch must not shrink its release-note scope.
- Discover packable projects under
src/; ignoretest/,tuning/,tooling/, and projects that are explicitly non-packable. - Prefer an existing
.nuget/{ProjectName}/folder when one already exists for the packable project. If none exists, create.nuget/<MSBuildProjectName>/PackageReleaseNotes.txt. - A version-only invocation covers every packable
src/project, including unchanged projects. Narrow the package inventory only when the user explicitly selects packages or projects; an explicit git range alone does not narrow it. - Every selected package must receive a complete target-version block with
Version:, resolvedAvailability:, and a non-empty# ALMsection, even when its file already exists or its semantic delta is empty. - Treat the package's base-to-
HEADstate as truth; chronological history is supporting provenance. - Inspect cumulative package, API, manifest, version, and metadata deltas before classifying the package history.
- Classify each user-facing package capability from whether it existed at the resolved base before considering intermediate commits or individual files.
- Describe only surviving package outcomes. Do not preserve intermediate upgrades, removals, renames, or bug fixes that do not survive into
HEAD. - Read full commit subjects and bodies before writing the package notes.
- Inspect the net diff too; do not classify a package from commit subjects alone.
- Use cumulative newest-first history.
- If the target version already exists at the top of the file, rewrite that block in place instead of duplicating it.
- If the target version is not present, prepend the new block above the older history.
- Normalize the block you write to
Version:andAvailability:. - Always include
# ALMand at least one ALM bullet in the block you write. Use the required default below when there are no package-specific ALM outcomes. - Use only this section order when sections are populated:
ALM,Breaking Changes,New Features,Improvements,Bug Fixes,References. - Omit empty optional sections instead of emitting placeholders.
# ALMis mandatory and uses the required default when needed. - Start every bullet with an all-caps action verb such as
ADDED,CHANGED,REMOVED,FIXED,EXTENDED,OPTIMIZED,MOVED,RENAMED,DEPRECATED, orREFACTORED. - Keep package/type/member identifiers exact where possible.
- Do not dump commit subjects verbatim into the release notes.
- Do not invent unsupported changes, package references, or availability.
- Ignore odd historical spacing such as non-breaking spaces in older entries; normalize only the block you are writing unless the user asks for a larger cleanup.
Required Release Block
Package coverage and change classification are separate decisions. An empty semantic delta suppresses change-specific bullets, never the release block. If there are no package-specific ALM outcomes, use this exact default bullet:
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)This is the required package-release boilerplate, including for unchanged packages. It is not evidence that a named dependency changed; do not infer additional upgrade bullets from it. When actual ALM outcomes exist, describe them accurately instead of replacing their details with the default. Other sections contain only supported surviving outcomes.
The minimum complete block for an unchanged package is:
Version: <resolved-version>
Availability: <resolved-framework-list>
# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)Deterministic Package Delta Model
When a scope is resolved, use this model for each target package:
Result = semantic_delta(PackageBase, PackageHEAD)
History = provenance used to explain ResultHistory is evidence; the resulting state is truth.
Reduce first. Interpret second. Summarize last.
Establish the classification baseline at the user-facing package-capability boundary, not independently for every changed file or commit. If a capability is absent at the base and present at HEAD, it belongs under # New Features with an ADDED bullet; intermediate commits that refine, fix, document, or validate that capability cannot move it to # Improvements or # Bug Fixes. Dependency, TFM, packaging, or separately pre-existing capability changes remain distinct outcomes classified from their own base states.
- Inspect cumulative manifest, property, version, and metadata deltas that affect the package.
- Inspect the cumulative base-to-
HEADdiff for the package and its shared packaging files. - Determine which package changes actually survive at
HEAD. - Read chronological commit subjects and bodies as supporting context.
- Use history to explain the surviving outcomes, then map them into the package-note sections.
Do not accumulate bullets from individual commits and deduplicate them afterward.
Reconciliation rules:
- Base state and
HEADstate are identical -> no change-specific bullet; still write the complete target-version block with the default ALM text. - Dependency, API, metadata, or TFM value that returns to the base state -> no change-specific bullet; this never suppresses the required release block or default ALM text.
- Package capability absent at base and present at
HEAD-> one survivingADDEDoutcome under# New Features. Do not emitCHANGED,EXTENDED, orFIXEDoutcomes for refinements within that same introduction cycle. - Base present and
HEADabsent -> one surviving removal. - Base present and changed
HEADstate -> one surviving modification, fix, rename, or move derived from the final delta. - Equivalent entity/path/name moved or renamed -> one rename/move outcome when the cumulative diff supports it, not add plus remove.
Examples:
Newtonsoft.Json 13.0.3 -> 14.0.0 -> 13.0.3-> no dependency-specific# ALMbullet; keep the required default ALM block.Newtonsoft.Json 13.0.3 -> 14.0.0 -> 14.0.2-> one surviving upgrade from13.0.3to14.0.2.- Public API removed and later restored unchanged -> no
# Breaking Changesbullet. - Feature added, fixed several times, then removed -> no package-note entry for that feature.
- One capability added, reworked, fixed, documented, and still present -> one final
ADDEDbullet under# New Featuresdescribing what shipped.
Workflow
Step 1: Resolve the source range
Resolve the range from local, read-only git metadata in this order:
- If the user named a range, branch comparison, base branch, or PR range, use that. Preserve explicit range endpoints; for a branch comparison, resolve its merge-base with
HEAD. - Otherwise, resolve the repository's integration branch. Prefer the locally cached remote default branch, such as
origin/HEADresolving toorigin/main, then tryorigin/main,origin/master, localmain, and localmaster. A differently named upstream may be used when repository metadata or conventions establish it as the integration branch. - Treat a same-named tracking branch such as
origin/v10.8.0/options-enhancementforv10.8.0/options-enhancementas a synchronization target only. Use it as the base only when the user explicitly requested that comparison. Never limit the default scope to unpushed commits. - Resolve
<base>to the merge-base of the integration branch andHEAD, and use<base>..HEADfor the full branch delta. Keep the resolved endpoints fixed throughout inspection. - State the resolved range briefly and proceed with the edits. Do not ask the user to choose between the full branch and its latest commits when the default resolves safely.
- If no safe integration branch or merge-base can be established, or the current branch is itself the integration branch, stop and ask for a base branch or range instead of guessing. An explicit range remains usable on the integration branch.
A concrete version such as 10.8.0 selects the block to write; it does not select a git range. Do not switch to a previous-release tag merely because a version was supplied. A previous-release tag is a comparison boundary only when explicitly requested, and its own commit is excluded from <tag>..HEAD. Already released blocks remain historical output to preserve, not targets to regenerate.
The current target-version block is cached output, not a comparison baseline. Recompute it from the entire resolved delta even when earlier branch commits already wrote part of that block; this keeps surviving features and their later refinements together. Do not preserve obsolete bullets or drop earlier branch outcomes by using the draft's commit as the base.
Helpful commands:
git status --short --branch
git rev-parse --abbrev-ref HEAD
git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'
git symbolic-ref refs/remotes/origin/HEAD --short
git merge-base HEAD origin/main
git merge-base HEAD origin/master
git merge-base HEAD main
git merge-base HEAD masterStep 2: Discover the target packages
Discover the packable src/ projects that belong in .nuget/.
- Enumerate
src/**/*.csproj. - Exclude projects that live outside
src/or are clearly test, benchmark, sample, or tooling projects. - Exclude projects with
IsPackableexplicitly set tofalse. - Keep project identity anchored to the packable project name or the existing
.nuget/{ProjectName}/folder already used by the repo. - By default, select every packable
src/project. Honor an explicit package/project selection, but never use the changed-path list to exclude unchanged projects from the selected inventory. - Maintain that selected inventory through writing and final verification. An existing note file or an empty package diff does not satisfy target-version coverage.
Helpful commands:
rg --files src -g *.csproj
git diff --name-only <base>..HEAD -- src .nuget Directory.Build.props Directory.Build.targets Directory.Packages.propsStep 3: Resolve the concrete release version
Each release-note block needs a real package version, not an [Unreleased] placeholder.
Use this order:
- Explicit version provided by the user.
- Branch prefix such as
v0.3.1/feature-name->0.3.1. - Evaluated package version from the project if it is concrete and safe to use.
If you cannot determine a safe concrete version, stop and ask instead of guessing.
Do not infer a version by bumping the previous entry manually unless the user explicitly asked you to choose the next version.
Step 4: Resolve the availability line
Derive Availability: from the package's target frameworks.
- Read
TargetFrameworkorTargetFrameworksfrom the project and any inherited repo-level props when needed. - Reuse the prior Availability line when the current target frameworks are verified unchanged. Check the project and inherited framework settings; recompute the line if frameworks or their order changed. Apply this resolution to unchanged packages too.
- Preserve the project order when rendering frameworks.
- Convert TFMs to the human-readable style used by the existing files.
- Join the final list with commas and
and.
Examples:
net10.0;net9.0->.NET 10 and .NET 9net10.0;net9.0;netstandard2.0->.NET 10, .NET 9 and .NET Standard 2.0net10.0;net9.0;netstandard2.1;netstandard2.0->.NET 10, .NET 9, .NET Standard 2.1 and .NET Standard 2.0
Do not guess availability from memory if the project file or evaluated MSBuild properties can answer it.
Step 5: Inspect the cumulative package delta first
For each target package, use this order to understand the real release story.
- Build the package-specific path set: the package project, its source folder, any package-specific
.nuget/{ProjectName}/files, and shared packaging/build files that materially affect it. - Inspect cumulative manifest, property, version, and metadata deltas first. This includes
Directory.Packages.props, package references in project files,TargetFramework/TargetFrameworks, package metadata, and other shared packaging files that affect the package. - Inspect the cumulative base-to-
HEADdiff for the package paths. - Determine which package changes survive at
HEAD: public APIs, dependency versions, TFMs, package metadata, types/members, renames/moves, removals, and bug fixes that still exist. - Identify each user-facing package capability and test its existence at the resolved base before classifying its child files or commit verbs.
- Eliminate exact reversions, temporary features, reverted dependency churn, and restored APIs or metadata that match the base state.
- Read the full commit bodies only after the cumulative delta is clear. Use history to explain the surviving outcomes, confirm rename intent, understand migration context, and choose accurate user-facing terminology. Never let an intermediate commit override contradictory final-state evidence.
Helpful commands:
git diff --name-status -M -C <base>..HEAD -- <paths>
git diff --stat <base>..HEAD -- <paths>
git diff <base>..HEAD -- <paths>
git log --reverse --format=medium <range> -- <paths>
git log --reverse --stat --format=medium <range> -- <paths>Step 6: Classify the content into the package-note format
Use the normalized section order from references/package-release-notes-format.md.
Classification guidance:
# ALM: describe surviving dependency upgrades/downgrades, TFM support changes, packaging metadata changes, or other release-engineering/package-management changes. Use the final before -> after versions that remain atHEAD. If none exist for the package, write the exact required default ALM bullet from Required Release Block; never omit the section or leave it empty.# Breaking Changes: only incompatible renames, removals, moved APIs, changed contracts, or behavior that still requires consumer action atHEAD.# New Features: only additive APIs, capabilities, packages, or options that are absent at the base state and present atHEAD.# Improvements: surviving non-breaking enhancements such asCHANGED,EXTENDED,OPTIMIZED,DEPRECATED, or other refinements to existing behavior.# Bug Fixes: surviving defect corrections for behavior that remains changed versus the base state.# References: package IDs only, and only when the package is an umbrella/meta package or the existing file already carries a references section the current release should preserve.
Prefer a minimal complete block over an inflated one. ALM-only blocks are required for selected packages with no surviving changes, as well as valid for dependency or TFM maintenance.
A restored API or reverted dependency upgrade does not earn a section entry. Use history to help group or explain the surviving outcomes, not to manufacture extra bullets.
Refinement or bug-fix commits made after a capability was first added but before its first release remain part of the ADDED new-feature outcome. # Improvements and # Bug Fixes require the affected capability or behavior to exist at the resolved base.
Step 7: Write or update PackageReleaseNotes.txt
Write the block in this normalized shape:
Version: 0.3.1
Availability: .NET 10 and .NET 9
# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)
# New Features
- ADDED ...Editing rules:
- Apply these rules to every selected package, including unchanged packages. Do not stop after editing only the packages with source or dependency changes.
- If the file is missing, create it with the new block only.
- If the top block already targets the resolved version, replace that top block in place from the full resolved delta and leave older history below it intact. Existing draft bullets are not independent evidence or a reason to narrow the range.
- If the top block targets an older version, prepend the new block and a blank line before the existing history.
- An existing target-version block is complete only when its version, availability, non-empty ALM section, and supported change bullets all satisfy this workflow. Repair missing ALM even if its feature text already matches the delta.
- Preserve older release blocks below the edited one unless the user explicitly asked for a historical cleanup.
- Keep each bullet on one physical line regardless of length. Do not hard-wrap at a fixed column width; rely on editor soft wrapping instead.
- Do not add decorative Markdown, tables, or changelog callouts.
Step 8: Stop after the edit
Before stopping, reconcile the selected project inventory against the written target-version blocks. Read each selected file and verify exactly one target-version block at the top, resolved availability, and # ALM with either accurate package-specific outcomes or the exact default bullet. Verify older blocks remain intact. A file's existence alone is not coverage; no selected package may remain on an older version or lack ALM. Correct missing or incomplete blocks before handing back the result.
After updating the relevant PackageReleaseNotes.txt files, stop and let the user review them. Do not commit, tag, push, pack, or publish unless the user asks.
Good Output Characteristics
- Reads like curated package release notes, not a repo-wide changelog.
- Keeps one truthful release block per package/version.
- Covers every selected packable package, including unchanged packages, with a complete target-version block and non-empty ALM.
- Classifies each package from its surviving base-to-
HEADdelta; reverted churn disappears. - Uses concrete package/type/member names and namespaces.
- Writes the newest release first while preserving older history.
- Keeps ALM details explicit when dependencies or TFMs changed.
- Creates missing files when the package should be represented.
- Keeps availability aligned with actual target frameworks.
Bad Output Characteristics
- Writing one repo-level summary and copying it into every package file.
- Skipping unchanged selected packages, leaving them on a prior version, or accepting a target-version block without ALM.
- Using
Unreleasedor omitting the concrete version line. - Guessing availability instead of reading project metadata.
- Dumping commit subjects line by line into the file.
- Reporting temporary dependency, API, metadata, or TFM changes that do not survive into
HEAD. - Emitting
# Breaking Changes,# New Features, or# Bug Fixesbullets for work that was later restored or removed before release. - Moving a base-absent capability into
# Improvementsor# Bug Fixesbecause intermediate commits refined or fixed it before its first release. - Creating empty headings or filler bullets like "misc updates".
- Claiming breaking changes, fixes, or references not supported by git and the project/package metadata.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

