File tree Expand file tree Collapse file tree 3 files changed +86
-0
lines changed
Expand file tree Collapse file tree 3 files changed +86
-0
lines changed Original file line number Diff line number Diff line change 1+ name : Release
2+
3+ on :
4+ push :
5+ tags :
6+ - " v*.*.*"
7+
8+ permissions :
9+ contents : write
10+
11+ jobs :
12+ release :
13+ runs-on : ubuntu-latest
14+ steps :
15+ - name : Checkout
16+ uses : actions/checkout@v4
17+
18+ - name : Create GitHub Release
19+ uses : softprops/action-gh-release@v2
20+ with :
21+ tag_name : ${{ github.ref_name }}
22+ generate_release_notes : true
Original file line number Diff line number Diff line change @@ -65,6 +65,19 @@ not just this one. Every change we make must account for the experience of those
6565- ** Discuss trade-offs** : if a feature requires consumers to make non-trivial changes (new secrets,
6666 new workflow jobs, new permissions), flag it in the PR for a deliberate decision.
6767
68+ ## Versioning & Releases
69+
70+ We use semver tags (` v1.0.0 ` ) alongside a floating major tag (` v1 ` ) — consumers pin to ` @v1 ` .
71+ Only bump the major version for breaking changes (e.g. removed/renamed inputs, new required secrets).
72+
73+ To release:
74+
75+ ``` bash
76+ ./scripts/release.sh 1.0.0
77+ ```
78+
79+ Always use the script — it handles both tags atomically. Never tag manually.
80+
6881## Branching Convention
6982
7083- Features: ` feat/<name> `
Original file line number Diff line number Diff line change 1+ #! /usr/bin/env bash
2+ set -euo pipefail
3+
4+ if [ $# -ne 1 ]; then
5+ echo " Usage: $0 <version>"
6+ echo " Example: $0 1.0.0"
7+ exit 1
8+ fi
9+
10+ VERSION=" $1 "
11+
12+ # Strip leading 'v' if provided
13+ VERSION=" ${VERSION# v} "
14+
15+ # Validate semver format
16+ if ! [[ " $VERSION " =~ ^[0-9]+\. [0-9]+\. [0-9]+$ ]]; then
17+ echo " Error: '$VERSION ' is not a valid semantic version (expected X.Y.Z)"
18+ exit 1
19+ fi
20+
21+ MAJOR=" ${VERSION%% .* } "
22+ TAG=" v${VERSION} "
23+ MAJOR_TAG=" v${MAJOR} "
24+
25+ # Ensure we're on a clean working tree
26+ if [ -n " $( git status --porcelain) " ]; then
27+ echo " Error: working tree is not clean. Commit or stash changes first."
28+ exit 1
29+ fi
30+
31+ # Create the immutable semver tag
32+ if git rev-parse " $TAG " > /dev/null 2>&1 ; then
33+ echo " Error: tag '$TAG ' already exists. Semver tags are immutable."
34+ exit 1
35+ fi
36+
37+ git tag " $TAG "
38+ echo " Created tag $TAG "
39+
40+ # Force-move the floating major tag
41+ git tag -f " $MAJOR_TAG "
42+ echo " Moved tag $MAJOR_TAG -> $( git rev-parse --short HEAD) "
43+
44+ # Push both tags
45+ git push origin " $TAG "
46+ git push origin " $MAJOR_TAG " --force
47+
48+ echo " "
49+ echo " Release complete:"
50+ echo " $TAG (immutable semver tag)"
51+ echo " $MAJOR_TAG (floating major tag, force-updated)"
You can’t perform that action at this time.
0 commit comments