Skip to content

Commit 80d35fe

Browse files
Add version bump check workflow and remove old release workflow
1 parent 90db914 commit 80d35fe

3 files changed

Lines changed: 119 additions & 77 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Catches when developers forget to bump package.json for release-affecting changes.
2+
# App code changes (app.js, bin/, config/, routes/, views/, etc.) require a version bump vs latest tag.
3+
# Skips for: test-only, docs, .github (workflows/config), dependency-only bumps without app edits.
4+
name: Check Version Bump
5+
6+
on:
7+
pull_request:
8+
9+
jobs:
10+
version-bump:
11+
name: Version bump
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Detect changed files and version bump
20+
id: detect
21+
run: |
22+
if git rev-parse HEAD^2 >/dev/null 2>&1; then
23+
FILES=$(git diff --name-only HEAD^1 HEAD^2)
24+
else
25+
FILES=$(git diff --name-only HEAD~1 HEAD)
26+
fi
27+
VERSION_FILES_CHANGED=false
28+
echo "$FILES" | grep -qx 'package.json' && VERSION_FILES_CHANGED=true
29+
echo "version_files_changed=$VERSION_FILES_CHANGED" >> $GITHUB_OUTPUT
30+
# App source paths for this boilerplate (no lib/webpack/dist); .github/ and test/ do not count
31+
CODE_CHANGED=false
32+
echo "$FILES" | grep -qE '^app\.js$|^bin/|^config/|^middlewares/|^models/|^public/|^routes/|^views/|^schemaNentries/' && CODE_CHANGED=true
33+
echo "$FILES" | grep -qx 'package.json' && CODE_CHANGED=true
34+
echo "code_changed=$CODE_CHANGED" >> $GITHUB_OUTPUT
35+
36+
- name: Skip when only test/docs/.github changed
37+
if: steps.detect.outputs.code_changed != 'true'
38+
run: |
39+
echo "No release-affecting files changed (e.g. only test/docs/.github). Skipping version-bump check."
40+
exit 0
41+
42+
- name: Fail when version bump was missed
43+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed != 'true'
44+
run: |
45+
echo "::error::This PR has code changes but no version bump. Please bump the version in package.json."
46+
exit 1
47+
48+
- name: Setup Node
49+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed == 'true'
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: '22.x'
53+
54+
- name: Check version bump
55+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed == 'true'
56+
run: |
57+
set -e
58+
PKG_VERSION=$(node -p "require('./package.json').version.replace(/^v/, '')")
59+
if [ -z "$PKG_VERSION" ]; then
60+
echo "::error::Could not read version from package.json"
61+
exit 1
62+
fi
63+
git fetch --tags --force 2>/dev/null || true
64+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
65+
if [ -z "$LATEST_TAG" ]; then
66+
echo "No existing tags found. Skipping version-bump check (first release)."
67+
exit 0
68+
fi
69+
LATEST_VERSION="${LATEST_TAG#v}"
70+
LATEST_VERSION="${LATEST_VERSION%%-*}"
71+
if [ "$(printf '%s\n' "$LATEST_VERSION" "$PKG_VERSION" | sort -V | tail -1)" != "$PKG_VERSION" ]; then
72+
echo "::error::Version bump required: package.json version ($PKG_VERSION) is not greater than latest tag ($LATEST_TAG). Please bump the version in package.json."
73+
exit 1
74+
fi
75+
if [ "$PKG_VERSION" = "$LATEST_VERSION" ]; then
76+
echo "::error::Version bump required: package.json version ($PKG_VERSION) equals latest tag ($LATEST_TAG). Please bump the version in package.json."
77+
exit 1
78+
fi
79+
echo "Version bump check passed: package.json is at $PKG_VERSION (latest tag: $LATEST_TAG)."

.github/workflows/release.yml

Lines changed: 0 additions & 77 deletions
This file was deleted.

.husky/post-checkout

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env sh
2+
# When switching to a branch that doesn't exist on remote (e.g. newly created),
3+
# pull and merge origin/main or origin/master into current branch. Does not push.
4+
5+
# Only run on branch checkout (not file checkout)
6+
if [ "$3" != "1" ]; then
7+
exit 0
8+
fi
9+
10+
# Skip if we don't have a remote
11+
if ! git rev-parse --verify origin 2>/dev/null; then
12+
exit 0
13+
fi
14+
15+
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
16+
17+
# Skip main/master - no need to merge base into these
18+
case "$CURRENT_BRANCH" in
19+
main|master) exit 0 ;;
20+
esac
21+
22+
# Only run when current branch does not exist on origin (treat as new local branch)
23+
if git ls-remote --heads origin "$CURRENT_BRANCH" 2>/dev/null | grep -q .; then
24+
echo "post-checkout: $CURRENT_BRANCH exists on origin, skipping merge."
25+
exit 0
26+
fi
27+
28+
# Prefer main, fallback to master
29+
if git rev-parse --verify origin/main 2>/dev/null; then
30+
BASE=origin/main
31+
elif git rev-parse --verify origin/master 2>/dev/null; then
32+
BASE=origin/master
33+
else
34+
exit 0
35+
fi
36+
37+
echo "New branch detected: merging latest $BASE into $CURRENT_BRANCH (local only, not pushing)..."
38+
git fetch origin
39+
git merge "$BASE" --no-edit --no-ff
40+
echo "Done. Merge is local only; push when ready."

0 commit comments

Comments
 (0)