Skip to content

Commit be5909c

Browse files
powderluvclaude
andauthored
Add release pipeline + bump workspace version to 0.3.0 (#50)
Adds a release workflow modeled on the spur repo: - Triggered on `v*` tag push or `workflow_dispatch` - Builds spur-cloud-api on Ubuntu 22.04 (glibc 2.35 → portable to 22.04+) - Builds the Vite frontend - Packages a `spur-cloud-{tag}-linux-amd64.tar.gz` containing the binary, frontend dist, deploy/docker manifests, deploy/k8s manifests, README, LICENSE, and an example config - Smoke-tests `spur-cloud-api --help` on Ubuntu 22.04, 24.04, Debian 12 - Builds and pushes Docker images for the API and frontend to `ghcr.io/<owner>/spur-cloud-{api,frontend}:<tag>` (and `:latest`) - Creates a GitHub release with auto-generated notes and the tarball Bumps workspace version 0.1.0 → 0.3.0 to align with the upcoming release tag (matches the release naming pattern; spur-cloud was at v0.1.3 in tagged releases but the workspace version has not been bumped before). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent 52e9c89 commit be5909c

3 files changed

Lines changed: 231 additions & 3 deletions

File tree

.github/workflows/release.yml

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: "Release tag (e.g. v0.3.0)"
10+
required: true
11+
12+
permissions:
13+
contents: write
14+
packages: write
15+
16+
env:
17+
CARGO_TERM_COLOR: always
18+
REGISTRY: ghcr.io
19+
20+
jobs:
21+
build-binary:
22+
name: Build release binary
23+
# ubuntu-22.04 → glibc 2.35, the binary will run on 22.04+ and on
24+
# any newer Debian/RHEL with glibc >= 2.35.
25+
runs-on: ubuntu-22.04
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- name: Install protobuf compiler
30+
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
31+
32+
- uses: dtolnay/rust-toolchain@stable
33+
34+
- uses: actions/cache@v4
35+
with:
36+
path: |
37+
~/.cargo/registry
38+
~/.cargo/git
39+
target
40+
key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}
41+
restore-keys: |
42+
${{ runner.os }}-cargo-release-
43+
44+
- name: Build spur-cloud-api
45+
run: cargo build --release --bin spur-cloud-api
46+
47+
- uses: actions/upload-artifact@v4
48+
with:
49+
name: spur-cloud-api-binary
50+
path: target/release/spur-cloud-api
51+
retention-days: 1
52+
53+
build-frontend:
54+
name: Build frontend
55+
runs-on: ubuntu-latest
56+
steps:
57+
- uses: actions/checkout@v4
58+
59+
- uses: actions/setup-node@v4
60+
with:
61+
node-version: "20"
62+
cache: "npm"
63+
cache-dependency-path: frontend/package-lock.json
64+
65+
- name: Install dependencies
66+
working-directory: frontend
67+
run: npm ci
68+
69+
- name: Build frontend
70+
working-directory: frontend
71+
run: npm run build
72+
73+
- uses: actions/upload-artifact@v4
74+
with:
75+
name: spur-cloud-frontend-dist
76+
path: frontend/dist/
77+
retention-days: 1
78+
79+
package:
80+
name: Package release tarball
81+
needs: [build-binary, build-frontend]
82+
runs-on: ubuntu-latest
83+
steps:
84+
- uses: actions/checkout@v4
85+
86+
- uses: actions/download-artifact@v4
87+
with:
88+
name: spur-cloud-api-binary
89+
path: ./bin
90+
91+
- uses: actions/download-artifact@v4
92+
with:
93+
name: spur-cloud-frontend-dist
94+
path: ./frontend-dist
95+
96+
- name: Package binaries + assets
97+
run: |
98+
set -e
99+
VERSION="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}"
100+
DIST="spur-cloud-${VERSION}-linux-amd64"
101+
mkdir -p "${DIST}/bin" "${DIST}/frontend" "${DIST}/etc" "${DIST}/deploy"
102+
103+
cp ./bin/spur-cloud-api "${DIST}/bin/"
104+
chmod +x "${DIST}/bin/spur-cloud-api"
105+
106+
cp -r ./frontend-dist/. "${DIST}/frontend/"
107+
108+
cp spur-cloud.toml.example "${DIST}/etc/spur-cloud.toml.example"
109+
cp -r deploy/. "${DIST}/deploy/"
110+
cp README.md LICENSE "${DIST}/"
111+
112+
tar czf "${DIST}.tar.gz" "${DIST}"
113+
sha256sum "${DIST}.tar.gz" > "${DIST}.tar.gz.sha256"
114+
ls -lh "${DIST}.tar.gz" "${DIST}.tar.gz.sha256"
115+
116+
- uses: actions/upload-artifact@v4
117+
with:
118+
name: spur-cloud-release
119+
path: |
120+
spur-cloud-*.tar.gz
121+
spur-cloud-*.tar.gz.sha256
122+
123+
verify:
124+
name: Verify on ${{ matrix.name }}
125+
needs: package
126+
runs-on: ubuntu-latest
127+
strategy:
128+
fail-fast: false
129+
matrix:
130+
include:
131+
- distro: "ubuntu:22.04"
132+
name: "Ubuntu 22.04"
133+
- distro: "ubuntu:24.04"
134+
name: "Ubuntu 24.04"
135+
- distro: "debian:12"
136+
name: "Debian 12"
137+
steps:
138+
- uses: actions/download-artifact@v4
139+
with:
140+
name: spur-cloud-release
141+
142+
- name: Smoke test on ${{ matrix.name }}
143+
run: |
144+
set -e
145+
tar xzf spur-cloud-*.tar.gz
146+
BINDIR=$(ls -d spur-cloud-*/bin | head -1)
147+
docker run --rm -v "$(pwd)/${BINDIR}:/test:ro" ${{ matrix.distro }} bash -c '
148+
set -e
149+
echo "=== $(grep PRETTY_NAME /etc/os-release | cut -d\" -f2) ==="
150+
echo "glibc: $(ldd --version 2>&1 | head -1)"
151+
/test/spur-cloud-api --help > /dev/null
152+
echo " spur-cloud-api: OK"
153+
'
154+
155+
docker-images:
156+
name: Build and push Docker images
157+
needs: [build-binary, build-frontend]
158+
runs-on: ubuntu-latest
159+
steps:
160+
- uses: actions/checkout@v4
161+
162+
- uses: docker/setup-buildx-action@v3
163+
164+
- uses: docker/login-action@v3
165+
with:
166+
registry: ${{ env.REGISTRY }}
167+
username: ${{ github.actor }}
168+
password: ${{ secrets.GITHUB_TOKEN }}
169+
170+
- name: Resolve tag
171+
id: vars
172+
run: |
173+
VERSION="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}"
174+
# ghcr.io requires lowercase repo names
175+
REPO_LOWER="$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')"
176+
OWNER_LOWER="${REPO_LOWER%/*}"
177+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
178+
echo "owner=${OWNER_LOWER}" >> "$GITHUB_OUTPUT"
179+
180+
- name: Build and push API image
181+
uses: docker/build-push-action@v5
182+
with:
183+
context: .
184+
file: deploy/docker/Dockerfile.api
185+
push: true
186+
tags: |
187+
${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-api:${{ steps.vars.outputs.version }}
188+
${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-api:latest
189+
cache-from: type=gha,scope=api
190+
cache-to: type=gha,mode=max,scope=api
191+
192+
- name: Build and push frontend image
193+
uses: docker/build-push-action@v5
194+
with:
195+
context: .
196+
file: deploy/docker/Dockerfile.frontend
197+
push: true
198+
tags: |
199+
${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-frontend:${{ steps.vars.outputs.version }}
200+
${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-frontend:latest
201+
cache-from: type=gha,scope=frontend
202+
cache-to: type=gha,mode=max,scope=frontend
203+
204+
release:
205+
name: Create GitHub Release
206+
needs: [verify, docker-images]
207+
runs-on: ubuntu-latest
208+
steps:
209+
- uses: actions/checkout@v4
210+
211+
- uses: actions/download-artifact@v4
212+
with:
213+
name: spur-cloud-release
214+
215+
- name: Resolve tag
216+
id: tag
217+
run: echo "tag=${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" >> "$GITHUB_OUTPUT"
218+
219+
- name: Create release
220+
env:
221+
GH_TOKEN: ${{ github.token }}
222+
run: |
223+
TAG="${{ steps.tag.outputs.tag }}"
224+
gh release create "${TAG}" \
225+
--title "Spur Cloud ${TAG}" \
226+
--generate-notes \
227+
spur-cloud-*.tar.gz spur-cloud-*.tar.gz.sha256

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ members = [
66
]
77

88
[workspace.package]
9-
version = "0.1.0"
9+
version = "0.3.0"
1010
edition = "2021"
1111
license = "Apache-2.0"
1212
repository = "https://github.com/ROCm/spur-cloud"

0 commit comments

Comments
 (0)