1- name : Production Pipeline
1+ name : Main Pipeline
22
33on :
44 push :
@@ -55,20 +55,21 @@ jobs:
5555 if : github.event_name == 'push' && github.ref == 'refs/heads/main'
5656 run : npm run test:redirects
5757
58- # JOB 2: Only run version bumping if the validation job passes AND it's the main branch
58+ # JOB 2: Only run version bumping if the validation job passes AND it's the stage branch
5959 bump-version :
6060 runs-on : ubuntu-latest
6161 needs : validate
62- # Only bump on merges to main
63- if : github.event_name == 'push' && github.ref == 'refs/heads/main '
62+ # Only bump version when code lands on stage
63+ if : github.event_name == 'push' && github.ref == 'refs/heads/stage '
6464 permissions :
65- contents : write # Allows the action to push changes back to GitHub
65+ contents : write # Crucial for the bot to push commits/tags
6666
6767 steps :
6868 - name : Checkout Repository
6969 uses : actions/checkout@v4
7070 with :
7171 fetch-depth : 0 # Required to see commit history cleanly
72+ ssh-key : ${{ secrets.DEPLOY_KEY }} # <--- Instructs Git to authenticate using deploy key
7273
7374 - name : Setup Node.js
7475 uses : actions/setup-node@v4
@@ -79,21 +80,50 @@ jobs:
7980 - name : Configure Git
8081 run : |
8182 git config --global user.name "github-actions[bot]"
82- git config --global user.email "github-actions[bot]@users.noreply.github.com"
83+ git config --global user.email "41898282+ github-actions[bot]@users.noreply.github.com"
8384
8485 # This reads the commit message. If it contains [major] or [minor], it bumps accordingly.
85- # Otherwise, it defaults to a standard patch bump (0.0.2 -> 0.0.3).
86+ # Otherwise, it defaults to a standard patch bump (e.g. 0.0.2 -> 0.0.3).
8687 - name : Evaluate Commits & Bump Version
8788 run : |
89+ # 1. Fetch current baseline version from package.json and latest commit message from the incoming branch
90+ CURRENT_VER=$(node -p "require('./package.json').version")
8891 COMMIT_MSG=$(git log -1 --pretty=%B)
92+
93+ # 2. Prevent infinite loops
94+ if [[ "$COMMIT_MSG" == *"chore: bump version"* ]]; then
95+ echo "Already a version bump commit. Exiting gracefully."
96+ exit 0
97+ fi
98+
99+ # 3. Determine the target version based on commit message
89100 if [[ "$COMMIT_MSG" == *"[major]"* ]]; then
90- npm version major -m "chore: bump version to %s [skip ci]"
101+ NEXT_VER=$(npx semver $CURRENT_VER -i major)
91102 elif [[ "$COMMIT_MSG" == *"[minor]"* ]]; then
92- npm version minor -m "chore: bump version to %s [skip ci]"
103+ NEXT_VER=$(npx semver $CURRENT_VER -i minor)
93104 else
94- npm version patch -m "chore: bump version to %s [skip ci]"
105+ NEXT_VER=$(npx semver $CURRENT_VER -i patch)
95106 fi
96107
97- - name : Push Version Update to GitHub
108+ # 4. Check for tag collisions and dynamically auto-increment patches if needed
109+ echo "Checking if tag v$NEXT_VER already exists..."
110+ while git rev-parse "v$NEXT_VER" >/dev/null 2>&1; do
111+ echo "⚠️ Tag v$NEXT_VER exists! Auto-incrementing to next patch level..."
112+ NEXT_VER=$(npx semver $NEXT_VER -i patch)
113+ done
114+
115+ echo "✅ Selected next available version tag: v$NEXT_VER"
116+
117+ # 5. Overwrite package.json explicitly to match the chosen unique version
118+ # We use --no-git-tag-version so we can manage the commit message and tag creation cleanly ourselves
119+ npm version $NEXT_VER --no-git-tag-version
120+
121+ # 6. Commit the files and generate the brand new unique Git tag
122+ git add package.json package-lock.json
123+ git commit -m "chore: bump version to $NEXT_VER [skip ci]"
124+ git tag -a "v$NEXT_VER" -m "chore: bump version to $NEXT_VER [skip ci]"
125+
126+ - name : Push Version Update and Tags to Stage
98127 run : |
99- git push origin main --follow-tags
128+ # The '-o ci.skip' option tells GitHub's server to completely ignore branch rules regarding PR requirements for this specific automated push
129+ git push origin stage --follow-tags -o ci.skip
0 commit comments