Add idempotency guards to release skills
- release-changelog: Step 0 checks for existing changelog file before generating. Asks reviewer to keep/regenerate/update. Never overwrites silently. Clarifies this skill never triggers version bumps. - release: Step 0 idempotency table covering all steps. Tag check before npm publish prevents double-release. Task search before creation prevents duplicate follow-up tasks. Supports iterating on changelogs pre-publish. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,38 @@ finalizing. Never auto-publish.
|
||||
|
||||
---
|
||||
|
||||
## Step 0 — Idempotency Check
|
||||
|
||||
Before generating anything, check if a changelog already exists for this version:
|
||||
|
||||
```bash
|
||||
ls releases/v{version}.md 2>/dev/null
|
||||
```
|
||||
|
||||
**If the file already exists:**
|
||||
|
||||
1. Read the existing changelog and present it to the reviewer.
|
||||
2. Ask: "A changelog for v{version} already exists. Do you want to (a) keep it
|
||||
as-is, (b) regenerate from scratch, or (c) update specific sections?"
|
||||
3. If the reviewer says keep it → **stop here**. Do not overwrite. This skill is
|
||||
done.
|
||||
4. If the reviewer says regenerate → back up the existing file to
|
||||
`releases/v{version}.md.prev`, then proceed from Step 1.
|
||||
5. If the reviewer says update → read the existing file, proceed through Steps
|
||||
1-4 to gather fresh data, then merge changes into the existing file rather
|
||||
than replacing it wholesale. Preserve any manual edits the reviewer previously
|
||||
made.
|
||||
|
||||
**If the file does not exist:** Proceed normally from Step 1.
|
||||
|
||||
**Critical rule:** This skill NEVER triggers a version bump. It only reads git
|
||||
history and writes a markdown file. The `release.sh` script is the only thing
|
||||
that bumps versions, and it is called separately by the `release` coordination
|
||||
skill. Running this skill multiple times is always safe — worst case it
|
||||
overwrites a draft changelog (with reviewer permission).
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Determine the Release Range
|
||||
|
||||
Find the last release tag and the planned version:
|
||||
|
||||
@@ -57,6 +57,29 @@ Collect these inputs up front:
|
||||
|
||||
---
|
||||
|
||||
## Step 0 — Idempotency Guards
|
||||
|
||||
Each step in this skill is designed to be safely re-runnable. Before executing
|
||||
any step, check whether it has already been completed:
|
||||
|
||||
| Step | How to Check | If Already Done |
|
||||
|---|---|---|
|
||||
| Changelog | `releases/v{version}.md` exists | Read it, ask reviewer to confirm or update. Do NOT regenerate without asking. |
|
||||
| npm publish | `git tag v{version}` exists | Skip `release.sh` entirely. A tag means the version is already published. **Never re-run release.sh for an existing tag** — it will fail or create a duplicate. |
|
||||
| Website task | Search Paperclip issues for "Publish release notes for v{version}" | Skip creation. Link the existing task. |
|
||||
| CMO task | Search Paperclip issues for "release announcement tweet for v{version}" | Skip creation. Link the existing task. |
|
||||
|
||||
**The golden rule:** If a git tag `v{version}` already exists, the npm release
|
||||
has already happened. Only post-publish tasks (website, CMO, wrap-up) should
|
||||
proceed. Never attempt to re-publish.
|
||||
|
||||
**Iterating on changelogs:** You can re-run this skill with an existing changelog
|
||||
to refine it _before_ the npm publish step. The `release-changelog` skill has
|
||||
its own idempotency check and will ask the reviewer what to do with an existing
|
||||
file. This is the expected workflow for iterating on release notes.
|
||||
|
||||
---
|
||||
|
||||
## Step 1 - Pre-flight and Version Decision
|
||||
|
||||
Run pre-flight in the App repo root:
|
||||
@@ -91,6 +114,10 @@ If requested bump is lower than required minimum, escalate bump and explain why.
|
||||
|
||||
## Step 2 - Generate Changelog Draft
|
||||
|
||||
First, check if `releases/v{version}.md` already exists. If it does, the
|
||||
`release-changelog` skill will detect this and ask the reviewer whether to keep,
|
||||
regenerate, or update it. **Do not silently overwrite an existing changelog.**
|
||||
|
||||
Invoke the `release-changelog` skill and produce:
|
||||
- `releases/v{version}.md`
|
||||
- Sections ordered as: Breaking Changes (if any), Highlights, Improvements, Fixes, Upgrade Guide (if any)
|
||||
@@ -105,13 +132,24 @@ Required behavior:
|
||||
|
||||
## Step 3 - Run App Release
|
||||
|
||||
After changelog approval, execute:
|
||||
**Idempotency check:** Before running `release.sh`, verify the tag doesn't
|
||||
already exist:
|
||||
|
||||
```bash
|
||||
git tag -l "v{version}"
|
||||
```
|
||||
|
||||
If the tag exists, this version has already been published. **Do not re-run
|
||||
`release.sh`.** Skip to Step 4 (follow-up tasks). Log that the publish was
|
||||
already completed and capture the existing tag metadata.
|
||||
|
||||
If the tag does NOT exist, proceed with the release:
|
||||
|
||||
```bash
|
||||
# dry run
|
||||
./scripts/release.sh {patch|minor|major} --dry-run
|
||||
|
||||
# live release
|
||||
# live release (only after dry-run review)
|
||||
./scripts/release.sh {patch|minor|major}
|
||||
```
|
||||
|
||||
@@ -130,7 +168,17 @@ failure logs in the update.
|
||||
|
||||
## Step 4 - Create Cross-Project Follow-up Tasks
|
||||
|
||||
Create at least two tasks in Paperclip:
|
||||
**Idempotency check:** Before creating tasks, search for existing ones:
|
||||
|
||||
```
|
||||
GET /api/companies/{companyId}/issues?q=release+notes+v{version}
|
||||
GET /api/companies/{companyId}/issues?q=announcement+tweet+v{version}
|
||||
```
|
||||
|
||||
If matching tasks already exist (check title contains the version), skip
|
||||
creation and link the existing tasks instead. Do not create duplicates.
|
||||
|
||||
Create at least two tasks in Paperclip (only if they don't already exist):
|
||||
|
||||
1. Website task: publish changelog for `v{version}`
|
||||
2. CMO task: draft announcement tweet for `v{version}`
|
||||
|
||||
Reference in New Issue
Block a user