From e1715143add2d440100eaac2247f55471a23bc32 Mon Sep 17 00:00:00 2001 From: mikkeldamsgaard Date: Thu, 12 Mar 2026 00:03:08 +0100 Subject: [PATCH] chore: add release automation and /release skill - Auto-tag workflow: detects Cargo.toml version bump on main push, creates git tag automatically, which triggers the release workflow. - /release Claude Code skill: guided release preparation with semver determination, user confirmation, and PR creation. Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 41 ++++++++++++++++++++++++++++++++++ .github/workflows/auto-tag.yml | 40 +++++++++++++++++++++++++++++++++ CHANGELOG.md | 4 ++++ 3 files changed, 85 insertions(+) create mode 100644 .claude/commands/release.md create mode 100644 .github/workflows/auto-tag.yml diff --git a/.claude/commands/release.md b/.claude/commands/release.md new file mode 100644 index 0000000..f636752 --- /dev/null +++ b/.claude/commands/release.md @@ -0,0 +1,41 @@ +# Release + +Prepare a release PR for initium. This command handles version bumping, changelog updates, and PR creation. The release is published automatically when the PR merges (CI detects the version bump and creates the tag, which triggers the release workflow). + +## Determine the next version number + +Follow semantic versioning (MAJOR.MINOR.PATCH): + +1. Read `CHANGELOG.md` under `## [Unreleased]` to see what has changed since the last release. +2. Read recent commits since the last tag: `git log $(git describe --tags --abbrev=0)..HEAD --oneline` +3. Determine the version bump: + - **PATCH** (x.y.Z): Only bug fixes, documentation, or internal changes with no user-facing behavior change. + - **MINOR** (x.Y.0): New features, new CLI flags, new configuration options, or backward-compatible enhancements. + - **MAJOR** (X.0.0): Breaking changes — removed features, changed defaults, incompatible schema/config changes, or renamed CLI flags. +4. Read the current version from `Cargo.toml` and compute the next version. + +## Confirmation phase + +Before making any changes, present to the user: +- The **current version** and the **proposed next version** with reasoning. +- A **summary of changes** that will go into the release (from Unreleased changelog + commit log). +- Ask: "Proceed with version X.Y.Z?" and wait for confirmation. +- If the user suggests a different version, use that instead. + +## Execute the release + +Once confirmed: + +1. Fetch origin and create a branch: `release/vX.Y.Z` from `origin/main`. +2. Bump version in `Cargo.toml` (the `version = "..."` field under `[package]`). +3. Run `cargo check` to update `Cargo.lock`. +4. Update `CHANGELOG.md`: + - Move everything under `## [Unreleased]` into a new `## [X.Y.Z] - YYYY-MM-DD` section (use today's date). + - Leave `## [Unreleased]` empty (with just the heading). +5. Run `cargo test` to verify nothing is broken. +6. Run `cargo clippy -- -D warnings` and `cargo fmt -- --check`. +7. Commit: `release: vX.Y.Z` +8. Push the branch and create a PR with title `release: vX.Y.Z`. +9. The PR body should include the changelog entries for this version. + +When the PR merges, the auto-tag workflow detects the version bump in `Cargo.toml` and creates the `vX.Y.Z` tag, which triggers the release workflow (Docker build + crates.io publish). diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml new file mode 100644 index 0000000..258978a --- /dev/null +++ b/.github/workflows/auto-tag.yml @@ -0,0 +1,40 @@ +name: Auto Tag +on: + push: + branches: [main] + paths: + - Cargo.toml +permissions: + contents: write +jobs: + tag: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Check for version bump + id: version + run: | + CURRENT=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/') + PREVIOUS=$(git show HEAD~1:Cargo.toml | grep '^version' | head -1 | sed 's/.*"\(.*\)"/\1/') + echo "current=$CURRENT" >> "$GITHUB_OUTPUT" + echo "previous=$PREVIOUS" >> "$GITHUB_OUTPUT" + if [ "$CURRENT" != "$PREVIOUS" ]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + else + echo "changed=false" >> "$GITHUB_OUTPUT" + fi + - name: Create and push tag + if: steps.version.outputs.changed == 'true' + run: | + VERSION="${{ steps.version.outputs.current }}" + TAG="v${VERSION}" + if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists, skipping" + exit 0 + fi + git tag "$TAG" + git push origin "$TAG" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 17c77ec..cf72282 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Auto-tag workflow: CI automatically creates a git tag when `Cargo.toml` version changes on main, triggering the release workflow. +- `/release` skill for Claude Code: guided release preparation with version determination, confirmation, and PR creation. + ## [1.2.0] - 2026-03-11 ### Added