$npx -y skills add Shpigford/chops --skill releaseDetermine the next version, update the marketing site, and run the full release pipeline.
| 1 | Cut a new release of Chops. Determines the version from git history, updates the marketing site, and runs the release script. |
| 2 | |
| 3 | ## Instructions |
| 4 | |
| 5 | ### Step 1: Verify prerequisites |
| 6 | |
| 7 | 1. Confirm `.env` exists in the project root. If it does not, stop and tell the user: |
| 8 | "Missing `.env` file. Copy `.env.example` to `.env` and fill in APPLE_TEAM_ID, APPLE_ID, and SIGNING_IDENTITY_NAME." |
| 9 | 2. Confirm the notarytool keychain profile `AC_PASSWORD` works: |
| 10 | ```bash |
| 11 | xcrun notarytool history --keychain-profile "AC_PASSWORD" >/dev/null 2>&1 |
| 12 | ``` |
| 13 | If it fails, stop and tell the user to run: |
| 14 | ```bash |
| 15 | xcrun notarytool store-credentials "AC_PASSWORD" --apple-id "<APPLE_ID>" --team-id "<TEAM_ID>" --password "<app-specific-password>" |
| 16 | ``` |
| 17 | 3. Confirm the working tree is clean (`git status --porcelain`). If there are uncommitted changes, stop and tell the user to commit or stash first. |
| 18 | 4. Confirm you are on the `main` branch. If not, stop and tell the user to switch to `main` first. |
| 19 | |
| 20 | ### Step 2: Determine the next version |
| 21 | |
| 22 | 1. Get the latest tag: |
| 23 | ```bash |
| 24 | git tag -l 'v*' | sort -V | tail -1 |
| 25 | ``` |
| 26 | 2. Get commits since that tag: |
| 27 | ```bash |
| 28 | git log <latest_tag>..HEAD --oneline --format='%s' |
| 29 | ``` |
| 30 | 3. If there are zero commits since the last tag, stop and tell the user there is nothing to release. |
| 31 | 4. Apply semver logic to the current latest version: |
| 32 | - If any commit message starts with `feat:` or `feat(` → **minor** bump (e.g. 1.1.0 → 1.2.0) |
| 33 | - If all commits are `fix:`, `chore:`, `docs:`, or similar → **patch** bump (e.g. 1.1.0 → 1.1.1) |
| 34 | - If any commit contains `BREAKING CHANGE` or uses a `!:` suffix → ask the user what version to use |
| 35 | - If the commit messages are ambiguous or do not follow conventional commits, use `mcp__conductor__AskUserQuestion` to ask: |
| 36 | - question: "Commits since the last release don't clearly indicate the version bump. What version should this release be?" |
| 37 | - header: "Release version" |
| 38 | - multiSelect: false |
| 39 | - options with labels: "Patch (X.Y.Z+1)", "Minor (X.Y+1.0)", "Major (X+1.0.0)", "Custom" |
| 40 | |
| 41 | ### Step 3: Confirm the version |
| 42 | |
| 43 | Always confirm the version before proceeding. Use `mcp__conductor__AskUserQuestion`: |
| 44 | - question: "Release as v<VERSION>? Commits included:\n<commit list>" |
| 45 | - header: "Confirm release" |
| 46 | - multiSelect: false |
| 47 | - options: |
| 48 | - "Yes, release v<VERSION>" |
| 49 | - "Use a different version" |
| 50 | - "Cancel" |
| 51 | |
| 52 | If the user picks "Use a different version", ask them for the version number. If they pick "Cancel", stop. |
| 53 | |
| 54 | ### Step 3.5: Update CHANGELOG.md |
| 55 | |
| 56 | 1. Check if `CHANGELOG.md` has an `## [Unreleased]` section with content (bullet points). |
| 57 | 2. If the `## [Unreleased]` section is empty or missing, draft entries from commits since the last tag: |
| 58 | - **Rewrite each entry to be user-facing.** Don't echo commit messages. Describe what changed from the user's perspective — what it enables, fixes, or improves. |
| 59 | - Bad: "feat: add skills registry browser with multi-agent install" |
| 60 | - Good: "Browse and install community skills directly from the app" |
| 61 | - Keep entries succinct (one line each). No technical jargon, no commit prefixes. |
| 62 | - Confirm the drafted entries with the user using `mcp__conductor__AskUserQuestion`. |
| 63 | 3. Rename `## [Unreleased]` to `## [VERSION] - YYYY-MM-DD` (today's date). |
| 64 | 4. Add a new empty `## [Unreleased]` section above it. |
| 65 | |
| 66 | ### Step 4: Update the marketing site version |
| 67 | |
| 68 | 1. Edit `site/src/pages/index.astro`. Find the line containing `class="requires"` and replace it with: |
| 69 | ```html |
| 70 | <p class="requires">v<VERSION> · Requires macOS Sequoia</p> |
| 71 | ``` |
| 72 | where `<VERSION>` is the confirmed version. |
| 73 | 2. Commit this change along with the changelog: |
| 74 | ```bash |
| 75 | git add site/src/pages/index.astro CHANGELOG.md |
| 76 | git commit -m "chore: update site version to v<VERSION>" |
| 77 | git push |
| 78 | ``` |
| 79 | |
| 80 | ### Step 5: Run the release script |
| 81 | |
| 82 | ```bash |
| 83 | ./scripts/release.sh <VERSION> |
| 84 | ``` |
| 85 | |
| 86 | This handles: xcodegen → archive → export → DMG → notarize → staple → git tag → appcast → push → GitHub Release. |
| 87 | |
| 88 | Let it run to completion. If it fails, report the error output to the user and stop. Do NOT retry automatically. |
| 89 | |
| 90 | ### Step 6: Push and report |
| 91 | |
| 92 | Ensure all commits are on the remote: |
| 93 | ```bash |
| 94 | git push |
| 95 | ``` |
| 96 | |
| 97 | Tell the user: |
| 98 | - The version that was released |
| 99 | - Link: `https://github.com/Shpigford/chops/releases/tag/v<VERSION>` |
| 100 | - Remind them to deploy the marketing site if needed (`npm run build` from `site/`) |
| 101 | |
| 102 | ## Important Rules |
| 103 | |
| 104 | - ALWAYS confirm the version with the user before proceeding |
| 105 | - NEVER run the release script if `.env` is missing or the working tree is dirty |
| 106 | - NEVER skip the marketing site version update |
| 107 | - If the release script fails, do NOT retry — report the error and stop |
| 108 | - The release script handles git tagging and GitHub release creation — do not duplicate those steps |