$npx -y skills add zakelfassi/skills-driven-development --skill release-cutCut a versioned release for shipctl — bump the version, generate a changelog from conventional commits, create and push the git tag, and draft a GitHub release with cross-compiled binaries attached. Use when preparing a new release, when asked to "cut a release", or when the vers
| 1 | # Release Cut |
| 2 | |
| 3 | Bump the version, generate a changelog, tag, and publish a GitHub release for `shipctl`. |
| 4 | |
| 5 | ## Inputs |
| 6 | - Target version (semver, e.g. `1.2.0` or `patch`/`minor`/`major`) |
| 7 | - Release channel (defaults to `stable`; `pre` for release candidates) |
| 8 | - Skip binary attach? (boolean, defaults to `false`) |
| 9 | |
| 10 | ## Steps |
| 11 | |
| 12 | 1. **Verify the working tree is clean** |
| 13 | ```bash |
| 14 | git status --porcelain |
| 15 | ``` |
| 16 | If dirty, commit or stash before proceeding. |
| 17 | |
| 18 | 2. **Run the full test suite** |
| 19 | ```bash |
| 20 | cargo test --workspace |
| 21 | ``` |
| 22 | Abort if any test fails. |
| 23 | |
| 24 | 3. **Run the breaking-change audit** (invoke the `breaking-change-audit` skill) |
| 25 | Confirms no accidental public-interface regressions before tagging. |
| 26 | |
| 27 | 4. **Bump the version** |
| 28 | ```bash |
| 29 | # For Rust: |
| 30 | cargo set-version {version} # or edit Cargo.toml manually |
| 31 | # For Go: |
| 32 | # Update version constant in cmd/root.go |
| 33 | ``` |
| 34 | Commit the version bump: |
| 35 | ```bash |
| 36 | git commit -am "chore(release): bump version to {version}" |
| 37 | ``` |
| 38 | |
| 39 | 5. **Generate the changelog** |
| 40 | ```bash |
| 41 | scripts/release-cut.sh --changelog-only {version} |
| 42 | ``` |
| 43 | Review `CHANGELOG.md` — edit entries if the generated text is unclear. |
| 44 | Commit: `git commit -am "docs(changelog): {version} release notes"` |
| 45 | |
| 46 | 6. **Create and push the tag** |
| 47 | ```bash |
| 48 | git tag -a "v{version}" -m "Release v{version}" |
| 49 | git push origin "v{version}" |
| 50 | ``` |
| 51 | |
| 52 | 7. **Trigger cross-compile and attach binaries** |
| 53 | The CI matrix builds all registered target triples (see `cross-compile-matrix` skill). |
| 54 | Wait for the `release` workflow to complete: |
| 55 | ```bash |
| 56 | gh run watch --exit-status |
| 57 | ``` |
| 58 | |
| 59 | 8. **Draft the GitHub release** |
| 60 | ```bash |
| 61 | gh release create "v{version}" \ |
| 62 | --title "v{version}" \ |
| 63 | --notes-file CHANGELOG.md \ |
| 64 | --draft |
| 65 | ``` |
| 66 | Review the draft, then publish: |
| 67 | ```bash |
| 68 | gh release edit "v{version}" --draft=false |
| 69 | ``` |
| 70 | |
| 71 | 9. **Announce** (if applicable) |
| 72 | Post in the team channel: title, key changes, install command: |
| 73 | ``` |
| 74 | cargo install shipctl --version {version} |
| 75 | ``` |
| 76 | |
| 77 | ## Conventions |
| 78 | - Version tags always use the `v` prefix: `v1.2.0`, not `1.2.0` |
| 79 | - Changelog entries follow the Keep a Changelog format (Added / Changed / Deprecated / Removed / Fixed / Security) |
| 80 | - Release candidates are tagged `v1.2.0-rc.1` |
| 81 | - Binary naming: `shipctl-{version}-{target}.tar.gz` |
| 82 | - Dry-run: `scripts/release-cut.sh --dry-run {version}` prints the plan without side effects |
| 83 | |
| 84 | ## Edge Cases |
| 85 | - **Tag already exists:** Delete the local tag, investigate what was released, never force-push a tag that CI has already processed. |
| 86 | - **Changelog is empty:** Check that commits follow conventional format (`feat:`, `fix:`, etc.); if the log is legitimately empty, write a manual entry. |
| 87 | - **Binary attach fails:** Re-run `gh release upload "v{version}" dist/*.tar.gz`; check that the CI artifact paths match what the release workflow uploads. |
| 88 | - **Yanked release:** Use `gh release delete "v{version}"` + `git push origin --delete "v{version}"`; never publish a replacement under the same tag. |