Skip to content

Commit 5f830da

Browse files
adding release automation
1 parent 4607763 commit 5f830da

2 files changed

Lines changed: 148 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Require release label for main PRs
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- reopened
8+
- synchronize
9+
- labeled
10+
- unlabeled
11+
branches:
12+
- main
13+
14+
permissions:
15+
pull-requests: read
16+
17+
jobs:
18+
require-release-label:
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Check for release label
23+
uses: actions/github-script@v7
24+
with:
25+
script: |
26+
const labels = context.payload.pull_request.labels.map(l => l.name);
27+
28+
const allowed = [
29+
'release:patch',
30+
'release:minor',
31+
'release:major',
32+
'release:none'
33+
];
34+
35+
const found = labels.filter(l => allowed.includes(l));
36+
37+
if (found.length === 0) {
38+
core.setFailed(
39+
"Missing release label. Add one of: " +
40+
"release:patch | release:minor | release:major | release:none"
41+
);
42+
}
43+
44+
if (found.length > 1) {
45+
core.setFailed(
46+
"Multiple release labels found. Exactly one is required."
47+
);
48+
}
49+
50+
console.log(`Release label OK: ${found[0]}`);

.github/workflows/release.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Release a New Verison
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
branches:
7+
- main
8+
9+
permissions:
10+
contents: write
11+
pull-requests: read
12+
13+
jobs:
14+
release:
15+
if: github.event.pull_request.merged == true
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Get release label
25+
id: label
26+
run: |
27+
labels='${{ toJson(github.event.pull_request.labels) }}'
28+
29+
if echo "$labels" | grep -q 'release:major'; then
30+
echo "bump=major" >> $GITHUB_OUTPUT
31+
elif echo "$labels" | grep -q 'release:minor'; then
32+
echo "bump=minor" >> $GITHUB_OUTPUT
33+
elif echo "$labels" | grep -q 'release:patch'; then
34+
echo "bump=patch" >> $GITHUB_OUTPUT
35+
elif echo "$labels" | grep -q 'release:none'; then
36+
echo "bump=none" >> $GITHUB_OUTPUT
37+
else
38+
echo "No release label found. Add one of:"
39+
echo "release:patch | release:minor | release:major | release:none"
40+
exit 1
41+
fi
42+
43+
- name: Exit if no release needed
44+
if: steps.label.outputs.bump == 'none'
45+
run: |
46+
echo "No release requested. Exiting."
47+
exit 0
48+
49+
- name: Get latest version tag
50+
id: version
51+
run: |
52+
latest=$(git tag --list 'v*' --sort=-v:refname | head -n 1)
53+
echo "latest=$latest" >> $GITHUB_OUTPUT
54+
55+
- name: Calculate next version
56+
id: next
57+
run: |
58+
version=${{ steps.version.outputs.latest }}
59+
bump=${{ steps.label.outputs.bump }}
60+
61+
version=${version#v}
62+
IFS='.' read -r major minor patch <<< "$version"
63+
64+
case "$bump" in
65+
major)
66+
major=$((major+1))
67+
minor=0
68+
patch=0
69+
;;
70+
minor)
71+
minor=$((minor+1))
72+
patch=0
73+
;;
74+
patch)
75+
patch=$((patch+1))
76+
;;
77+
esac
78+
79+
next="v$major.$minor.$patch"
80+
echo "next=$next" >> $GITHUB_OUTPUT
81+
82+
- name: Create version tag
83+
run: |
84+
git tag ${{ steps.next.outputs.next }}
85+
git push origin ${{ steps.next.outputs.next }}
86+
87+
- name: Update moving major tag (v1)
88+
run: |
89+
major=$(echo "${{ steps.next.outputs.next }}" | cut -d. -f1)
90+
git tag -f $major
91+
git push origin $major --force
92+
93+
- name: Create GitHub Release
94+
uses: softprops/action-gh-release@v1
95+
with:
96+
tag_name: ${{ steps.next.outputs.next }}
97+
name: Release ${{ steps.next.outputs.next }}
98+
generate_release_notes: true

0 commit comments

Comments
 (0)