Skip to content

Commit b36c0ab

Browse files
feat(ci): add label-driven auto-tag workflow for releases
Adds `.github/workflows/auto-tag.yml` — a second entry point into release.yml that fires when a PR is merged with a release label. Flow: 1. Engineer opens a PR, adds `release:patch` / `release:minor` / `release:major` label. 2. Merge PR to main. 3. auto-tag.yml: - Reads PROJECT_VERSION from VERSIONS - Bumps per the label (patch: x.y.Z+1, minor: x.Y+1.0, major: X+1.0.0) - Runs sync-versions.sh to propagate across all manifests - Commits to main + pushes the new v<version> tag - Comments on the PR with a link to the triggered release 4. Tag push triggers release.yml → builds everything → draft GH Release. The existing manual flow (engineer runs sync-versions.sh + tags + pushes) still works — label-driven is an additive convenience. Also created 3 repo labels: release:patch (green) release:minor (yellow) release:major (red) No-op if a PR merges without any release label — merges without labels just land on main as normal. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0e134c6 commit b36c0ab

1 file changed

Lines changed: 152 additions & 0 deletions

File tree

.github/workflows/auto-tag.yml

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
name: Auto-Tag Release
2+
3+
# =============================================================================
4+
# Label-driven release triggering.
5+
#
6+
# When a PR is merged to main with one of these labels:
7+
# release:patch — v0.19.7 → v0.19.8
8+
# release:minor — v0.19.7 → v0.20.0
9+
# release:major — v0.19.7 → v1.0.0
10+
#
11+
# this workflow:
12+
# 1. Determines the current PROJECT_VERSION from sdk/runanywhere-commons/VERSIONS
13+
# 2. Bumps it according to the label
14+
# 3. Runs scripts/sync-versions.sh to propagate the new version across all manifests
15+
# 4. Commits the bump to main and pushes tag v{new-version}
16+
# 5. The tag push then triggers release.yml → builds everything → draft GH Release
17+
#
18+
# If no release label is present, the workflow is a no-op. Merges without a label
19+
# just land the code on main as normal — releases are explicit opt-in.
20+
#
21+
# Alternative (manual): engineer can still run this flow manually:
22+
# scripts/sync-versions.sh 0.20.0
23+
# git tag v0.20.0 && git push origin v0.20.0
24+
# Both paths converge on release.yml.
25+
# =============================================================================
26+
27+
on:
28+
pull_request:
29+
types: [closed]
30+
branches: [main]
31+
32+
permissions:
33+
contents: write # needed to commit version bump + push tag
34+
35+
jobs:
36+
auto-tag:
37+
if: github.event.pull_request.merged == true
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Detect release label on merged PR
41+
id: label
42+
env:
43+
PR_LABELS: ${{ toJson(github.event.pull_request.labels) }}
44+
run: |
45+
set -euo pipefail
46+
# Extract just the label names
47+
NAMES=$(echo "$PR_LABELS" | jq -r '.[].name')
48+
echo "PR labels: $NAMES"
49+
50+
BUMP=""
51+
for name in $NAMES; do
52+
case "$name" in
53+
release:patch) BUMP="patch" ;;
54+
release:minor) BUMP="minor" ;;
55+
release:major) BUMP="major" ;;
56+
esac
57+
done
58+
59+
if [ -z "$BUMP" ]; then
60+
echo "No release:* label — nothing to do."
61+
echo "should-release=false" >> "$GITHUB_OUTPUT"
62+
else
63+
echo "Release label found: release:$BUMP"
64+
echo "should-release=true" >> "$GITHUB_OUTPUT"
65+
echo "bump=$BUMP" >> "$GITHUB_OUTPUT"
66+
fi
67+
68+
- name: Checkout main
69+
if: steps.label.outputs.should-release == 'true'
70+
uses: actions/checkout@v4
71+
with:
72+
ref: main
73+
fetch-depth: 0
74+
token: ${{ secrets.GITHUB_TOKEN }}
75+
76+
- name: Compute next version
77+
if: steps.label.outputs.should-release == 'true'
78+
id: version
79+
env:
80+
BUMP: ${{ steps.label.outputs.bump }}
81+
run: |
82+
set -euo pipefail
83+
CURRENT=$(grep -E '^PROJECT_VERSION=' sdk/runanywhere-commons/VERSIONS | cut -d= -f2 | xargs)
84+
# Strip any pre-release suffix for bumping
85+
BASE="${CURRENT%%-*}"
86+
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
87+
88+
case "$BUMP" in
89+
patch) PATCH=$((PATCH + 1)) ;;
90+
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
91+
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
92+
esac
93+
94+
NEW="${MAJOR}.${MINOR}.${PATCH}"
95+
echo "Current: $CURRENT"
96+
echo "Bump: $BUMP"
97+
echo "New: $NEW"
98+
echo "new-version=$NEW" >> "$GITHUB_OUTPUT"
99+
100+
- name: Sanity-check tag doesn't already exist
101+
if: steps.label.outputs.should-release == 'true'
102+
env:
103+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
104+
run: |
105+
set -euo pipefail
106+
if git rev-parse "v${NEW_VERSION}" >/dev/null 2>&1; then
107+
echo "::error::Tag v${NEW_VERSION} already exists."
108+
exit 1
109+
fi
110+
111+
- name: Run sync-versions.sh
112+
if: steps.label.outputs.should-release == 'true'
113+
env:
114+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
115+
run: |
116+
set -euo pipefail
117+
chmod +x scripts/sync-versions.sh
118+
./scripts/sync-versions.sh "${NEW_VERSION}"
119+
120+
- name: Configure git identity
121+
if: steps.label.outputs.should-release == 'true'
122+
run: |
123+
git config user.name "github-actions[bot]"
124+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
125+
126+
- name: Commit version bump + push tag
127+
if: steps.label.outputs.should-release == 'true'
128+
env:
129+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
130+
BUMP: ${{ steps.label.outputs.bump }}
131+
PR_NUMBER: ${{ github.event.pull_request.number }}
132+
run: |
133+
set -euo pipefail
134+
git add -u
135+
if git diff --cached --quiet; then
136+
echo "No manifest changes from sync-versions.sh — unexpected; aborting"
137+
exit 1
138+
fi
139+
git commit -m "chore: release v${NEW_VERSION} (${BUMP} bump from PR #${PR_NUMBER})"
140+
git tag "v${NEW_VERSION}"
141+
git push origin main
142+
git push origin "v${NEW_VERSION}"
143+
echo "::notice::Pushed tag v${NEW_VERSION} — release.yml will now build and create a draft release"
144+
145+
- name: Comment on merged PR
146+
if: steps.label.outputs.should-release == 'true'
147+
env:
148+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
149+
PR_NUMBER: ${{ github.event.pull_request.number }}
150+
NEW_VERSION: ${{ steps.version.outputs.new-version }}
151+
run: |
152+
gh pr comment "$PR_NUMBER" --repo "${{ github.repository }}" --body "🚀 Auto-tagged **v${NEW_VERSION}** — release.yml is now building artifacts. The GitHub Release will be created as a draft; publish it after reviewing the assets."

0 commit comments

Comments
 (0)