Skip to content

Commit b0c2f69

Browse files
authored
Merge pull request #688 from thecodacus/stable-branch-workflow
chore: Add Automated Release Workflow
2 parents 68757cb + ddf4319 commit b0c2f69

File tree

2 files changed

+171
-0
lines changed

2 files changed

+171
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
name: Update Stable Branch
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
branches:
7+
- main
8+
9+
jobs:
10+
update-stable:
11+
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'stable-release')
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: write
15+
pull-requests: read
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
token: ${{ secrets.GITHUB_TOKEN }}
22+
23+
- name: Configure Git
24+
run: |
25+
git config --global user.name 'github-actions[bot]'
26+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
27+
28+
- name: Setup Node.js
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: '20'
32+
cache: 'npm'
33+
34+
- name: Determine Version Bump
35+
id: version_bump
36+
run: |
37+
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'major') }}" == "true" ]]; then
38+
echo "bump=major" >> $GITHUB_OUTPUT
39+
elif [[ "${{ contains(github.event.pull_request.labels.*.name, 'minor') }}" == "true" ]]; then
40+
echo "bump=minor" >> $GITHUB_OUTPUT
41+
else
42+
echo "bump=patch" >> $GITHUB_OUTPUT
43+
fi
44+
45+
- name: Get Current Version
46+
id: current_version
47+
run: |
48+
CURRENT_VERSION=$(node -p "require('./package.json').version")
49+
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
50+
51+
- name: Install semver
52+
run: npm install -g semver
53+
54+
- name: Bump Version
55+
id: bump_version
56+
run: |
57+
NEW_VERSION=$(semver -i ${{ steps.version_bump.outputs.bump }} ${{ steps.current_version.outputs.version }})
58+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
59+
60+
- name: Update Package.json
61+
run: |
62+
NEW_VERSION=${{ steps.bump_version.outputs.new_version }}
63+
npm version $NEW_VERSION --no-git-tag-version --allow-same-version
64+
65+
- name: Generate Changelog
66+
id: changelog
67+
run: |
68+
# Get the latest tag
69+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
70+
71+
# Start changelog file
72+
echo "# Release v${{ steps.bump_version.outputs.new_version }}" > changelog.md
73+
echo "" >> changelog.md
74+
75+
if [ -z "$LATEST_TAG" ]; then
76+
echo "### 🎉 First Release" >> changelog.md
77+
echo "" >> changelog.md
78+
COMPARE_BASE="$(git rev-list --max-parents=0 HEAD)"
79+
else
80+
echo "### 🔄 Changes since $LATEST_TAG" >> changelog.md
81+
echo "" >> changelog.md
82+
COMPARE_BASE="$LATEST_TAG"
83+
fi
84+
85+
# Function to extract conventional commit type
86+
get_commit_type() {
87+
if [[ $1 =~ ^feat:|^feature: ]]; then echo "✨ Features";
88+
elif [[ $1 =~ ^fix: ]]; then echo "🐛 Bug Fixes";
89+
elif [[ $1 =~ ^docs: ]]; then echo "📚 Documentation";
90+
elif [[ $1 =~ ^style: ]]; then echo "💎 Styles";
91+
elif [[ $1 =~ ^refactor: ]]; then echo "♻️ Code Refactoring";
92+
elif [[ $1 =~ ^perf: ]]; then echo "⚡️ Performance Improvements";
93+
elif [[ $1 =~ ^test: ]]; then echo "✅ Tests";
94+
elif [[ $1 =~ ^build: ]]; then echo "🛠️ Build System";
95+
elif [[ $1 =~ ^ci: ]]; then echo "⚙️ CI";
96+
elif [[ $1 =~ ^chore: ]]; then echo "🔧 Chores";
97+
else echo "🔍 Other Changes";
98+
fi
99+
}
100+
101+
# Generate categorized changelog
102+
declare -A CATEGORIES
103+
declare -A COMMITS_BY_CATEGORY
104+
105+
# Get commits since last tag or all commits if no tag exists
106+
while IFS= read -r commit_line; do
107+
HASH=$(echo "$commit_line" | cut -d'|' -f1)
108+
MSG=$(echo "$commit_line" | cut -d'|' -f2)
109+
PR_NUM=$(echo "$commit_line" | cut -d'|' -f3)
110+
111+
CATEGORY=$(get_commit_type "$MSG")
112+
CATEGORIES["$CATEGORY"]=1
113+
114+
# Format commit message with PR link if available
115+
if [ -n "$PR_NUM" ]; then
116+
COMMITS_BY_CATEGORY["$CATEGORY"]+="- ${MSG#*: } ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM))"$'\n'
117+
else
118+
COMMITS_BY_CATEGORY["$CATEGORY"]+="- ${MSG#*: }"$'\n'
119+
fi
120+
done < <(git log "${COMPARE_BASE}..HEAD" --pretty=format:"%H|%s|%(trailers:key=PR-Number,valueonly)" --reverse)
121+
122+
# Write categorized commits to changelog
123+
for category in "✨ Features" "🐛 Bug Fixes" "📚 Documentation" "💎 Styles" "♻️ Code Refactoring" "⚡️ Performance Improvements" "✅ Tests" "🛠️ Build System" "⚙️ CI" "🔧 Chores" "🔍 Other Changes"; do
124+
if [ -n "${COMMITS_BY_CATEGORY[$category]}" ]; then
125+
echo "#### $category" >> changelog.md
126+
echo "" >> changelog.md
127+
echo "${COMMITS_BY_CATEGORY[$category]}" >> changelog.md
128+
echo "" >> changelog.md
129+
fi
130+
done
131+
132+
# Add compare link if not first release
133+
if [ -n "$LATEST_TAG" ]; then
134+
echo "**Full Changelog**: [\`$LATEST_TAG..v${{ steps.bump_version.outputs.new_version }}\`](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/$LATEST_TAG...v${{ steps.bump_version.outputs.new_version }})" >> changelog.md
135+
fi
136+
137+
# Save changelog content for the release
138+
CHANGELOG_CONTENT=$(cat changelog.md)
139+
echo "content<<EOF" >> $GITHUB_OUTPUT
140+
echo "$CHANGELOG_CONTENT" >> $GITHUB_OUTPUT
141+
echo "EOF" >> $GITHUB_OUTPUT
142+
143+
- name: Commit Version Update
144+
run: |
145+
git add package.json package-lock.json
146+
git commit -m "chore: bump version to ${{ steps.bump_version.outputs.new_version }}"
147+
git push origin main
148+
149+
- name: Update Stable Branch
150+
run: |
151+
# Ensure stable branch exists
152+
git checkout stable 2>/dev/null || git checkout -b stable
153+
git merge main --no-ff -m "chore: merge main into stable for version ${{ steps.bump_version.outputs.new_version }}"
154+
git push origin stable
155+
156+
- name: Create and Push Tag
157+
run: |
158+
VERSION="v${{ steps.bump_version.outputs.new_version }}"
159+
git tag -a "$VERSION" -m "Release $VERSION"
160+
git push origin "$VERSION"
161+
162+
- name: Create GitHub Release
163+
env:
164+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
165+
run: |
166+
VERSION="v${{ steps.bump_version.outputs.new_version }}"
167+
gh release create "$VERSION" \
168+
--title "Release $VERSION" \
169+
--notes "${{ steps.changelog.outputs.content }}" \
170+
--target stable

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"license": "MIT",
66
"sideEffects": false,
77
"type": "module",
8+
"version": "0.0.0",
89
"scripts": {
910
"deploy": "npm run build && wrangler pages deploy",
1011
"build": "remix vite:build",

0 commit comments

Comments
 (0)