Skip to content

Commit ac3bce1

Browse files
committed
feat: add automated release on version bumps
When Renovate merges dependency updates with version bumps: **Flow:** 1. Renovate creates PR to development with version bump (0.1.0 → 0.1.1) 2. PR auto-merges (if patch update) 3. Auto-release workflow detects version change 4. Creates PR from development → main with changelog 5. When main PR merges, auto-release tags and triggers release workflow 6. Release workflow builds artifacts, creates GitHub Release, updates 'latest' tag **Result:** - Dependency updates automatically trigger 0.1.x patch releases - Security fixes get immediate releases - All releases include attestations, checksums, binaries No manual intervention needed for routine dependency updates!
1 parent cc88cc7 commit ac3bce1

2 files changed

Lines changed: 165 additions & 1 deletion

File tree

.github/workflows/auto-release.yml

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
name: Auto Release on Version Bump
2+
3+
# Automatically creates a release when Cargo.toml version changes
4+
# Triggered by Renovate PRs merging to development
5+
6+
on:
7+
push:
8+
branches: [development, main]
9+
paths:
10+
- 'Cargo.toml'
11+
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
16+
jobs:
17+
check-version-change:
18+
name: Check Version Change
19+
runs-on: ubuntu-latest
20+
outputs:
21+
version_changed: ${{ steps.check.outputs.changed }}
22+
new_version: ${{ steps.check.outputs.version }}
23+
should_release: ${{ steps.check.outputs.should_release }}
24+
steps:
25+
- uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 2
28+
29+
- name: Check if version changed
30+
id: check
31+
run: |
32+
# Get current version
33+
NEW_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/.*= "\(.*\)"/\1/')
34+
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
35+
36+
# Get previous version
37+
git checkout HEAD^
38+
OLD_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/.*= "\(.*\)"/\1/')
39+
git checkout -
40+
41+
echo "Current version: $NEW_VERSION"
42+
echo "Previous version: $OLD_VERSION"
43+
44+
if [ "$NEW_VERSION" != "$OLD_VERSION" ]; then
45+
echo "changed=true" >> $GITHUB_OUTPUT
46+
echo "should_release=true" >> $GITHUB_OUTPUT
47+
echo "✅ Version changed from $OLD_VERSION to $NEW_VERSION"
48+
else
49+
echo "changed=false" >> $GITHUB_OUTPUT
50+
echo "should_release=false" >> $GITHUB_OUTPUT
51+
echo "ℹ️ Version unchanged"
52+
fi
53+
54+
- name: Check if tag already exists
55+
if: steps.check.outputs.changed == 'true'
56+
run: |
57+
VERSION="${{ steps.check.outputs.version }}"
58+
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
59+
echo "⚠️ Tag v$VERSION already exists, skipping release"
60+
echo "should_release=false" >> $GITHUB_OUTPUT
61+
fi
62+
63+
create-pr-to-main:
64+
name: Create PR to Main
65+
needs: check-version-change
66+
if: needs.check-version-change.outputs.version_changed == 'true'
67+
runs-on: ubuntu-latest
68+
steps:
69+
- uses: actions/checkout@v4
70+
with:
71+
fetch-depth: 0
72+
73+
- name: Create release branch
74+
run: |
75+
VERSION="${{ needs.check-version-change.outputs.new_version }}"
76+
git checkout -b "release/v$VERSION"
77+
git push -u origin "release/v$VERSION"
78+
79+
- name: Create PR to main
80+
env:
81+
GH_TOKEN: ${{ github.token }}
82+
run: |
83+
VERSION="${{ needs.check-version-change.outputs.new_version }}"
84+
85+
# Check if PR already exists
86+
EXISTING_PR=$(gh pr list --base main --head "release/v$VERSION" --json number --jq '.[0].number')
87+
88+
if [ -n "$EXISTING_PR" ]; then
89+
echo "PR #$EXISTING_PR already exists"
90+
exit 0
91+
fi
92+
93+
# Get commit messages since last release
94+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
95+
if [ -n "$LAST_TAG" ]; then
96+
CHANGES=$(git log --pretty=format:"- %s (%h)" "$LAST_TAG"..HEAD)
97+
else
98+
CHANGES=$(git log --pretty=format:"- %s (%h)" -10)
99+
fi
100+
101+
gh pr create \
102+
--base main \
103+
--head "release/v$VERSION" \
104+
--title "Release v$VERSION" \
105+
--body "## Release v$VERSION
106+
107+
Automated release created by version bump in Cargo.toml.
108+
109+
### Changes
110+
$CHANGES
111+
112+
### Checklist
113+
- [ ] All CI checks pass
114+
- [ ] Documentation is up to date
115+
- [ ] CHANGELOG.md updated (if needed)
116+
117+
Once merged, the release workflow will automatically:
118+
- Create GitHub Release v$VERSION
119+
- Build and attach all artifacts
120+
- Update \`latest\` tag
121+
- Generate attestations and checksums
122+
123+
---
124+
_🤖 Auto-generated by version bump workflow_"
125+
126+
trigger-release:
127+
name: Create Release Tag
128+
needs: check-version-change
129+
if: needs.check-version-change.outputs.should_release == 'true' && github.ref == 'refs/heads/main'
130+
runs-on: ubuntu-latest
131+
steps:
132+
- uses: actions/checkout@v4
133+
with:
134+
fetch-depth: 0
135+
136+
- name: Create and push release tag
137+
run: |
138+
VERSION="${{ needs.check-version-change.outputs.new_version }}"
139+
140+
git config user.name "github-actions[bot]"
141+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
142+
143+
# Create tag
144+
git tag -a "v$VERSION" -m "Release v$VERSION
145+
146+
Automated release from version bump in Cargo.toml.
147+
Triggered by Renovate dependency updates."
148+
149+
# Push tag (this will trigger the release workflow)
150+
git push origin "v$VERSION"
151+
152+
echo "✅ Created and pushed tag v$VERSION"
153+
echo "🚀 Release workflow will now build and publish the release"

renovate.json5

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,20 @@
2525
// Rust-specific configuration
2626
"rust": {
2727
"enabled": true,
28-
"bumpVersion": "patch" // Auto-bump version in Cargo.toml
28+
"bumpVersion": "patch" // Auto-bump version in Cargo.toml for patch updates
2929
},
3030

31+
// Auto-release configuration
32+
// When version bumps merge to development, auto-release workflow creates release PR to main
33+
"prBodyNotes": [
34+
"---",
35+
"**🤖 Automated Release**: When this PR merges to `development`, the auto-release workflow will:",
36+
"- Detect the version bump in Cargo.toml",
37+
"- Create a PR from `development` → `main` with release notes",
38+
"- Once that PR merges, trigger the release workflow automatically",
39+
"- Publish v{{newVersion}} with all artifacts and attestations"
40+
],
41+
3142
// Cargo configuration
3243
"cargo": {
3344
"enabled": true,

0 commit comments

Comments
 (0)