Skip to content

Commit 920e1d5

Browse files
Merge pull request #203 from joshrotenberg/feat/release-system
feat: implement comprehensive release automation system
2 parents fee956d + 8514042 commit 920e1d5

File tree

11 files changed

+825
-93
lines changed

11 files changed

+825
-93
lines changed

.github/workflows/docker.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Docker Build and Push
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags:
7+
- 'v*'
8+
release:
9+
types: [published]
10+
11+
env:
12+
REGISTRY: docker.io
13+
IMAGE_NAME: joshrotenberg/redisctl
14+
15+
jobs:
16+
docker:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v4
25+
26+
- name: Set up QEMU
27+
uses: docker/setup-qemu-action@v3
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Log in to Docker Hub
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ${{ env.REGISTRY }}
36+
username: ${{ secrets.DOCKER_USERNAME }}
37+
password: ${{ secrets.DOCKER_PASSWORD }}
38+
39+
- name: Extract metadata
40+
id: meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
44+
tags: |
45+
type=ref,event=branch
46+
type=ref,event=pr
47+
type=semver,pattern={{version}}
48+
type=semver,pattern={{major}}.{{minor}}
49+
type=semver,pattern={{major}}
50+
type=sha
51+
type=raw,value=latest,enable={{is_default_branch}}
52+
53+
- name: Build and push Docker image
54+
uses: docker/build-push-action@v5
55+
with:
56+
context: .
57+
file: ./Dockerfile.alpine
58+
platforms: linux/amd64,linux/arm64
59+
push: true
60+
tags: ${{ steps.meta.outputs.tags }}
61+
labels: ${{ steps.meta.outputs.labels }}
62+
cache-from: type=gha
63+
cache-to: type=gha,mode=max
64+
build-args: |
65+
VERSION=${{ github.ref_name }}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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+
options:
11+
- patch
12+
- minor
13+
- major
14+
pre_release:
15+
description: 'Pre-release tag (e.g., alpha, beta, rc)'
16+
required: false
17+
type: string
18+
19+
permissions:
20+
contents: write
21+
pull-requests: write
22+
23+
jobs:
24+
prepare:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@v4
29+
with:
30+
fetch-depth: 0
31+
token: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Install Rust
34+
uses: dtolnay/rust-toolchain@stable
35+
36+
- name: Install git-cliff
37+
run: cargo install git-cliff
38+
39+
- name: Determine new version
40+
id: version
41+
run: |
42+
current_version=$(grep '^version =' Cargo.toml | head -1 | cut -d'"' -f2)
43+
echo "Current version: $current_version"
44+
45+
IFS='.' read -r major minor patch <<< "$current_version"
46+
47+
case "${{ github.event.inputs.bump }}" in
48+
major)
49+
major=$((major + 1))
50+
minor=0
51+
patch=0
52+
;;
53+
minor)
54+
minor=$((minor + 1))
55+
patch=0
56+
;;
57+
patch)
58+
patch=$((patch + 1))
59+
;;
60+
esac
61+
62+
new_version="$major.$minor.$patch"
63+
64+
if [ -n "${{ github.event.inputs.pre_release }}" ]; then
65+
new_version="$new_version-${{ github.event.inputs.pre_release }}"
66+
fi
67+
68+
echo "New version: $new_version"
69+
echo "new_version=$new_version" >> $GITHUB_OUTPUT
70+
echo "current_version=$current_version" >> $GITHUB_OUTPUT
71+
72+
- name: Update version in Cargo.toml files
73+
run: |
74+
# Update workspace version
75+
sed -i 's/^version = ".*"/version = "${{ steps.version.outputs.new_version }}"/' Cargo.toml
76+
77+
# Update crate versions
78+
for crate in crates/*/Cargo.toml; do
79+
sed -i 's/^version = ".*"/version = "${{ steps.version.outputs.new_version }}"/' "$crate"
80+
done
81+
82+
# Update internal dependencies
83+
find . -name "Cargo.toml" -exec sed -i \
84+
-e 's/redis-cloud = { version = ".*"/redis-cloud = { version = "${{ steps.version.outputs.new_version }}"/' \
85+
-e 's/redis-enterprise = { version = ".*"/redis-enterprise = { version = "${{ steps.version.outputs.new_version }}"/' \
86+
{} \;
87+
88+
- name: Generate changelog
89+
run: |
90+
git-cliff --config cliff.toml \
91+
--tag v${{ steps.version.outputs.new_version }} \
92+
--unreleased \
93+
--output CHANGELOG.md
94+
95+
- name: Update Cargo.lock
96+
run: cargo update -w
97+
98+
- name: Create release branch
99+
run: |
100+
git config user.name "github-actions[bot]"
101+
git config user.email "github-actions[bot]@users.noreply.github.com"
102+
103+
branch_name="release/v${{ steps.version.outputs.new_version }}"
104+
git checkout -b "$branch_name"
105+
106+
git add -A
107+
git commit -m "chore: prepare release v${{ steps.version.outputs.new_version }}"
108+
git push origin "$branch_name"
109+
110+
- name: Create pull request
111+
uses: peter-evans/create-pull-request@v5
112+
with:
113+
token: ${{ secrets.GITHUB_TOKEN }}
114+
branch: release/v${{ steps.version.outputs.new_version }}
115+
title: "Release v${{ steps.version.outputs.new_version }}"
116+
body: |
117+
## 🚀 Release v${{ steps.version.outputs.new_version }}
118+
119+
This PR prepares the release of version ${{ steps.version.outputs.new_version }}.
120+
121+
### Changes
122+
- Version bumped from ${{ steps.version.outputs.current_version }} to ${{ steps.version.outputs.new_version }}
123+
- Updated CHANGELOG.md with latest changes
124+
- Updated Cargo.lock
125+
126+
### Next Steps
127+
1. Review the changes
128+
2. Merge this PR to trigger the release
129+
3. The tag-on-merge workflow will create the release tag
130+
4. The release workflow will build and publish artifacts
131+
132+
---
133+
*This PR was automatically created by the prepare-release workflow.*
134+
labels: |
135+
release
136+
automated

.github/workflows/release-plz.yml

Lines changed: 0 additions & 29 deletions
This file was deleted.

.github/workflows/tag-on-merge.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Tag on Merge
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
branches:
7+
- main
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
tag:
14+
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/')
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
token: ${{ secrets.GITHUB_TOKEN }}
22+
23+
- name: Extract version from branch name
24+
id: version
25+
run: |
26+
branch_name="${{ github.event.pull_request.head.ref }}"
27+
version="${branch_name#release/}"
28+
echo "Version extracted: $version"
29+
echo "version=$version" >> $GITHUB_OUTPUT
30+
31+
- name: Create and push tag
32+
run: |
33+
git config user.name "github-actions[bot]"
34+
git config user.email "github-actions[bot]@users.noreply.github.com"
35+
36+
tag_name="${{ steps.version.outputs.version }}"
37+
38+
# Create annotated tag with release notes from PR body
39+
git tag -a "$tag_name" -m "Release $tag_name" -m "${{ github.event.pull_request.body }}"
40+
git push origin "$tag_name"
41+
42+
echo "✅ Created and pushed tag: $tag_name"
43+
44+
- name: Trigger release workflow
45+
uses: peter-evans/repository-dispatch@v2
46+
with:
47+
token: ${{ secrets.GITHUB_TOKEN }}
48+
event-type: release-tagged
49+
client-payload: '{"tag": "${{ steps.version.outputs.version }}"}'

0 commit comments

Comments
 (0)