1+ name : Semantic Release
2+
3+ on :
4+ push :
5+ branches :
6+ - production
7+ workflow_dispatch :
8+
9+ permissions :
10+ contents : write
11+ issues : write
12+ pull-requests : write
13+
14+ jobs :
15+ release :
16+ name : Create Semantic Release
17+ runs-on : ubuntu-latest
18+
19+ outputs :
20+ new_release_published : ${{ steps.semantic.outputs.new_release_published }}
21+ new_release_version : ${{ steps.semantic.outputs.new_release_version }}
22+ new_release_git_tag : ${{ steps.semantic.outputs.new_release_git_tag }}
23+
24+ steps :
25+ - name : Checkout
26+ uses : actions/checkout@v4
27+ with :
28+ fetch-depth : 0
29+ token : ${{ secrets.GITHUB_TOKEN }}
30+
31+ - name : Setup Node.js
32+ uses : actions/setup-node@v4
33+ with :
34+ node-version : ' 20'
35+
36+ - name : Install semantic-release dependencies
37+ run : |
38+ npm install -g semantic-release
39+ npm install -g @semantic-release/changelog
40+ npm install -g @semantic-release/git
41+ npm install -g @semantic-release/github
42+ npm install -g conventional-changelog-conventionalcommits
43+
44+ - name : Configure Git
45+ run : |
46+ git config user.name "github-actions[bot]"
47+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
48+
49+ - name : Handle existing v2.0 tag
50+ run : |
51+ # Check if v2.0 tag exists but v2.0.0 doesn't
52+ if git tag -l | grep -q "^v2.0$" && ! git tag -l | grep -q "^v2.0.0$"; then
53+ echo "Found v2.0 tag, creating v2.0.0 tag for semantic-release compatibility"
54+ # Get the commit hash of v2.0 tag
55+ COMMIT_HASH=$(git rev-list -n 1 v2.0)
56+ # Create v2.0.0 tag pointing to the same commit
57+ git tag v2.0.0 $COMMIT_HASH
58+ echo "Created v2.0.0 tag pointing to same commit as v2.0"
59+ fi
60+
61+ - name : Create .releaserc.json
62+ run : |
63+ cat > .releaserc.json << 'EOF'
64+ {
65+ "branches": ["production"],
66+ "tagFormat": "v${version}",
67+ "repositoryUrl": "https://github.com/ChingEnLin/QueryPal",
68+ "plugins": [
69+ [
70+ "@semantic-release/commit-analyzer",
71+ {
72+ "preset": "conventionalcommits",
73+ "releaseRules": [
74+ {"type": "feat", "release": "minor"},
75+ {"type": "fix", "release": "patch"},
76+ {"type": "docs", "release": "patch"},
77+ {"type": "style", "release": "patch"},
78+ {"type": "refactor", "release": "patch"},
79+ {"type": "perf", "release": "patch"},
80+ {"type": "test", "release": "patch"},
81+ {"type": "ci", "release": "patch"},
82+ {"type": "chore", "release": "patch"},
83+ {"type": "build", "release": "patch"},
84+ {"breaking": true, "release": "major"}
85+ ]
86+ }
87+ ],
88+ [
89+ "@semantic-release/release-notes-generator",
90+ {
91+ "preset": "conventionalcommits",
92+ "presetConfig": {
93+ "types": [
94+ {"type": "feat", "section": "Features"},
95+ {"type": "fix", "section": "Bug Fixes"},
96+ {"type": "chore", "section": "Maintenance", "hidden": false},
97+ {"type": "docs", "section": "Documentation", "hidden": false},
98+ {"type": "style", "section": "Styling", "hidden": false},
99+ {"type": "refactor", "section": "Refactoring", "hidden": false},
100+ {"type": "perf", "section": "Performance", "hidden": false},
101+ {"type": "test", "section": "Testing", "hidden": false},
102+ {"type": "build", "section": "Build System", "hidden": false},
103+ {"type": "ci", "section": "CI/CD", "hidden": false}
104+ ]
105+ }
106+ }
107+ ],
108+ [
109+ "@semantic-release/changelog",
110+ {
111+ "changelogFile": "CHANGELOG.md"
112+ }
113+ ],
114+ [
115+ "@semantic-release/git",
116+ {
117+ "assets": ["CHANGELOG.md"],
118+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
119+ }
120+ ],
121+ [
122+ "@semantic-release/github",
123+ {
124+ "assets": []
125+ }
126+ ]
127+ ]
128+ }
129+ EOF
130+
131+ - name : Run semantic-release
132+ id : semantic
133+ run : semantic-release
134+ env :
135+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
136+
137+ - name : Output version information
138+ if : steps.semantic.outputs.new_release_published == 'true'
139+ run : |
140+ echo "New version published: ${{ steps.semantic.outputs.new_release_version }}"
141+ echo "Git tag: ${{ steps.semantic.outputs.new_release_git_tag }}"
142+
143+ update-wiki :
144+ name : Update Wiki Page
145+ runs-on : ubuntu-latest
146+ needs : release
147+ if : needs.release.outputs.new_release_published == 'true'
148+
149+ steps :
150+ - name : Checkout
151+ uses : actions/checkout@v4
152+ with :
153+ fetch-depth : 0
154+
155+ - name : Get release information
156+ id : release_info
157+ run : |
158+ # Get the latest release information
159+ VERSION="${{ needs.release.outputs.new_release_version }}"
160+ TAG="${{ needs.release.outputs.new_release_git_tag }}"
161+
162+ # Get commit messages since last tag (excluding the current one)
163+ PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
164+ if [ -n "$PREVIOUS_TAG" ]; then
165+ COMMITS=$(git log ${PREVIOUS_TAG}..HEAD --oneline --no-merges)
166+ else
167+ COMMITS=$(git log --oneline --no-merges)
168+ fi
169+
170+ # Create release notes
171+ echo "RELEASE_VERSION=${VERSION}" >> $GITHUB_OUTPUT
172+ echo "RELEASE_TAG=${TAG}" >> $GITHUB_OUTPUT
173+ echo "RELEASE_DATE=$(date '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT
174+
175+ # Save commits to file for wiki
176+ echo "$COMMITS" > commits.txt
177+
178+ - name : Create/Update Wiki Release Page
179+ run : |
180+ VERSION="${{ steps.release_info.outputs.RELEASE_VERSION }}"
181+ TAG="${{ steps.release_info.outputs.RELEASE_TAG }}"
182+ RELEASE_DATE="${{ steps.release_info.outputs.RELEASE_DATE }}"
183+
184+ # Clone wiki repository
185+ git clone https://github.com/ChingEnLin/QueryPal.wiki.git wiki
186+ cd wiki
187+
188+ # Configure git for wiki
189+ git config user.name "github-actions[bot]"
190+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
191+
192+ # Preserve existing releases before creating new content
193+ EXISTING_RELEASES=""
194+ if [ -f "Releases.md" ]; then
195+ # Extract everything after "### Previous Releases" from existing file
196+ if grep -q "### Previous Releases" "Releases.md"; then
197+ EXISTING_RELEASES=$(grep -A 1000 "### Previous Releases" "Releases.md" | tail -n +2)
198+ fi
199+
200+ # Also extract current "Latest Release" section to move to Previous Releases
201+ if grep -q "## Latest Release:" "Releases.md"; then
202+ CURRENT_LATEST=$(sed -n '/## Latest Release:/,/### Previous Releases/p' "Releases.md" | head -n -1)
203+ # Convert "Latest Release" to a previous release entry
204+ if [ -n "$CURRENT_LATEST" ]; then
205+ # Extract version from the current latest release
206+ PREV_VERSION=$(echo "$CURRENT_LATEST" | grep "## Latest Release:" | sed 's/.*Latest Release: //')
207+ # Format the previous release entry
208+ PREV_RELEASE_FORMATTED="## Release ${PREV_VERSION}"$'\n\n'"$(echo "$CURRENT_LATEST" | sed '/## Latest Release:/d')"
209+ # Combine with existing releases
210+ if [ -n "$EXISTING_RELEASES" ]; then
211+ EXISTING_RELEASES="${PREV_RELEASE_FORMATTED}"$'\n\n'"${EXISTING_RELEASES}"
212+ else
213+ EXISTING_RELEASES="${PREV_RELEASE_FORMATTED}"
214+ fi
215+ fi
216+ fi
217+ fi
218+
219+ # Create or update the Releases page with new content
220+ cat > "Releases.md" << EOF
221+ # QueryPal Releases
222+
223+ This page contains information about QueryPal releases, automatically generated from conventional commits.
224+
225+ ## Latest Release: ${TAG}
226+
227+ **Release Date:** ${RELEASE_DATE}
228+
229+ **Version:** ${VERSION}
230+
231+ ### Changes in this Release
232+
233+ EOF
234+
235+ # Add commit information
236+ if [ -f ../commits.txt ]; then
237+ echo "### Commits:" >> "Releases.md"
238+ echo "" >> "Releases.md"
239+ while IFS= read -r commit; do
240+ echo "- $commit" >> "Releases.md"
241+ done < ../commits.txt
242+ fi
243+
244+ # Add deployment information
245+ cat >> "Releases.md" << EOF
246+
247+ ### Deployment Information
248+
249+ - **Backend Service:** querypal-backend
250+ - **Frontend Service:** querypal-frontend
251+ - **Cloud Platform:** Google Cloud Run
252+ - **Region:** europe-west1
253+
254+ ### Getting Started
255+
256+ For setup and usage instructions, see the [main README](https://github.com/ChingEnLin/QueryPal/blob/production/README.md).
257+
258+ ### Previous Releases
259+
260+ EOF
261+
262+ # Append preserved existing releases
263+ if [ -n "$EXISTING_RELEASES" ]; then
264+ echo "$EXISTING_RELEASES" >> "Releases.md"
265+ fi
266+
267+ # Add to git and push
268+ git add "Releases.md"
269+ if ! git diff --staged --quiet; then
270+ git commit -m "docs: Update releases page for ${TAG}"
271+ git push https://${{ secrets.GITHUB_TOKEN }}@github.com/ChingEnLin/QueryPal.wiki.git
272+ echo "Wiki updated successfully"
273+ else
274+ echo "No changes to commit"
275+ fi
276+ env :
277+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments