Skip to content

Commit 51c6201

Browse files
committed
CI: Add release workflows
1 parent 15d8a68 commit 51c6201

2 files changed

Lines changed: 212 additions & 0 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: Prepare Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
bump:
7+
description: 'Version bump type'
8+
required: true
9+
type: choice
10+
default: 'patch'
11+
options:
12+
- patch
13+
- minor
14+
- major
15+
16+
jobs:
17+
prepare:
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Generate token
22+
id: generate-token
23+
uses: actions/create-github-app-token@v1
24+
with:
25+
app-id: ${{ vars.ALCHEMY_BOT_APP_ID }}
26+
private-key: ${{ secrets.ALCHEMY_BOT_APP_PRIVATE_KEY }}
27+
28+
- uses: actions/checkout@v4
29+
with:
30+
token: ${{ steps.generate-token.outputs.token }}
31+
32+
- name: Calculate next version
33+
id: version
34+
run: |
35+
# Read current version
36+
CURRENT=$(grep VERSION lib/alchemy/solidus/version.rb | sed 's/.*"\(.*\)".*/\1/')
37+
echo "Current version: $CURRENT"
38+
39+
# Split into major.minor.patch
40+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
41+
42+
# Bump based on input
43+
case "${{ inputs.bump }}" in
44+
major)
45+
MAJOR=$((MAJOR + 1))
46+
MINOR=0
47+
PATCH=0
48+
;;
49+
minor)
50+
MINOR=$((MINOR + 1))
51+
PATCH=0
52+
;;
53+
patch)
54+
PATCH=$((PATCH + 1))
55+
;;
56+
esac
57+
58+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
59+
echo "New version: $NEW_VERSION"
60+
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
61+
62+
- name: Configure git
63+
run: |
64+
git config user.name "alchemycms-bot"
65+
git config user.email "alchemycms-bot@users.noreply.github.com"
66+
67+
- name: Create release branch
68+
run: |
69+
git checkout -b release/v${{ steps.version.outputs.version }}
70+
71+
- name: Generate release notes
72+
id: release-notes
73+
uses: actions/github-script@v7
74+
with:
75+
github-token: ${{ steps.generate-token.outputs.token }}
76+
script: |
77+
const { writeFileSync } = require('fs');
78+
79+
// Get the previous tag for comparison
80+
let previousTag;
81+
try {
82+
const tags = await github.rest.repos.listTags({
83+
owner: context.repo.owner,
84+
repo: context.repo.repo,
85+
per_page: 1
86+
});
87+
previousTag = tags.data[0]?.name;
88+
} catch (error) {
89+
console.log('No previous tags found');
90+
}
91+
92+
// Generate release notes
93+
const params = {
94+
owner: context.repo.owner,
95+
repo: context.repo.repo,
96+
tag_name: 'v${{ steps.version.outputs.version }}',
97+
target_commitish: context.ref.replace('refs/heads/', '')
98+
};
99+
100+
if (previousTag) {
101+
params.previous_tag_name = previousTag;
102+
}
103+
104+
const { data } = await github.rest.repos.generateReleaseNotes(params);
105+
106+
// Save to file for changelog
107+
writeFileSync('/tmp/release-notes.md', data.body);
108+
109+
// Also save for PR body
110+
writeFileSync('/tmp/pr-body.md', data.body);
111+
112+
- name: Bump version
113+
run: |
114+
# Update version file
115+
sed -i 's/VERSION = "[^"]*"/VERSION = "${{ steps.version.outputs.version }}"/' lib/alchemy/solidus/version.rb
116+
117+
# Update changelog with generated release notes
118+
DATE=$(date +%Y-%m-%d)
119+
{
120+
echo "# Changelog"
121+
echo ""
122+
echo "## ${{ steps.version.outputs.version }} ($DATE)"
123+
echo ""
124+
cat /tmp/release-notes.md
125+
echo ""
126+
tail -n +3 CHANGELOG.md
127+
} > /tmp/changelog-new.md
128+
mv /tmp/changelog-new.md CHANGELOG.md
129+
130+
- name: Commit changes
131+
run: |
132+
git add lib/alchemy/solidus/version.rb CHANGELOG.md
133+
git commit -m "Release v${{ steps.version.outputs.version }}"
134+
git push origin release/v${{ steps.version.outputs.version }}
135+
136+
- name: Create Pull Request
137+
uses: actions/github-script@v7
138+
with:
139+
github-token: ${{ steps.generate-token.outputs.token }}
140+
script: |
141+
const { readFileSync } = require('fs');
142+
const releaseNotes = readFileSync('/tmp/pr-body.md', 'utf8');
143+
144+
const { data: pr } = await github.rest.pulls.create({
145+
owner: context.repo.owner,
146+
repo: context.repo.repo,
147+
title: 'Release v${{ steps.version.outputs.version }}',
148+
head: 'release/v${{ steps.version.outputs.version }}',
149+
base: 'main',
150+
body: `## Release v${{ steps.version.outputs.version }}
151+
152+
${releaseNotes}
153+
154+
---
155+
This PR was automatically created by the prepare-release workflow.
156+
Once merged, the gem will be automatically published to RubyGems.`
157+
});
158+
159+
console.log(`Created PR #${pr.number}: ${pr.html_url}`);

.github/workflows/release.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Publish Release
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
types: [closed]
7+
branches:
8+
- main
9+
10+
jobs:
11+
publish:
12+
# Only run if manually triggered OR (PR was merged and branch starts with "release/v")
13+
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/v'))
14+
runs-on: ubuntu-latest
15+
permissions:
16+
id-token: write
17+
contents: write
18+
19+
steps:
20+
- name: Generate token
21+
id: generate-token
22+
uses: actions/create-github-app-token@v1
23+
with:
24+
app-id: ${{ vars.ALCHEMY_BOT_APP_ID }}
25+
private-key: ${{ secrets.ALCHEMY_BOT_APP_PRIVATE_KEY }}
26+
27+
- uses: actions/checkout@v4
28+
with:
29+
token: ${{ steps.generate-token.outputs.token }}
30+
31+
- name: Set up Ruby
32+
uses: ruby/setup-ruby@v1
33+
with:
34+
bundler-cache: true
35+
ruby-version: ruby
36+
37+
- name: Release gem to RubyGems
38+
uses: rubygems/release-gem@v1
39+
40+
- name: Get version
41+
id: version
42+
run: |
43+
VERSION=$(grep VERSION lib/alchemy/solidus/version.rb | sed 's/.*"\(.*\)".*/\1/')
44+
echo "version=$VERSION" >> $GITHUB_OUTPUT
45+
echo "Version: $VERSION"
46+
47+
- name: Create GitHub Release
48+
uses: softprops/action-gh-release@v2
49+
with:
50+
tag_name: v${{ steps.version.outputs.version }}
51+
generate_release_notes: true
52+
env:
53+
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}

0 commit comments

Comments
 (0)