|
| 1 | +--- |
| 2 | +name: release-plannotator |
| 3 | +description: Prepare and execute a Plannotator release — draft release notes with full contributor credit, bump versions across all package files, build in dependency order, and kick off the tag-driven release pipeline. Use this skill whenever the user mentions preparing a release, bumping versions, writing release notes, tagging a release, or publishing. Also trigger when the user says things like "let's ship", "prep a release", "what's changed since last release", or "time to cut a new version". |
| 4 | +--- |
| 5 | + |
| 6 | +# Plannotator Release |
| 7 | + |
| 8 | +The process has four phases. Phase 1 (release notes) is where most of the work happens — present the draft for review before proceeding to later phases. |
| 9 | + |
| 10 | +## Phase 1: Draft Release Notes |
| 11 | + |
| 12 | +This is the most important phase. The release notes are the public face of each version and the primary way the community sees their contributions recognized. |
| 13 | + |
| 14 | +### Step 1: Determine scope |
| 15 | + |
| 16 | +1. Find the latest release tag: `git tag --sort=-v:refname | head -1` |
| 17 | +2. Determine the new version number. Ask the user if unclear (patch, minor, or major). |
| 18 | +3. Gather all changes since the last tag: |
| 19 | + - `git log --oneline <last-tag>..HEAD` for commit history |
| 20 | + - `git log --merges --oneline <last-tag>..HEAD` for merged PRs |
| 21 | +4. For each PR, use `gh pr view <number> --json title,author,body,closedIssues,labels` to get details. |
| 22 | + |
| 23 | +### Step 2: Research contributors |
| 24 | + |
| 25 | +This is critical. Every person who participated in the release gets credit — not just PR authors. |
| 26 | + |
| 27 | +For each PR and linked issue, collect: |
| 28 | +- **PR authors** — the person who wrote the code |
| 29 | +- **Issue reporters** — who filed the bug or feature request |
| 30 | +- **Issue commenters** — who participated in the discussion with useful context |
| 31 | +- **Discussion creators** — who started relevant GitHub Discussions |
| 32 | +- **Feature requestors** — check the linked "closes #N" issues and their authors |
| 33 | + |
| 34 | +Use the GitHub API via `gh`: |
| 35 | +```bash |
| 36 | +# Get issue details including author |
| 37 | +gh issue view <number> --json author,title,body |
| 38 | + |
| 39 | +# Get issue comments to find participants |
| 40 | +gh api repos/backnotprop/plannotator/issues/<number>/comments --jq '.[].user.login' |
| 41 | + |
| 42 | +# Get PR review comments |
| 43 | +gh api repos/backnotprop/plannotator/pulls/<number>/comments --jq '.[].user.login' |
| 44 | +``` |
| 45 | + |
| 46 | +### Step 3: Write the release notes |
| 47 | + |
| 48 | +Read the reference release notes in `references/` for the canonical template structure. These are real release notes from previous versions — match their tone, structure, and level of detail. |
| 49 | + |
| 50 | +- `release-notes-v0.13.0.md` — large release, 14 PRs, 3 first-time contributors, "New Contributors" + narrative "Contributors" section |
| 51 | +- `release-notes-v0.12.0.md` — large community release, 14 PRs, 10 external, detailed narrative "Contributors" section |
| 52 | +- `release-notes-v0.13.1.md` — small patch release, 2 PRs, no external authors, "Community" section focused on issue reporters |
| 53 | + |
| 54 | +Pay attention to how each reference handles contributor crediting differently. Pick the pattern that fits the release's contributor profile — a release with many external PRs warrants a narrative "Contributors" section; a patch driven by issue reports uses a lighter "Community" section. |
| 55 | + |
| 56 | +Write the file to the repo root as `RELEASE_NOTES_v<VERSION>.md`. |
| 57 | + |
| 58 | +#### Structure |
| 59 | + |
| 60 | +1. **X/Twitter follow link** — first line, always the same: |
| 61 | + ``` |
| 62 | + Follow [@plannotator](https://x.com/plannotator) on X for updates |
| 63 | + ``` |
| 64 | + |
| 65 | +2. **"Missed recent releases?"** collapsible table — copy from the previous release's notes, then: |
| 66 | + - Add the previous release (the one you're succeeding) as the newest row |
| 67 | + - Keep roughly 10-12 rows; drop the oldest if needed |
| 68 | + - Each row: version link + comma-separated feature highlights (short phrases) |
| 69 | + |
| 70 | +3. **"What's New in vX.Y.Z"** — the heart of the notes |
| 71 | + - Open with 1-3 sentences summarizing the release theme and scope. Mention how many PRs, how many from external contributors, any first-timers. |
| 72 | + - Each major feature/fix gets its own `###` subsection with: |
| 73 | + - A descriptive heading (not the PR title verbatim — rephrase for clarity) |
| 74 | + - 1-4 paragraphs explaining what changed and why it matters. Be specific and concrete. Describe the problem that existed before, what the change does, and how users experience it. |
| 75 | + - Credit line at the bottom: PR link, linked issues with `closing [#N]`, and contributor attribution |
| 76 | + - Minor changes go under `### Additional Changes` as bold-titled bullets |
| 77 | + |
| 78 | +4. **Install / Update** — standard block, read from the previous release notes and reuse verbatim |
| 79 | + |
| 80 | +5. **"What's Changed"** — bullet list of every PR in the release: |
| 81 | + ``` |
| 82 | + - feat: descriptive PR title by @author in [#N](url) |
| 83 | + ``` |
| 84 | + |
| 85 | +6. **"New Contributors"** — if any first-time contributors: |
| 86 | + ``` |
| 87 | + - @username made their first contribution in [#N](url) |
| 88 | + ``` |
| 89 | + |
| 90 | +7. **"Contributors" or "Community"** — narrative section recognizing everyone who participated: |
| 91 | + - PR authors get a sentence about what they built |
| 92 | + - Issue reporters and commenters get listed with what they reported/discussed |
| 93 | + - Group community issue reporters in a bullet list at the end |
| 94 | + |
| 95 | +8. **Full Changelog link**: |
| 96 | + ``` |
| 97 | + **Full Changelog**: https://github.com/backnotprop/plannotator/compare/<prev-tag>...<new-tag> |
| 98 | + ``` |
| 99 | + |
| 100 | +#### Writing guidelines |
| 101 | + |
| 102 | +- **Narrative over noise.** Write in clear, readable prose. Not marketing-speak, not changelog-dump. Explain what changed and why someone should care, in plain language. |
| 103 | +- **Bullets where they help.** Use bullet lists for enumerating discrete items (additional changes, contributor lists). Use paragraphs for explaining features. |
| 104 | +- **No cliches or buzzwords.** Don't say "exciting", "game-changing", "seamless", "powerful". Just describe what happened. |
| 105 | +- **No punchlines.** Don't end sections with a clever quip or a summary zinger. Let the feature speak for itself. |
| 106 | +- **Speak through practical benefit.** Describe what changed and what it means for the user in concrete, reliable terms. Not aspirational, not hype — just what it does. |
| 107 | +- **Don't overuse em dashes.** One or two per release is fine. If you notice them stacking up, restructure the sentence instead. |
| 108 | +- **Grammatical structure matters.** Vary sentence structure. Active voice. Concrete subjects and verbs. |
| 109 | +- **Contributor tags.** Use `@username` — bare at-mentions, not markdown links like `[@user](url)`. GitHub renders bare `@mentions` with avatar icons in release notes. This is important for community recognition. |
| 110 | +- **Every contributor counts.** Everyone who filed an issue, left a comment that shaped a decision, or participated in a discussion gets mentioned. This project's community is its lifeblood. |
| 111 | + |
| 112 | +### Step 4: Present for review |
| 113 | + |
| 114 | +Write the draft to `RELEASE_NOTES_v<VERSION>.md` in the repo root and tell the user it's ready for review. Do not `git add` or commit this file — release notes are kept untracked by design. Wait for their feedback before proceeding to Phase 2. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +## Phase 2: Version Bump |
| 119 | + |
| 120 | +Bump the version string in these **5 files** (and only these — other package.json files use stub versions): |
| 121 | + |
| 122 | +| File | Field | |
| 123 | +|------|-------| |
| 124 | +| `package.json` (root) | `"version"` | |
| 125 | +| `apps/opencode-plugin/package.json` | `"version"` | |
| 126 | +| `apps/pi-extension/package.json` | `"version"` | |
| 127 | +| `apps/hook/.claude-plugin/plugin.json` | `"version"` | |
| 128 | +| `packages/server/package.json` | `"version"` | |
| 129 | + |
| 130 | +Read each file, confirm the current version matches expectations, then update all 5 atomically. |
| 131 | + |
| 132 | +Do not bump the VS Code extension (`apps/vscode-extension/package.json`) — it has independent versioning. |
| 133 | + |
| 134 | +--- |
| 135 | + |
| 136 | +## Phase 3: Build |
| 137 | + |
| 138 | +Run builds in dependency order: |
| 139 | + |
| 140 | +```bash |
| 141 | +bun run build:review # 1. Code review editor (standalone Vite build) |
| 142 | +bun run build:hook # 2. Plan review + hook server (copies review's built HTML into hook dist) |
| 143 | +bun run build:opencode # 3. OpenCode plugin (copies built HTML from hook + review) |
| 144 | +bun run build:pi # 4. Pi extension (chains review → hook → pi internally, safe to run after 1-2) |
| 145 | +``` |
| 146 | + |
| 147 | +`build:pi` chains review and hook internally, so after steps 1-2 it only runs the pi-specific build. |
| 148 | + |
| 149 | +Verify all builds succeed before proceeding. |
| 150 | + |
| 151 | +--- |
| 152 | + |
| 153 | +## Phase 4: Commit, Tag, and Release |
| 154 | + |
| 155 | +1. **Commit the version bump:** |
| 156 | + ``` |
| 157 | + chore: bump version to X.Y.Z |
| 158 | + ``` |
| 159 | + Stage only the 5 version-bumped files. Do not stage the release notes file (it's untracked by design). |
| 160 | + |
| 161 | +2. **Create and push the tag:** |
| 162 | + ```bash |
| 163 | + git tag vX.Y.Z |
| 164 | + git push origin main |
| 165 | + git push origin vX.Y.Z |
| 166 | + ``` |
| 167 | + The `v*` tag push triggers the release pipeline (`.github/workflows/release.yml`). |
| 168 | + |
| 169 | +3. **The pipeline handles everything else:** |
| 170 | + - Runs tests |
| 171 | + - Cross-compiles binaries for 5 platforms (macOS ARM64/x64, Linux x64/ARM64, Windows x64) |
| 172 | + - Compiles paste service binaries (same 5 platforms) |
| 173 | + - Creates the GitHub Release with all binaries attached |
| 174 | + - Publishes `@plannotator/opencode` and `@plannotator/pi-extension` to npm with provenance |
| 175 | + |
| 176 | +4. **Monitor the pipeline:** |
| 177 | + Watch the release workflow run until it completes: |
| 178 | + ```bash |
| 179 | + gh run list --workflow=release.yml --limit=1 |
| 180 | + gh run view <run-id> --log |
| 181 | + ``` |
| 182 | + Verify: |
| 183 | + - All jobs pass (test, build, release, npm-publish) |
| 184 | + - The GitHub Release was created with all binary artifacts |
| 185 | + - npm packages published successfully (check with `npm view @plannotator/opencode version` and `npm view @plannotator/pi-extension version`) |
| 186 | + |
| 187 | + If anything fails, investigate the logs and report to the user before retrying. |
| 188 | + |
| 189 | +5. **Replace the release notes:** |
| 190 | + Once the release is live and verified, replace the auto-generated notes body with the drafted release notes: |
| 191 | + ```bash |
| 192 | + gh release edit vX.Y.Z --notes-file RELEASE_NOTES_v<VERSION>.md |
| 193 | + ``` |
| 194 | + |
| 195 | +--- |
| 196 | + |
| 197 | +## Checklist |
| 198 | + |
| 199 | +Before tagging, verify: |
| 200 | +- [ ] All 5 version files bumped consistently |
| 201 | +- [ ] Release notes drafted and reviewed |
| 202 | +- [ ] `bun run build:review` succeeded |
| 203 | +- [ ] `bun run build:hook` succeeded |
| 204 | +- [ ] `bun run build:opencode` succeeded |
| 205 | +- [ ] `bun run build:pi` succeeded (or pi-specific build step) |
| 206 | +- [ ] Version bump committed |
| 207 | +- [ ] No stale build artifacts (clean builds, no cache issues — run `bun install` first if dependencies changed) |
| 208 | + |
| 209 | +After tagging, verify: |
| 210 | +- [ ] Release workflow completed (all 4 jobs green) |
| 211 | +- [ ] GitHub Release created with all binaries |
| 212 | +- [ ] npm packages published at correct version |
| 213 | +- [ ] Release notes replaced via `gh release edit` |
0 commit comments