Skip to content

Commit f28ac16

Browse files
committed
chore: updated gh action release workflow
1 parent 635e475 commit f28ac16

6 files changed

Lines changed: 566 additions & 10 deletions

File tree

‎.github/workflows/docker-build.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ on:
1111
type: boolean
1212
default: true
1313
required: false
14+
workflow_call:
15+
inputs:
16+
version:
17+
description: 'Version to build'
18+
type: string
19+
required: true
20+
tag_as_latest:
21+
description: 'Tag this version as latest'
22+
type: boolean
23+
default: true
24+
required: false
1425

1526
jobs:
1627
docker:

‎.github/workflows/release.yml‎

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
# Release Workflow
2+
#
3+
# Triggered by pushing a version tag (e.g., v0.12.15)
4+
# Builds CLI, Docker images, generates release notes, creates GitHub release, updates Homebrew
5+
#
6+
# Required secrets:
7+
# - DOCKERHUB_USERNAME, DOCKERHUB_TOKEN: Docker Hub authentication
8+
# - SELF_HOSTED_SENTRY_DSN: Sentry DSN for self-hosted builds
9+
# - ANTHROPIC_API_KEY: For Claude Code release notes generation
10+
# - HOMEBREW_TAP_PAT: Personal Access Token with repo scope for sequinstream/homebrew-sequin
11+
12+
name: Release
13+
14+
on:
15+
push:
16+
tags:
17+
- 'v*'
18+
19+
env:
20+
VERSION: ${{ github.ref_name }}
21+
22+
jobs:
23+
# ============================================================================
24+
# Build CLI for all platforms
25+
# ============================================================================
26+
build-cli:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v4
31+
32+
- name: Set up Go
33+
uses: actions/setup-go@v5
34+
with:
35+
go-version: '1.21'
36+
37+
- name: Build CLI for all platforms
38+
run: |
39+
cd cli
40+
PACKAGE_NAME="sequin-cli"
41+
PLATFORMS=(
42+
"windows/amd64"
43+
"windows/386"
44+
"darwin/amd64"
45+
"darwin/arm64"
46+
"linux/amd64"
47+
"linux/386"
48+
"linux/arm"
49+
"linux/arm64"
50+
)
51+
52+
mkdir -p ../release_assets
53+
54+
for platform in "${PLATFORMS[@]}"; do
55+
IFS="/" read -r GOOS GOARCH <<< "$platform"
56+
output_name="${PACKAGE_NAME}-${VERSION}-${GOOS}-${GOARCH}"
57+
if [ "$GOOS" = "windows" ]; then
58+
output_name+=".exe"
59+
fi
60+
61+
echo "Building $output_name"
62+
env GOOS="$GOOS" GOARCH="$GOARCH" go build -tags prod -o "$output_name" .
63+
64+
zip_name="../release_assets/${PACKAGE_NAME}-${VERSION}-${GOOS}-${GOARCH}.zip"
65+
zip -r "$zip_name" "$output_name"
66+
rm "$output_name"
67+
done
68+
69+
- name: Create docker-compose archive
70+
run: |
71+
cp -r docker sequin-docker-compose
72+
zip -r release_assets/sequin-docker-compose.zip sequin-docker-compose/
73+
rm -rf sequin-docker-compose
74+
75+
- name: Calculate SHA256 checksums
76+
id: checksums
77+
run: |
78+
cd release_assets
79+
echo "darwin_arm64=$(sha256sum sequin-cli-${VERSION}-darwin-arm64.zip | awk '{print $1}')" >> $GITHUB_OUTPUT
80+
echo "darwin_amd64=$(sha256sum sequin-cli-${VERSION}-darwin-amd64.zip | awk '{print $1}')" >> $GITHUB_OUTPUT
81+
echo "linux_arm64=$(sha256sum sequin-cli-${VERSION}-linux-arm64.zip | awk '{print $1}')" >> $GITHUB_OUTPUT
82+
echo "linux_amd64=$(sha256sum sequin-cli-${VERSION}-linux-amd64.zip | awk '{print $1}')" >> $GITHUB_OUTPUT
83+
84+
- name: Upload CLI artifacts
85+
uses: actions/upload-artifact@v4
86+
with:
87+
name: cli-binaries
88+
path: release_assets/*.zip
89+
90+
outputs:
91+
darwin_arm64_sha: ${{ steps.checksums.outputs.darwin_arm64 }}
92+
darwin_amd64_sha: ${{ steps.checksums.outputs.darwin_amd64 }}
93+
linux_arm64_sha: ${{ steps.checksums.outputs.linux_arm64 }}
94+
linux_amd64_sha: ${{ steps.checksums.outputs.linux_amd64 }}
95+
96+
# ============================================================================
97+
# Build Docker images (amd64 + arm64)
98+
# ============================================================================
99+
build-docker:
100+
strategy:
101+
matrix:
102+
include:
103+
- platform: linux/amd64
104+
runner: warp-ubuntu-latest-x64-32x
105+
- platform: linux/arm64
106+
runner: warp-ubuntu-latest-arm64-32x
107+
runs-on: ${{ matrix.runner }}
108+
steps:
109+
- name: Checkout
110+
uses: actions/checkout@v4
111+
112+
- name: Login to Docker Hub
113+
uses: docker/login-action@v3
114+
with:
115+
username: ${{ secrets.DOCKERHUB_USERNAME }}
116+
password: ${{ secrets.DOCKERHUB_TOKEN }}
117+
118+
- name: Extract platform info
119+
id: platform
120+
run: |
121+
ARCH=${MATRIX_PLATFORM#*/}
122+
echo "arch=$ARCH" >> $GITHUB_OUTPUT
123+
env:
124+
MATRIX_PLATFORM: ${{ matrix.platform }}
125+
126+
- name: Build and push (WarpBuild)
127+
uses: Warpbuilds/build-push-action@v6
128+
with:
129+
context: .
130+
platforms: ${{ matrix.platform }}
131+
push: true
132+
profile-name: sequin-builder
133+
build-args: |
134+
SELF_HOSTED=1
135+
RELEASE_VERSION=${{ env.VERSION }}
136+
SENTRY_DSN=${{ secrets.SELF_HOSTED_SENTRY_DSN }}
137+
tags: |
138+
sequin/sequin:${{ env.VERSION }}-${{ steps.platform.outputs.arch }}
139+
provenance: false
140+
sbom: false
141+
env:
142+
DOCKER_BUILD_RECORD_UPLOAD: false
143+
DOCKER_BUILD_SUMMARY: false
144+
DOCKER_BUILD_CHECKS_ANNOTATIONS: false
145+
146+
# ============================================================================
147+
# Smoke test Docker image
148+
# ============================================================================
149+
smoke-test:
150+
needs: build-docker
151+
runs-on: ubuntu-latest
152+
steps:
153+
- name: Checkout
154+
uses: actions/checkout@v4
155+
156+
- name: Login to Docker Hub
157+
uses: docker/login-action@v3
158+
with:
159+
username: ${{ secrets.DOCKERHUB_USERNAME }}
160+
password: ${{ secrets.DOCKERHUB_TOKEN }}
161+
162+
- name: Pull and test AMD64 image
163+
env:
164+
IMAGE_VERSION: ${{ env.VERSION }}-amd64
165+
run: .github/workflows/docker-smoke.sh
166+
167+
# ============================================================================
168+
# Create multi-arch Docker manifest
169+
# ============================================================================
170+
create-manifest:
171+
needs: [smoke-test, generate-release-notes]
172+
runs-on: ubuntu-latest
173+
steps:
174+
- name: Login to Docker Hub
175+
uses: docker/login-action@v3
176+
with:
177+
username: ${{ secrets.DOCKERHUB_USERNAME }}
178+
password: ${{ secrets.DOCKERHUB_TOKEN }}
179+
180+
- name: Create and push manifest
181+
run: |
182+
# Version-specific manifest
183+
docker buildx imagetools create -t sequin/sequin:${{ env.VERSION }} \
184+
sequin/sequin:${{ env.VERSION }}-amd64 \
185+
sequin/sequin:${{ env.VERSION }}-arm64
186+
187+
# Latest manifest
188+
docker buildx imagetools create -t sequin/sequin:latest \
189+
sequin/sequin:${{ env.VERSION }}-amd64 \
190+
sequin/sequin:${{ env.VERSION }}-arm64
191+
192+
# ============================================================================
193+
# Generate release notes with Claude Code
194+
# ============================================================================
195+
generate-release-notes:
196+
runs-on: ubuntu-latest
197+
steps:
198+
- name: Checkout
199+
uses: actions/checkout@v4
200+
with:
201+
fetch-depth: 0 # Full history for git log
202+
203+
- name: Get previous tag
204+
id: prev-tag
205+
run: |
206+
# Get the tag before the current one
207+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
208+
echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT
209+
210+
# Determine if this is a minor version bump
211+
CURRENT="${{ env.VERSION }}"
212+
if [ -n "$PREV_TAG" ]; then
213+
# Extract minor versions (e.g., v0.12.5 -> 12)
214+
PREV_MINOR=$(echo "$PREV_TAG" | sed -E 's/v?[0-9]+\.([0-9]+)\.[0-9]+/\1/')
215+
CURR_MINOR=$(echo "$CURRENT" | sed -E 's/v?[0-9]+\.([0-9]+)\.[0-9]+/\1/')
216+
if [ "$PREV_MINOR" != "$CURR_MINOR" ]; then
217+
echo "is_minor_bump=true" >> $GITHUB_OUTPUT
218+
else
219+
echo "is_minor_bump=false" >> $GITHUB_OUTPUT
220+
fi
221+
else
222+
echo "is_minor_bump=false" >> $GITHUB_OUTPUT
223+
fi
224+
225+
- name: Install Claude Code
226+
run: npm install -g @anthropic-ai/claude-code
227+
228+
- name: Generate release notes
229+
env:
230+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
231+
run: |
232+
PREV_TAG="${{ steps.prev-tag.outputs.tag }}"
233+
IS_MINOR="${{ steps.prev-tag.outputs.is_minor_bump }}"
234+
235+
# Build the prompt with context
236+
PROMPT="$(cat scripts/release-notes-template.txt)
237+
238+
---
239+
CONTEXT FOR THIS RELEASE:
240+
- New version: ${{ env.VERSION }}
241+
- Previous version: $PREV_TAG
242+
- Is minor version bump (breaking changes expected): $IS_MINOR
243+
244+
Generate the release notes now. Output ONLY the markdown release notes, no preamble or explanation."
245+
246+
# Run Claude Code with the prompt
247+
claude -p "$PROMPT" --output-file release_notes.md
248+
249+
echo "Generated release notes:"
250+
cat release_notes.md
251+
252+
- name: Upload release notes
253+
uses: actions/upload-artifact@v4
254+
with:
255+
name: release-notes
256+
path: release_notes.md
257+
258+
# ============================================================================
259+
# Create GitHub Release
260+
# ============================================================================
261+
create-release:
262+
needs: [build-cli, create-manifest, generate-release-notes]
263+
runs-on: ubuntu-latest
264+
steps:
265+
- name: Checkout
266+
uses: actions/checkout@v4
267+
268+
- name: Download CLI artifacts
269+
uses: actions/download-artifact@v4
270+
with:
271+
name: cli-binaries
272+
path: release_assets
273+
274+
- name: Download release notes
275+
uses: actions/download-artifact@v4
276+
with:
277+
name: release-notes
278+
path: .
279+
280+
- name: Create GitHub Release
281+
run: |
282+
gh release create ${{ env.VERSION }} \
283+
--title "Release ${{ env.VERSION }}" \
284+
--notes-file release_notes.md \
285+
release_assets/*.zip
286+
env:
287+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
288+
289+
# ============================================================================
290+
# Update Homebrew Formula
291+
# ============================================================================
292+
update-homebrew:
293+
needs: [create-release, build-cli]
294+
runs-on: ubuntu-latest
295+
steps:
296+
- name: Checkout homebrew-sequin
297+
uses: actions/checkout@v4
298+
with:
299+
repository: sequinstream/homebrew-sequin
300+
token: ${{ secrets.HOMEBREW_TAP_PAT }}
301+
path: homebrew-tap
302+
303+
- name: Update formula
304+
run: |
305+
cd homebrew-tap
306+
307+
# Update version
308+
sed -i 's/version ".*"/version "${{ env.VERSION }}"/' sequin.rb
309+
310+
# Update SHA256 checksums
311+
sed -i 's/sha256 ".*" # tag:darwin-arm64/sha256 "${{ needs.build-cli.outputs.darwin_arm64_sha }}" # tag:darwin-arm64/' sequin.rb
312+
sed -i 's/sha256 ".*" # tag:darwin-amd64/sha256 "${{ needs.build-cli.outputs.darwin_amd64_sha }}" # tag:darwin-amd64/' sequin.rb
313+
sed -i 's/sha256 ".*" # tag:linux-arm64/sha256 "${{ needs.build-cli.outputs.linux_arm64_sha }}" # tag:linux-arm64/' sequin.rb
314+
sed -i 's/sha256 ".*" # tag:linux-amd64/sha256 "${{ needs.build-cli.outputs.linux_amd64_sha }}" # tag:linux-amd64/' sequin.rb
315+
316+
echo "Updated sequin.rb:"
317+
cat sequin.rb
318+
319+
- name: Commit and push
320+
run: |
321+
cd homebrew-tap
322+
git config user.name "GitHub Actions"
323+
git config user.email "actions@github.com"
324+
git add sequin.rb
325+
git commit -m "Bump sequin-cli version to ${{ env.VERSION }}"
326+
git push
327+

‎Makefile‎

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,11 @@ init: ## Create .settings.json from .settings.json.example
6868
echo ".settings.json already exists. No changes made."; \
6969
fi
7070

71-
release: ## Run the release script
72-
@./scripts/release.sh
73-
74-
release-dirty: ## Run the release script with --dirty flag
75-
@./scripts/release.sh --dirty
71+
release: ## Create and push a release tag (triggers GitHub Actions release workflow)
72+
@./scripts/tag-release.sh
7673

77-
release-gh: ## Run the release script using GitHub Actions for Docker builds
78-
@./scripts/release.sh --github-actions
79-
80-
release-dirty-gh: ## Run the release script with --dirty flag using GitHub Actions
81-
@./scripts/release.sh --dirty --github-actions
74+
release-local: ## Emergency fallback: run full release locally (use only if GH Actions unavailable)
75+
@./scripts/release.sh
8276

8377
checkout-pr: ## Check out a PR locally: make checkout-pr pr=<pr-number>
8478
@if [ -z "$(pr)" ]; then \

0 commit comments

Comments
 (0)