Skip to content

Commit 5669874

Browse files
claudensheaps
authored andcommitted
fix: auto-release on merge to main and add PR version comments
- Add auto-release.yml: runs release-it automatically when commits land on main (skips release commits to avoid loops) - Add pr-version-check.yml: comments on PRs with the expected version bump (major/minor/patch) or errors from conventional commit analysis - Update release-web/desktop/mobile workflows to also trigger on GitHub release published events, enabling the full CD pipeline: merge -> auto-release -> tag + GitHub release -> deploy workflows - Keep existing workflow_dispatch triggers for manual overrides https://claude.ai/code/session_01Mu841ZmkkUqmLw4wtPGhkT
1 parent 5c7461e commit 5669874

File tree

5 files changed

+204
-0
lines changed

5 files changed

+204
-0
lines changed

.github/workflows/auto-release.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Auto Release
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
10+
concurrency:
11+
group: release
12+
cancel-in-progress: false
13+
14+
jobs:
15+
release:
16+
name: Release
17+
runs-on: ubuntu-latest
18+
# Skip release commits to avoid infinite loops
19+
if: "!startsWith(github.event.head_commit.message, 'chore: release v')"
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Install mise
27+
uses: jdx/mise-action@v2
28+
29+
- name: Install dependencies
30+
run: bun install --frozen-lockfile
31+
32+
- name: Run quality gate
33+
run: bun run validate
34+
35+
- name: Determine version bump
36+
id: version
37+
run: |
38+
# Get the recommended bump from conventional commits
39+
NEXT_VERSION=$(bunx release-it --release-version --ci 2>/dev/null || echo "")
40+
if [ -z "$NEXT_VERSION" ]; then
41+
echo "No version bump detected from conventional commits"
42+
echo "skip=true" >> $GITHUB_OUTPUT
43+
else
44+
echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT
45+
echo "skip=false" >> $GITHUB_OUTPUT
46+
echo "Next version: $NEXT_VERSION"
47+
fi
48+
49+
- name: Configure git
50+
if: steps.version.outputs.skip != 'true'
51+
run: |
52+
git config user.name "github-actions[bot]"
53+
git config user.email "github-actions[bot]@users.noreply.github.com"
54+
55+
- name: Release
56+
if: steps.version.outputs.skip != 'true'
57+
run: bun run release:ci
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: PR Version Check
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
pull-requests: write
9+
contents: read
10+
11+
jobs:
12+
version-check:
13+
name: Check Version Bump
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Install mise
22+
uses: jdx/mise-action@v2
23+
24+
- name: Install dependencies
25+
run: bun install --frozen-lockfile
26+
27+
- name: Determine version bump
28+
id: version
29+
run: |
30+
set +e
31+
CURRENT_VERSION=$(node -p "require('./package.json').version")
32+
NEXT_VERSION=$(bunx release-it --release-version --ci 2>&1)
33+
EXIT_CODE=$?
34+
set -e
35+
36+
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
37+
38+
if [ $EXIT_CODE -ne 0 ] || [ -z "$NEXT_VERSION" ]; then
39+
echo "error=true" >> $GITHUB_OUTPUT
40+
echo "error_message<<EOF" >> $GITHUB_OUTPUT
41+
echo "$NEXT_VERSION" >> $GITHUB_OUTPUT
42+
echo "EOF" >> $GITHUB_OUTPUT
43+
else
44+
echo "error=false" >> $GITHUB_OUTPUT
45+
echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT
46+
47+
# Determine bump type by comparing versions
48+
CURRENT_MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
49+
CURRENT_MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)
50+
CURRENT_PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3)
51+
NEXT_MAJOR=$(echo "$NEXT_VERSION" | cut -d. -f1)
52+
NEXT_MINOR=$(echo "$NEXT_VERSION" | cut -d. -f2)
53+
NEXT_PATCH=$(echo "$NEXT_VERSION" | cut -d. -f3)
54+
55+
if [ "$NEXT_MAJOR" != "$CURRENT_MAJOR" ]; then
56+
echo "bump_type=major" >> $GITHUB_OUTPUT
57+
elif [ "$NEXT_MINOR" != "$CURRENT_MINOR" ]; then
58+
echo "bump_type=minor" >> $GITHUB_OUTPUT
59+
elif [ "$NEXT_PATCH" != "$CURRENT_PATCH" ]; then
60+
echo "bump_type=patch" >> $GITHUB_OUTPUT
61+
else
62+
echo "bump_type=none" >> $GITHUB_OUTPUT
63+
fi
64+
fi
65+
66+
- name: Comment on PR
67+
uses: actions/github-script@v7
68+
with:
69+
script: |
70+
const currentVersion = '${{ steps.version.outputs.current_version }}';
71+
const hasError = '${{ steps.version.outputs.error }}' === 'true';
72+
const nextVersion = '${{ steps.version.outputs.next_version }}';
73+
const bumpType = '${{ steps.version.outputs.bump_type }}';
74+
const errorMessage = `${{ steps.version.outputs.error_message }}`;
75+
76+
let body;
77+
if (hasError) {
78+
body = [
79+
'## Release Version Check',
80+
'',
81+
'> **Error determining version bump**',
82+
'',
83+
`Current version: \`${currentVersion}\``,
84+
'',
85+
'Error details:',
86+
'```',
87+
errorMessage,
88+
'```',
89+
'',
90+
'This PR may not trigger an automatic release when merged. Ensure commits follow [Conventional Commits](https://www.conventionalcommits.org/) format.',
91+
].join('\n');
92+
} else if (bumpType === 'none' || !nextVersion) {
93+
body = [
94+
'## Release Version Check',
95+
'',
96+
`> **No version bump detected**`,
97+
'',
98+
`Current version: \`${currentVersion}\``,
99+
'',
100+
'This PR will **not** trigger an automatic release when merged.',
101+
'To trigger a release, use [Conventional Commits](https://www.conventionalcommits.org/) prefixes like `feat:`, `fix:`, etc.',
102+
].join('\n');
103+
} else {
104+
const bumpEmoji = { major: '🔴', minor: '🟡', patch: '🟢' }[bumpType] || '📦';
105+
body = [
106+
'## Release Version Check',
107+
'',
108+
`> ${bumpEmoji} **${bumpType.toUpperCase()}** version bump`,
109+
'',
110+
`| | Version |`,
111+
`|---|---|`,
112+
`| Current | \`${currentVersion}\` |`,
113+
`| Next | \`${nextVersion}\` |`,
114+
'',
115+
'This version will be released automatically when this PR is merged to `main`.',
116+
].join('\n');
117+
}
118+
119+
const { data: comments } = await github.rest.issues.listComments({
120+
owner: context.repo.owner,
121+
repo: context.repo.repo,
122+
issue_number: context.payload.pull_request.number,
123+
});
124+
const existing = comments.find(c => c.body.includes('Release Version Check'));
125+
if (existing) {
126+
await github.rest.issues.updateComment({
127+
owner: context.repo.owner,
128+
repo: context.repo.repo,
129+
comment_id: existing.id,
130+
body,
131+
});
132+
} else {
133+
await github.rest.issues.createComment({
134+
owner: context.repo.owner,
135+
repo: context.repo.repo,
136+
issue_number: context.payload.pull_request.number,
137+
body,
138+
});
139+
}

.github/workflows/release-desktop.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Release Desktop
22

33
on:
4+
release:
5+
types: [published]
46
push:
57
tags:
68
- 'v*'

.github/workflows/release-mobile.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Release Mobile
22

33
on:
4+
release:
5+
types: [published]
46
push:
57
tags:
68
- 'v*'

.github/workflows/release-web.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Release Web
22

33
on:
4+
release:
5+
types: [published]
46
push:
57
tags:
68
- 'v*'

0 commit comments

Comments
 (0)