1+ name : Release Gate
2+
3+ on :
4+ pull_request :
5+ types : [closed]
6+ branches : [main]
7+
8+ jobs :
9+ release-gate :
10+ name : Tag and update release branches
11+ runs-on : ubuntu-latest
12+ # Only run when a release/ branch is merged (not just closed)
13+ if : |
14+ github.event.pull_request.merged == true &&
15+ startsWith(github.event.pull_request.head.ref, 'release/v')
16+
17+ permissions :
18+ contents : write
19+
20+ steps :
21+ - uses : actions/create-github-app-token@v1
22+ id : app-token
23+ with :
24+ app-id : ${{ secrets.APP_ID }}
25+ private-key : ${{ secrets.APP_PRIVATE_KEY }}
26+
27+ - uses : actions/checkout@v4
28+ with :
29+ # Full history required for version comparison against existing tags
30+ # and for the fast-forward push to stable/beta.
31+ fetch-depth : 0
32+ token : ${{ steps.app-token.outputs.token }}
33+
34+ - name : Extract and validate version
35+ id : version
36+ env :
37+ BRANCH_REF : ${{ github.event.pull_request.head.ref }}
38+ run : |
39+ BRANCH="$BRANCH_REF"
40+ NEW_VERSION="${BRANCH#release/}"
41+ echo "new=${NEW_VERSION}" >> $GITHUB_OUTPUT
42+
43+ # Determine if this is an RC
44+ if echo "$NEW_VERSION" | grep -qE '\-rc[0-9]+$'; then
45+ echo "is_rc=true" >> $GITHUB_OUTPUT
46+ else
47+ echo "is_rc=false" >> $GITHUB_OUTPUT
48+ fi
49+
50+ - name : Validate version is strictly increasing
51+ env :
52+ NEW_VERSION : ${{ steps.version.outputs.new }}
53+ run : |
54+ # Get the latest tag; if none exist yet, skip the comparison
55+ LATEST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -n1)
56+ if [ -z "$LATEST_TAG" ]; then
57+ echo "No existing tags found — skipping version comparison"
58+ exit 0
59+ fi
60+
61+ LATEST_VERSION="${LATEST_TAG#v}"
62+
63+ python3 - <<EOF
64+ import sys
65+ from packaging.version import Version
66+
67+ def normalize(v):
68+ # Convert vX.Y.Z-rcQ → X.Y.ZrcQ (PEP 440)
69+ return v.replace("-rc", "rc")
70+
71+ new = Version(normalize("$NEW_VERSION"))
72+ latest = Version(normalize("$LATEST_VERSION"))
73+
74+ print(f"Latest tag : {latest}")
75+ print(f"New version: {new}")
76+
77+ if new <= latest:
78+ print(f"\n❌ {new} is not strictly greater than current {latest}")
79+ sys.exit(1)
80+
81+ print(f"\n✅ Version order is valid")
82+ EOF
83+
84+ - name : Configure git
85+ run : |
86+ git config user.name "commit-boost-release-bot[bot]"
87+ git config user.email "commit-boost-release-bot[bot]@users.noreply.github.com"
88+
89+ - name : Create and push tag
90+ env :
91+ VERSION : ${{ steps.version.outputs.new }}
92+ run : |
93+ git tag "$VERSION" HEAD
94+ git push origin "$VERSION"
95+ # Branch fast-forwarding happens in release.yml after all artifacts
96+ # are successfully built. stable/beta are never touched if the build fails.
0 commit comments