From 37bbd639a41286a9894fed291e6aa0b4300b6a16 Mon Sep 17 00:00:00 2001 From: mikkeldamsgaard Date: Thu, 12 Mar 2026 00:18:11 +0100 Subject: [PATCH] chore: add release automation and /release skill - Auto-tag workflow: detects Cargo.toml version bump on main push, creates and pushes git tag to trigger the release workflow. Uses github.event.before for reliable diff, guards against null SHA on first push, and checks remote tags before creating. - /release Claude Code skill: guided release preparation with semver determination, confirmation phase, and PR creation. - CHANGELOG updated with new automation entries. Co-Authored-By: Claude Opus 4.6 --- .claude/commands/release.md | 2 +- .github/workflows/auto-tag.yml | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index f636752..e40f975 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -28,7 +28,7 @@ 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`. +3. Run `cargo check` to ensure the project builds successfully after the version bump. 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). diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml index 258978a..646fde9 100644 --- a/.github/workflows/auto-tag.yml +++ b/.github/workflows/auto-tag.yml @@ -12,12 +12,16 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 2 + fetch-depth: 0 - 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/') + if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then + PREVIOUS="$CURRENT" + else + PREVIOUS=$(git show ${{ github.event.before }}:Cargo.toml | grep '^version' | head -1 | sed 's/.*"\(.*\)"/\1/') + fi echo "current=$CURRENT" >> "$GITHUB_OUTPUT" echo "previous=$PREVIOUS" >> "$GITHUB_OUTPUT" if [ "$CURRENT" != "$PREVIOUS" ]; then @@ -30,11 +34,22 @@ jobs: run: | VERSION="${{ steps.version.outputs.current }}" TAG="v${VERSION}" + if git ls-remote --tags origin "refs/tags/$TAG" | grep -q .; then + echo "Tag $TAG already exists on origin, skipping" + exit 0 + fi if git rev-parse "$TAG" >/dev/null 2>&1; then - echo "Tag $TAG already exists, skipping" + echo "Tag $TAG already exists locally, skipping" exit 0 fi git tag "$TAG" - git push origin "$TAG" + if ! git push origin "$TAG"; then + if git ls-remote --tags origin "refs/tags/$TAG" | grep -q .; then + echo "Tag $TAG was created concurrently on origin, skipping" + exit 0 + fi + echo "Failed to push tag $TAG" + exit 1 + fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}