name: Release post-merge # On every push to main: if the catalog version changed, tag main HEAD as # vX.Y.Z. The catalog version is metadata.version in # .github/plugin/marketplace.json (the Catalog check keeps the Claude catalog # in sync). Pushes that don't change it are skipped. on: push: branches: [main] permissions: contents: write # push tags # Serialize tag-creation across overlapping pushes to main so two workflow runs # can't race on the same tag. concurrency: group: release-post-merge-${{ github.ref }} cancel-in-progress: false jobs: auto-tag: name: Tag main HEAD as vX.Y.Z runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Read catalog version id: ver env: BEFORE: ${{ github.event.before }} shell: bash run: | set -euo pipefail CATALOG=.github/plugin/marketplace.json VERSION=$(jq -r '.metadata.version' "$CATALOG") if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "::error::$CATALOG metadata.version '$VERSION' is not valid semver. Refusing to tag." exit 1 fi PREVIOUS="" if [[ -n "$BEFORE" && ! "$BEFORE" =~ ^0+$ ]] && git cat-file -e "$BEFORE:$CATALOG" 2>/dev/null; then PREVIOUS=$(git show "$BEFORE:$CATALOG" | jq -r '.metadata.version // empty') elif git cat-file -e "HEAD^1:$CATALOG" 2>/dev/null; then PREVIOUS=$(git show "HEAD^1:$CATALOG" | jq -r '.metadata.version // empty') fi if [[ "$PREVIOUS" == "$VERSION" ]]; then echo "::notice::Catalog version unchanged ($VERSION) — no tag." echo "tag=" >> "$GITHUB_OUTPUT" exit 0 fi echo "tag=v$VERSION" >> "$GITHUB_OUTPUT" - name: Create and push tag (idempotent, SHA-checked) if: steps.ver.outputs.tag != '' env: TAG: ${{ steps.ver.outputs.tag }} shell: bash run: | set -euo pipefail git fetch --tags origin --quiet # Same SHA = idempotent success. A tag on an earlier main commit (e.g. # after reverting a bump) is left alone. Anything else fails loudly; # never overwrite or accept a misplaced tag. if git rev-parse --verify --quiet "refs/tags/$TAG^{}" >/dev/null; then EXISTING_SHA=$(git rev-parse "refs/tags/$TAG^{}") if [[ "$EXISTING_SHA" == "$GITHUB_SHA" ]]; then echo "::notice::Tag $TAG already points at $GITHUB_SHA — nothing to do." exit 0 fi if git merge-base --is-ancestor "$EXISTING_SHA" "$GITHUB_SHA"; then echo "::notice::Tag $TAG already exists at earlier commit $EXISTING_SHA — not moving it." exit 0 fi echo "::error::Tag $TAG already exists at $EXISTING_SHA but main HEAD is $GITHUB_SHA. Bump the catalog version instead of reusing one." exit 1 fi git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git tag -a "$TAG" -m "Release $TAG" git push origin "$TAG" echo "::notice::Tagged $GITHUB_SHA as $TAG."