Skip to content

Commit 0e901a9

Browse files
committed
chore: automatically create release after bumping version
1 parent 8ceb0c3 commit 0e901a9

File tree

2 files changed

+217
-14
lines changed

2 files changed

+217
-14
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
name: Version Tag and Release Notes
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'versions.json'
9+
10+
workflow_dispatch:
11+
inputs:
12+
version:
13+
description: 'Version number (e.g., 0.17.0)'
14+
required: true
15+
type: string
16+
17+
jobs:
18+
create-tag-and-release:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0 # Fetch full history for release notes
25+
26+
- name: Extract version from versions.json
27+
id: extract_version
28+
run: |
29+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
30+
VERSION="${{ github.event.inputs.version }}"
31+
else
32+
# Extract version from versions.json
33+
VERSION=$(jq -r '.[0]' versions.json)
34+
echo "Extracted version from versions.json: $VERSION"
35+
fi
36+
37+
if [[ -z "$VERSION" ]]; then
38+
echo "Could not extract version"
39+
exit 1
40+
fi
41+
42+
# Ensure version has patch number (add .0 if missing)
43+
if [[ ! "$VERSION" =~ \.[0-9]+$ ]]; then
44+
VERSION="${VERSION}.0"
45+
fi
46+
47+
echo "Final version: $VERSION"
48+
echo "version=$VERSION" >> $GITHUB_OUTPUT
49+
echo "tag_name=v$VERSION" >> $GITHUB_OUTPUT - name: Check if tag exists
50+
id: check_tag
51+
run: |
52+
TAG_NAME="v${{ steps.extract_version.outputs.version }}"
53+
if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
54+
echo "Tag $TAG_NAME already exists"
55+
echo "tag_exists=true" >> $GITHUB_OUTPUT
56+
else
57+
echo "Tag $TAG_NAME does not exist"
58+
echo "tag_exists=false" >> $GITHUB_OUTPUT
59+
fi
60+
61+
- name: Get previous tag for release notes
62+
id: previous_tag
63+
if: steps.check_tag.outputs.tag_exists == 'false'
64+
run: |
65+
# Get the previous tag
66+
PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
67+
if [[ -z "$PREVIOUS_TAG" ]]; then
68+
# If no previous tag, use the first commit
69+
PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD)
70+
fi
71+
echo "previous_tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT
72+
echo "Previous tag: $PREVIOUS_TAG"
73+
74+
- name: Create tag
75+
if: steps.check_tag.outputs.tag_exists == 'false'
76+
run: |
77+
TAG_NAME="${{ steps.extract_version.outputs.tag_name }}"
78+
git config user.name "github-actions[bot]"
79+
git config user.email "github-actions[bot]@users.noreply.github.com"
80+
git tag -a "$TAG_NAME" -m "Release $TAG_NAME"
81+
git push origin "$TAG_NAME"
82+
83+
- name: Generate release notes
84+
if: steps.check_tag.outputs.tag_exists == 'false'
85+
uses: actions/github-script@v7
86+
with:
87+
script: |
88+
const { data: release } = await github.rest.repos.createRelease({
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
tag_name: '${{ steps.extract_version.outputs.tag_name }}',
92+
name: 'Release ${{ steps.extract_version.outputs.tag_name }}',
93+
body: '', // Will be auto-generated
94+
draft: false,
95+
prerelease: false,
96+
generate_release_notes: true
97+
});
98+
99+
console.log(`Created release: ${release.html_url}`);
100+
101+
// Output release info
102+
core.setOutput('release_url', release.html_url);
103+
core.setOutput('release_id', release.id);
104+
105+
- name: Update release with additional info
106+
if: steps.check_tag.outputs.tag_exists == 'false'
107+
uses: actions/github-script@v7
108+
with:
109+
script: |
110+
// Get the release that was just created
111+
const { data: releases } = await github.rest.repos.listReleases({
112+
owner: context.repo.owner,
113+
repo: context.repo.repo,
114+
per_page: 1
115+
});
116+
117+
if (releases.length === 0) {
118+
console.log('No releases found');
119+
return;
120+
}
121+
122+
const release = releases[0];
123+
124+
// Get commits between previous tag and current tag
125+
const previousTag = '${{ steps.previous_tag.outputs.previous_tag }}';
126+
const currentTag = '${{ steps.extract_version.outputs.tag_name }}';
127+
128+
let commits = [];
129+
try {
130+
const { data: compareData } = await github.rest.repos.compareCommits({
131+
owner: context.repo.owner,
132+
repo: context.repo.repo,
133+
base: previousTag,
134+
head: currentTag
135+
});
136+
commits = compareData.commits;
137+
} catch (error) {
138+
console.log(`Error comparing commits: ${error.message}`);
139+
// Fallback: get recent commits
140+
const { data: recentCommits } = await github.rest.repos.listCommits({
141+
owner: context.repo.owner,
142+
repo: context.repo.repo,
143+
per_page: 50
144+
});
145+
commits = recentCommits;
146+
}
147+
148+
// Get unique contributors
149+
const contributors = [...new Set(commits.map(commit => commit.author?.login).filter(Boolean))];
150+
151+
// Prepare additional release notes content
152+
let additionalContent = '\n\n## Contributors\n\n';
153+
contributors.forEach(contributor => {
154+
additionalContent += `* @${contributor}\n`;
155+
});
156+
157+
additionalContent += `\n**Full Changelog**: https://github.com/${context.repo.owner}/${context.repo.repo}/compare/${previousTag}...${currentTag}`;
158+
159+
// Update the release with additional content
160+
await github.rest.repos.updateRelease({
161+
owner: context.repo.owner,
162+
repo: context.repo.repo,
163+
release_id: release.id,
164+
body: release.body + additionalContent
165+
});
166+
167+
console.log(`Updated release with contributors and changelog link`);
168+
169+
- name: Notify completion
170+
if: steps.check_tag.outputs.tag_exists == 'false'
171+
run: |
172+
echo "✅ Successfully created tag ${{ steps.extract_version.outputs.tag_name }} and generated release notes!"
173+
echo "🔗 Release URL will be available in the GitHub repository releases page"
174+
175+
- name: Skip notification
176+
if: steps.check_tag.outputs.tag_exists == 'true'
177+
run: |
178+
echo "ℹ️ Tag ${{ steps.extract_version.outputs.tag_name }} already exists, skipping release creation"

package-lock.json

Lines changed: 39 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)