Release Cut
Bump the version, generate a changelog, tag, and publish a GitHub release for shipctl.
Inputs
- Target version (semver, e.g.
1.2.0orpatch/minor/major) - Release channel (defaults to
stable;prefor release candidates) - Skip binary attach? (boolean, defaults to
false)
Steps
Verify the working tree is clean
git status --porcelainIf dirty, commit or stash before proceeding.
Run the full test suite
cargo test --workspaceAbort if any test fails.
Run the breaking-change audit (invoke the
breaking-change-auditskill) Confirms no accidental public-interface regressions before tagging.Bump the version
# For Rust: cargo set-version {version} # or edit Cargo.toml manually # For Go: # Update version constant in cmd/root.goCommit the version bump:
git commit -am "chore(release): bump version to {version}"Generate the changelog
scripts/release-cut.sh --changelog-only {version}Review
CHANGELOG.md— edit entries if the generated text is unclear. Commit:git commit -am "docs(changelog): {version} release notes"Create and push the tag
git tag -a "v{version}" -m "Release v{version}" git push origin "v{version}"Trigger cross-compile and attach binaries The CI matrix builds all registered target triples (see
cross-compile-matrixskill). Wait for thereleaseworkflow to complete:gh run watch --exit-statusDraft the GitHub release
gh release create "v{version}" \ --title "v{version}" \ --notes-file CHANGELOG.md \ --draftReview the draft, then publish:
gh release edit "v{version}" --draft=falseAnnounce (if applicable) Post in the team channel: title, key changes, install command:
cargo install shipctl --version {version}
Conventions
- Version tags always use the
vprefix:v1.2.0, not1.2.0 - Changelog entries follow the Keep a Changelog format (Added / Changed / Deprecated / Removed / Fixed / Security)
- Release candidates are tagged
v1.2.0-rc.1 - Binary naming:
shipctl-{version}-{target}.tar.gz - Dry-run:
scripts/release-cut.sh --dry-run {version}prints the plan without side effects
Edge Cases
- Tag already exists: Delete the local tag, investigate what was released, never force-push a tag that CI has already processed.
- Changelog is empty: Check that commits follow conventional format (
feat:,fix:, etc.); if the log is legitimately empty, write a manual entry. - 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. - Yanked release: Use
gh release delete "v{version}"+git push origin --delete "v{version}"; never publish a replacement under the same tag.