From a48d3d215834ea2edcbd850f53d2ed6e1d28b6c7 Mon Sep 17 00:00:00 2001 From: milstan Date: Tue, 21 Apr 2026 15:40:10 -0700 Subject: [PATCH] ci(release): auto-push version tag on merge to main Removes the manual `git tag mcp-v && git push` step that was getting forgotten between the version-bump PR landing and the actual npm publish (0.2.2 sat on main for hours before someone noticed). How: new `auto-tag.yml` triggers on push to main when either `packages/mcp/package.json` or `packages/leadclaw/package.json` changes, reads the version, and pushes `-v` if that tag doesn't already exist. Existing `release.yml` then fires on the tag push (unchanged). Idempotent: re-runs on the same version no-op. Updated `release.yml` header comment so the runbook reflects automatic tagging rather than the old manual `git tag` recipe. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/auto-tag.yml | 71 ++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 8 ++-- 2 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/auto-tag.yml diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml new file mode 100644 index 0000000..ba39a52 --- /dev/null +++ b/.github/workflows/auto-tag.yml @@ -0,0 +1,71 @@ +name: auto-tag + +# When a merge to main bumps a package version, push the corresponding release +# tag (mcp-v or leadclaw-v). The existing release.yml then fires on +# the tag and publishes to npm (and ClawHub for leadclaw). No manual `git tag` +# step. Idempotent: if the tag already exists, the job no-ops. + +on: + push: + branches: [main] + paths: + - "packages/mcp/package.json" + - "packages/leadclaw/package.json" + workflow_dispatch: + +permissions: + contents: write + +jobs: + tag: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - package: mcp + path: packages/mcp/package.json + tag_prefix: mcp-v + - package: leadclaw + path: packages/leadclaw/package.json + tag_prefix: leadclaw-v + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Read version + id: ver + run: | + set -euo pipefail + ver=$(node -p "require('./${{ matrix.path }}').version") + tag="${{ matrix.tag_prefix }}${ver}" + echo "tag=${tag}" >> "$GITHUB_OUTPUT" + echo "version=${ver}" >> "$GITHUB_OUTPUT" + echo "Resolved ${{ matrix.package }} version: ${ver} → tag ${tag}" + + - name: Skip if tag exists + id: check + run: | + set -euo pipefail + if git rev-parse --verify "refs/tags/${{ steps.ver.outputs.tag }}" >/dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "Tag ${{ steps.ver.outputs.tag }} already exists locally." + elif git ls-remote --exit-code --tags origin "refs/tags/${{ steps.ver.outputs.tag }}" >/dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "Tag ${{ steps.ver.outputs.tag }} already exists on origin." + else + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Push tag + if: steps.check.outputs.exists == 'false' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git tag "${{ steps.ver.outputs.tag }}" "${{ github.sha }}" + git push origin "${{ steps.ver.outputs.tag }}" + echo "Pushed ${{ steps.ver.outputs.tag }} → release.yml will publish." diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1707bf0..67aed90 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,10 +12,10 @@ name: release # - CLAWHUB_TOKEN → ClawHub publish token with rights to @leadbay/leadclaw # # No auto-version-bump, no auto-changelog. Bump `package.json` (and -# `openclaw.plugin.json` for leadclaw) in a normal PR, then tag the merge commit: -# -# git tag mcp-v0.3.0 && git push origin mcp-v0.3.0 -# git tag leadclaw-v0.3.0 && git push origin leadclaw-v0.3.0 +# `openclaw.plugin.json` for leadclaw) in a normal PR. Tagging is automatic: +# `auto-tag.yml` watches main, sees the bumped version, and pushes the +# corresponding tag, which triggers this workflow. Manual `git tag` is only +# needed for emergency re-publish of a version already on main. on: push: