1- name : Bump Version
1+ name : Auto Bump Version on PR
22
33on :
4- push :
4+ pull_request :
5+ types : [opened, synchronize, reopened]
56 branches :
67 - development
78
89jobs :
910 bump-version :
10- # Skip if commit message contains [skip ci]
11- if : " !contains(github.event.head_commit.message, '[skip ci]')"
11+ # Skip if commit message contains [skip ci] or [version bump]
12+ if : |
13+ !contains(github.event.head_commit.message, '[skip ci]') &&
14+ !contains(github.event.head_commit.message, '[version bump]')
15+
1216 runs-on : ubuntu-latest
1317
18+ permissions :
19+ contents : write # Required to push to PR branch
20+ pull-requests : write # Required to comment on PR
21+
1422 steps :
15- - name : Checkout
16- uses : actions/checkout@v3
23+ - name : Checkout PR branch
24+ uses : actions/checkout@v4
1725 with :
26+ ref : ${{ github.head_ref }} # Check out the PR branch, not merge commit
1827 token : ${{ secrets.GITHUB_TOKEN }}
1928 fetch-depth : 0
2029
2130 - name : Setup Node.js
22- uses : actions/setup-node@v3
31+ uses : actions/setup-node@v4
2332 with :
24- node-version : ' 18'
33+ node-version : " 20"
34+
35+ - name : Check if version needs bumping
36+ id : check
37+ run : |
38+ # Fetch the base branch to compare against
39+ git fetch origin ${{ github.base_ref }}
40+ BASE_SHA=$(git rev-parse origin/${{ github.base_ref }})
41+
42+ echo "Comparing against base branch: ${{ github.base_ref }} ($BASE_SHA)"
43+
44+ # Check if package.json was modified in this PR
45+ CHANGED_FILES=$(git diff --name-only $BASE_SHA HEAD)
46+
47+ if echo "$CHANGED_FILES" | grep -qE "^package\.json$|^configure/package\.json$"; then
48+ echo "needs_bump=false" >> $GITHUB_OUTPUT
49+ echo "✓ Version files were already modified in this PR"
50+
51+ # Get the version for reporting
52+ CURRENT_VERSION=$(node -p "require('./package.json').version")
53+ echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
54+ else
55+ echo "needs_bump=true" >> $GITHUB_OUTPUT
56+ echo "✗ Version files not modified, will auto-bump"
57+ fi
2558
2659 - name : Bump version
60+ if : steps.check.outputs.needs_bump == 'true'
2761 id : bump
2862 run : |
2963 # Get current date in YYYYMMDD format
@@ -48,29 +82,156 @@ jobs:
4882 NEW_VERSION="$MAJOR.$MINOR.$PATCH-$DATE"
4983 echo "New version: $NEW_VERSION"
5084
85+ # Validate the new version format
86+ if ! echo "$NEW_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+-[0-9]{8}$'; then
87+ echo "Error: Generated invalid version format: $NEW_VERSION"
88+ exit 1
89+ fi
90+
5191 # Update package.json
5292 node -e "
5393 const fs = require('fs');
5494 const pkg = require('./package.json');
5595 pkg.version = '$NEW_VERSION';
5696 fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
5797 "
98+ echo "✓ Updated package.json"
5899
59- # Update configure/package.json
60- node -e "
61- const fs = require('fs');
62- const pkg = require('./configure/package.json');
63- pkg.version = '$NEW_VERSION';
64- fs.writeFileSync('./configure/package.json', JSON.stringify(pkg, null, 2) + '\n');
65- "
100+ # Update configure/package.json (with error handling)
101+ if [ -f configure/package.json ]; then
102+ node -e "
103+ const fs = require('fs');
104+ const pkg = require('./configure/package.json');
105+ pkg.version = '$NEW_VERSION';
106+ fs.writeFileSync('./configure/package.json', JSON.stringify(pkg, null, 2) + '\n');
107+ "
108+ echo "✓ Updated configure/package.json"
109+ else
110+ echo "ℹ configure/package.json not found, skipping"
111+ fi
66112
67- # Export new version for commit message
113+ # Export new version for commit message and PR comment
68114 echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
69115
70- - name : Commit and push
116+ - name : Commit version bump to PR branch
117+ if : steps.check.outputs.needs_bump == 'true'
71118 run : |
72119 git config --local user.email "github-actions[bot]@users.noreply.github.com"
73120 git config --local user.name "github-actions[bot]"
121+
74122 git add package.json configure/package.json
75- git commit -m "chore: bump version to ${{ steps.bump.outputs.NEW_VERSION }} [skip ci]"
76- git push
123+
124+ # Check if there are actually changes to commit
125+ if git diff --staged --quiet; then
126+ echo "⚠ No changes to commit"
127+ exit 0
128+ fi
129+
130+ git commit -m "chore: bump version to ${{ steps.bump.outputs.NEW_VERSION }} [version bump]"
131+
132+ echo "✓ Committed version bump"
133+
134+ - name : Push to PR branch
135+ if : steps.check.outputs.needs_bump == 'true'
136+ run : |
137+ # Push to the PR branch (head_ref is the source branch of the PR)
138+ git push origin HEAD:${{ github.head_ref }}
139+
140+ echo "✓ Pushed version bump to PR branch: ${{ github.head_ref }}"
141+
142+ - name : Comment on PR - Version Auto-Bumped
143+ if : steps.check.outputs.needs_bump == 'true'
144+ uses : actions/github-script@v7
145+ with :
146+ script : |
147+ const comment = `## 🤖 Version Auto-Bumped
148+
149+ The version has been automatically incremented to **\`${{ steps.bump.outputs.NEW_VERSION }}\`**
150+
151+ This commit was added to your PR branch. When you merge this PR, the new version will be included.
152+
153+ ---
154+ <sub>If you want a different version, update \`package.json\` manually and push to this PR.</sub>`;
155+
156+ // Check for existing bot comment to avoid spam
157+ const { data: comments } = await github.rest.issues.listComments({
158+ owner: context.repo.owner,
159+ repo: context.repo.repo,
160+ issue_number: context.issue.number,
161+ });
162+
163+ const botComment = comments.find(comment =>
164+ comment.user.type === 'Bot' &&
165+ comment.body.includes('Version Auto-Bumped')
166+ );
167+
168+ if (botComment) {
169+ // Update existing comment
170+ await github.rest.issues.updateComment({
171+ owner: context.repo.owner,
172+ repo: context.repo.repo,
173+ comment_id: botComment.id,
174+ body: comment
175+ });
176+ console.log('Updated existing comment');
177+ } else {
178+ // Create new comment
179+ await github.rest.issues.createComment({
180+ owner: context.repo.owner,
181+ repo: context.repo.repo,
182+ issue_number: context.issue.number,
183+ body: comment
184+ });
185+ console.log('Created new comment');
186+ }
187+
188+ - name : Comment on PR - Version Already Updated
189+ if : steps.check.outputs.needs_bump == 'false'
190+ uses : actions/github-script@v7
191+ with :
192+ script : |
193+ const comment = `## ✅ Version Already Updated
194+
195+ This PR includes a manual version update to **\`${{ steps.check.outputs.current_version }}\`**
196+
197+ No automatic version bump needed.`;
198+
199+ const { data: comments } = await github.rest.issues.listComments({
200+ owner: context.repo.owner,
201+ repo: context.repo.repo,
202+ issue_number: context.issue.number,
203+ });
204+
205+ const botComment = comments.find(comment =>
206+ comment.user.type === 'Bot' &&
207+ (comment.body.includes('Version Already Updated') || comment.body.includes('Version Auto-Bumped'))
208+ );
209+
210+ if (botComment) {
211+ await github.rest.issues.updateComment({
212+ owner: context.repo.owner,
213+ repo: context.repo.repo,
214+ comment_id: botComment.id,
215+ body: comment
216+ });
217+ } else {
218+ await github.rest.issues.createComment({
219+ owner: context.repo.owner,
220+ repo: context.repo.repo,
221+ issue_number: context.issue.number,
222+ body: comment
223+ });
224+ }
225+
226+ - name : Summary
227+ if : always()
228+ run : |
229+ if [ "${{ steps.check.outputs.needs_bump }}" == "true" ]; then
230+ echo "### 🤖 Version Auto-Bumped" >> $GITHUB_STEP_SUMMARY
231+ echo "Automatically bumped to version **${{ steps.bump.outputs.NEW_VERSION }}**" >> $GITHUB_STEP_SUMMARY
232+ echo "" >> $GITHUB_STEP_SUMMARY
233+ echo "The version bump has been committed to the PR branch." >> $GITHUB_STEP_SUMMARY
234+ else
235+ echo "### ✅ Version Already Updated" >> $GITHUB_STEP_SUMMARY
236+ echo "PR already includes version **${{ steps.check.outputs.current_version }}**" >> $GITHUB_STEP_SUMMARY
237+ fi
0 commit comments