From 9bd3f908ba636a187928b98a96b8ed0d0a6c83b2 Mon Sep 17 00:00:00 2001 From: Stephen Wakely Date: Mon, 27 Apr 2026 12:27:23 +0100 Subject: [PATCH 1/4] Add skills to help release the package --- .claude/skills/prepare-release/SKILL.md | 110 ++++++++++++++++++++++++ .claude/skills/publish-release/SKILL.md | 85 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 .claude/skills/prepare-release/SKILL.md create mode 100644 .claude/skills/publish-release/SKILL.md diff --git a/.claude/skills/prepare-release/SKILL.md b/.claude/skills/prepare-release/SKILL.md new file mode 100644 index 0000000..89c7a85 --- /dev/null +++ b/.claude/skills/prepare-release/SKILL.md @@ -0,0 +1,110 @@ +--- +name: prepare-release +description: "Prepare a DogStatsD C# client release PR. Creates a release branch, updates CHANGELOG.md, runs pimpmychangelog, bumps version in StatsdClient.csproj, commits, and opens a GitHub PR targeting master. Triggers on: prepare release, create release PR, start release, open release branch." +user-invocable: true +--- + +# Prepare Release PR + +Create a release branch with version bump and changelog, then open a PR for review. + +--- + +## Step 1: Confirm Version + +If the user did not supply a version number, read `src/StatsdClient/StatsdClient.csproj` and show the current ``. Ask: "Prepare release for X.Y.Z?" and wait for confirmation before proceeding. + +--- + +## Step 2: Create Release Branch + +```bash +git checkout master +git pull origin master +git checkout -b release/X.Y.Z +``` + +--- + +## Step 3: Update CHANGELOG.md + +- Open `CHANGELOG.md`. +- If a section for the target version already exists, leave it as-is. +- If not, add a new section at the top (below the `CHANGELOG\n=========` header) in the same format as existing entries: + +``` +# X.Y.Z / YYYY-MM-DD + +## Changes + +* [FEATURE/IMPROVEMENT/BUGFIX] Description here. See [#NNN][]. +``` + +Use today's date. Do **not** delete any existing entries. + +After writing, run `pimpmychangelog` from the repo root. It rewrites `CHANGELOG.md` in-place to add GitHub-style reference links at the bottom. Show the user the diff and ask if they want to adjust the changelog before continuing. + +--- + +## Step 4: Update Version in StatsdClient.csproj + +Edit `src/StatsdClient/StatsdClient.csproj`: +- Set `` to the release version. +- Set `` to the major version, do not change the minor version (always `MAJOR.MINOR.PATCH`, no pre-release suffix). + +> : This is the assembly version. You must update this value only when there is a major version change. See Create strong named .NET libraries for explanations. +> Example: When updating from version 4.0.0 to version 4.1.0, you must set 4.1.0 and 4.0.0 (and NOT 4.1.0). + +Example — releasing `9.2.0`: +```xml +9.2.0 +9.0.0 +``` + +--- + +## Step 5: Commit and Push + +```bash +git add CHANGELOG.md src/StatsdClient/StatsdClient.csproj +git commit -m "Release version X.Y.Z" +git push -u origin release/X.Y.Z +``` + +--- + +## Step 6: Open Pull Request + +Create a PR targeting `master`: + +```bash +gh pr create \ + --base master \ + --title "Release X.Y.Z" \ + --body "$(cat <<'EOF' +## Release X.Y.Z + +Changelog and version bump for the X.Y.Z NuGet release. + +### Checklist +- [ ] Changelog entries are accurate +- [ ] Version numbers are correct +- [ ] PR approved and ready to merge + +Once merged, run `/publish-release` to tag, build, and push to NuGet. +EOF +)" +``` + +Show the user the PR URL. + +--- + +## Summary Checklist + +- [ ] Branch `release/X.Y.Z` created from latest master +- [ ] CHANGELOG.md updated with release entry +- [ ] `pimpmychangelog` run +- [ ] `` and `` bumped in csproj +- [ ] Commit pushed to `release/X.Y.Z` +- [ ] PR opened targeting master diff --git a/.claude/skills/publish-release/SKILL.md b/.claude/skills/publish-release/SKILL.md new file mode 100644 index 0000000..87b09b8 --- /dev/null +++ b/.claude/skills/publish-release/SKILL.md @@ -0,0 +1,85 @@ +--- +name: publish-release +description: "Publish a merged DogStatsD C# client release. Tags the merged master commit, pushes the tag, builds the NuGet package, and uploads to NuGet.org. Run after the release PR is merged. Triggers on: publish release, push to nuget, tag release, ship release." +user-invocable: true +--- + +# Publish Release + +Tag the merged release, build the NuGet package, and push to NuGet.org. + +**Pre-condition:** The release PR must already be merged into master before running this. + +--- + +## Step 1: Confirm Version + +Read the version from `src/StatsdClient/StatsdClient.csproj` (``). Show it to the user and confirm: "Publish release X.Y.Z?" before proceeding. + +--- + +## Step 2: Switch to Master and Pull + +```bash +git checkout master +git pull origin master +``` + +Verify the top commit is the release commit (message should be "Release version X.Y.Z"). If it is not, stop and tell the user to ensure the release PR is merged before running this skill. + +--- + +## Step 3: Tag the Release + +```bash +git tag X.Y.Z +git push origin X.Y.Z +``` + +--- + +## Step 4: Build NuGet Package + +```bash +dotnet pack src/StatsdClient/StatsdClient.csproj -c Release -o artifacts/nuget +``` + +Verify the command exits 0 and that `artifacts/nuget/DogStatsD-CSharp-Client.X.Y.Z.nupkg` exists. + +--- + +## Step 5: Push to NuGet.org + +**Pause here.** Ask the user: + +> "Ready to push `DogStatsD-CSharp-Client.X.Y.Z.nupkg` to NuGet.org. Is `NUGET_API_KEY` set? Proceed?" + +Only run after explicit confirmation. + +Push the main package: + +```bash +dotnet nuget push artifacts/nuget/DogStatsD-CSharp-Client.X.Y.Z.nupkg \ + --api-key "$NUGET_API_KEY" \ + --source https://api.nuget.org/v3/index.json \ + --skip-duplicate +``` + +Push symbols if present: + +```bash +dotnet nuget push artifacts/nuget/DogStatsD-CSharp-Client.X.Y.Z.snupkg \ + --api-key "$NUGET_API_KEY" \ + --source https://api.nuget.org/v3/index.json \ + --skip-duplicate +``` + +--- + +## Summary Checklist + +- [ ] On latest master with release commit at HEAD +- [ ] Git tag X.Y.Z created and pushed +- [ ] `dotnet pack` succeeded, .nupkg exists +- [ ] .nupkg pushed to NuGet.org +- [ ] .snupkg (symbols) pushed to NuGet.org From 799e4b86c98cb6ebcc179d4a38d57c88e0169c2f Mon Sep 17 00:00:00 2001 From: Stephen Wakely Date: Mon, 27 Apr 2026 13:02:50 +0100 Subject: [PATCH 2/4] Drop verification check on commit comment. --- .claude/skills/publish-release/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/publish-release/SKILL.md b/.claude/skills/publish-release/SKILL.md index 87b09b8..e5e00ae 100644 --- a/.claude/skills/publish-release/SKILL.md +++ b/.claude/skills/publish-release/SKILL.md @@ -25,7 +25,7 @@ git checkout master git pull origin master ``` -Verify the top commit is the release commit (message should be "Release version X.Y.Z"). If it is not, stop and tell the user to ensure the release PR is merged before running this skill. +Re-read `` from `src/StatsdClient/StatsdClient.csproj` and verify it still matches X.Y.Z. If it does not, stop and tell the user to ensure the release PR is merged before running this skill. --- From 9f5766a7afa1246edafb111b5d19bbbd1d3760c3 Mon Sep 17 00:00:00 2001 From: Stephen Wakely Date: Mon, 27 Apr 2026 13:04:44 +0100 Subject: [PATCH 3/4] Fall back to when absent in prepare-release --- .claude/skills/prepare-release/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/prepare-release/SKILL.md b/.claude/skills/prepare-release/SKILL.md index 89c7a85..b70cd2d 100644 --- a/.claude/skills/prepare-release/SKILL.md +++ b/.claude/skills/prepare-release/SKILL.md @@ -12,7 +12,7 @@ Create a release branch with version bump and changelog, then open a PR for revi ## Step 1: Confirm Version -If the user did not supply a version number, read `src/StatsdClient/StatsdClient.csproj` and show the current ``. Ask: "Prepare release for X.Y.Z?" and wait for confirmation before proceeding. +If the user did not supply a version number, read `src/StatsdClient/StatsdClient.csproj` and show the current version. Use `` if present; otherwise fall back to ``. Ask: "Prepare release for X.Y.Z?" and wait for confirmation before proceeding. --- From 0ba843411e5d84fc9f180111559c812b4d5e4fae Mon Sep 17 00:00:00 2001 From: Stephen Wakely Date: Tue, 28 Apr 2026 12:30:44 +0100 Subject: [PATCH 4/4] Update skill to use `gh release`. --- .claude/skills/publish-release/SKILL.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.claude/skills/publish-release/SKILL.md b/.claude/skills/publish-release/SKILL.md index e5e00ae..434c15b 100644 --- a/.claude/skills/publish-release/SKILL.md +++ b/.claude/skills/publish-release/SKILL.md @@ -29,13 +29,24 @@ Re-read `` from `src/StatsdClient/StatsdClient.csproj` and verif --- -## Step 3: Tag the Release +## Step 3: Tag the Release and Publish GitHub Release + +Use `gh release create` — creates the tag, pushes it, and publishes a GitHub Release in one step. + +Extract the X.Y.Z section from `CHANGELOG.md` into a temp file (everything between the `## X.Y.Z` heading and the next `## ` heading), then: ```bash -git tag X.Y.Z -git push origin X.Y.Z +gh release create X.Y.Z --target master --title "X.Y.Z" --notes-file ``` +If extraction is awkward, fall back to `--generate-notes` (auto from commits/PRs): + +```bash +gh release create X.Y.Z --target master --title "X.Y.Z" --generate-notes +``` + +Verify tag pushed: `git fetch --tags && git tag -l X.Y.Z`. + --- ## Step 4: Build NuGet Package @@ -79,7 +90,8 @@ dotnet nuget push artifacts/nuget/DogStatsD-CSharp-Client.X.Y.Z.snupkg \ ## Summary Checklist - [ ] On latest master with release commit at HEAD -- [ ] Git tag X.Y.Z created and pushed +- [ ] Git tag X.Y.Z created and pushed via `gh release create` +- [ ] GitHub Release X.Y.Z published with notes - [ ] `dotnet pack` succeeded, .nupkg exists - [ ] .nupkg pushed to NuGet.org - [ ] .snupkg (symbols) pushed to NuGet.org