From 313e897d88332decb6f0427c9f954da9f1a1a2f1 Mon Sep 17 00:00:00 2001 From: powderluv Date: Tue, 28 Apr 2026 13:08:11 -0700 Subject: [PATCH] Add release pipeline + bump workspace version to 0.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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//spur-cloud-{api,frontend}:` (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 --- .github/workflows/release.yml | 227 ++++++++++++++++++++++++++++++++++ Cargo.lock | 5 +- Cargo.toml | 2 +- 3 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..765f98d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,227 @@ +name: Release + +on: + push: + tags: ["v*"] + workflow_dispatch: + inputs: + tag: + description: "Release tag (e.g. v0.3.0)" + required: true + +permissions: + contents: write + packages: write + +env: + CARGO_TERM_COLOR: always + REGISTRY: ghcr.io + +jobs: + build-binary: + name: Build release binary + # ubuntu-22.04 → glibc 2.35, the binary will run on 22.04+ and on + # any newer Debian/RHEL with glibc >= 2.35. + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Install protobuf compiler + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + + - uses: dtolnay/rust-toolchain@stable + + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-release- + + - name: Build spur-cloud-api + run: cargo build --release --bin spur-cloud-api + + - uses: actions/upload-artifact@v4 + with: + name: spur-cloud-api-binary + path: target/release/spur-cloud-api + retention-days: 1 + + build-frontend: + name: Build frontend + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + working-directory: frontend + run: npm ci + + - name: Build frontend + working-directory: frontend + run: npm run build + + - uses: actions/upload-artifact@v4 + with: + name: spur-cloud-frontend-dist + path: frontend/dist/ + retention-days: 1 + + package: + name: Package release tarball + needs: [build-binary, build-frontend] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: spur-cloud-api-binary + path: ./bin + + - uses: actions/download-artifact@v4 + with: + name: spur-cloud-frontend-dist + path: ./frontend-dist + + - name: Package binaries + assets + run: | + set -e + VERSION="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" + DIST="spur-cloud-${VERSION}-linux-amd64" + mkdir -p "${DIST}/bin" "${DIST}/frontend" "${DIST}/etc" "${DIST}/deploy" + + cp ./bin/spur-cloud-api "${DIST}/bin/" + chmod +x "${DIST}/bin/spur-cloud-api" + + cp -r ./frontend-dist/. "${DIST}/frontend/" + + cp spur-cloud.toml.example "${DIST}/etc/spur-cloud.toml.example" + cp -r deploy/. "${DIST}/deploy/" + cp README.md LICENSE "${DIST}/" + + tar czf "${DIST}.tar.gz" "${DIST}" + sha256sum "${DIST}.tar.gz" > "${DIST}.tar.gz.sha256" + ls -lh "${DIST}.tar.gz" "${DIST}.tar.gz.sha256" + + - uses: actions/upload-artifact@v4 + with: + name: spur-cloud-release + path: | + spur-cloud-*.tar.gz + spur-cloud-*.tar.gz.sha256 + + verify: + name: Verify on ${{ matrix.name }} + needs: package + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - distro: "ubuntu:22.04" + name: "Ubuntu 22.04" + - distro: "ubuntu:24.04" + name: "Ubuntu 24.04" + - distro: "debian:12" + name: "Debian 12" + steps: + - uses: actions/download-artifact@v4 + with: + name: spur-cloud-release + + - name: Smoke test on ${{ matrix.name }} + run: | + set -e + tar xzf spur-cloud-*.tar.gz + BINDIR=$(ls -d spur-cloud-*/bin | head -1) + docker run --rm -v "$(pwd)/${BINDIR}:/test:ro" ${{ matrix.distro }} bash -c ' + set -e + echo "=== $(grep PRETTY_NAME /etc/os-release | cut -d\" -f2) ===" + echo "glibc: $(ldd --version 2>&1 | head -1)" + /test/spur-cloud-api --help > /dev/null + echo " spur-cloud-api: OK" + ' + + docker-images: + name: Build and push Docker images + needs: [build-binary, build-frontend] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: docker/setup-buildx-action@v3 + + - uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Resolve tag + id: vars + run: | + VERSION="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" + # ghcr.io requires lowercase repo names + REPO_LOWER="$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" + OWNER_LOWER="${REPO_LOWER%/*}" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "owner=${OWNER_LOWER}" >> "$GITHUB_OUTPUT" + + - name: Build and push API image + uses: docker/build-push-action@v5 + with: + context: . + file: deploy/docker/Dockerfile.api + push: true + tags: | + ${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-api:${{ steps.vars.outputs.version }} + ${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-api:latest + cache-from: type=gha,scope=api + cache-to: type=gha,mode=max,scope=api + + - name: Build and push frontend image + uses: docker/build-push-action@v5 + with: + context: . + file: deploy/docker/Dockerfile.frontend + push: true + tags: | + ${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-frontend:${{ steps.vars.outputs.version }} + ${{ env.REGISTRY }}/${{ steps.vars.outputs.owner }}/spur-cloud-frontend:latest + cache-from: type=gha,scope=frontend + cache-to: type=gha,mode=max,scope=frontend + + release: + name: Create GitHub Release + needs: [verify, docker-images] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: spur-cloud-release + + - name: Resolve tag + id: tag + run: echo "tag=${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" >> "$GITHUB_OUTPUT" + + - name: Create release + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="${{ steps.tag.outputs.tag }}" + gh release create "${TAG}" \ + --title "Spur Cloud ${TAG}" \ + --generate-notes \ + spur-cloud-*.tar.gz spur-cloud-*.tar.gz.sha256 diff --git a/Cargo.lock b/Cargo.lock index 1cbe9cf..6f4ecfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2757,7 +2757,7 @@ dependencies = [ [[package]] name = "spur-cloud-api" -version = "0.1.0" +version = "0.3.0" dependencies = [ "anyhow", "argon2", @@ -2776,6 +2776,7 @@ dependencies = [ "rand 0.8.5", "reqwest", "schemars", + "semver", "serde", "serde_json", "sha2", @@ -2797,7 +2798,7 @@ dependencies = [ [[package]] name = "spur-cloud-common" -version = "0.1.0" +version = "0.3.0" dependencies = [ "chrono", "serde", diff --git a/Cargo.toml b/Cargo.toml index 77b9f28..a56aaf8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ ] [workspace.package] -version = "0.1.0" +version = "0.3.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/ROCm/spur-cloud"