ci(release): don't let prerelease tags clobber :latest / Homebrew / stable

A v*-rc* tag triggered the same release pipeline as a stable tag, which
would publish a normal release, overwrite ghcr.io/0xmassi/webclaw:latest,
and repoint the Homebrew formula at the rc — shipping a prerelease to every
stable Docker/brew user. Guard all three on the SemVer prerelease hyphen:

- release: add --prerelease for hyphenated tags
- docker: still push :${tag} (testable rc image) but only move :latest for stable
- homebrew: skip entirely for prereleases

Lets us cut rc tags (e.g. to validate the new musl build job) without
touching stable users.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Valerio 2026-06-27 14:45:49 +02:00
parent 1d49b4404e
commit d5d58ab612

View file

@ -176,11 +176,16 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag="${GITHUB_REF#refs/tags/}"
# SemVer prerelease tags (e.g. v1.2.3-rc1) contain a hyphen — mark
# them as prereleases so they never surface as the stable release.
prerelease=""
case "$tag" in *-*) prerelease="--prerelease" ;; esac
gh release create "$tag" \
artifacts/*.tar.gz \
artifacts/*.zip \
artifacts/SHA256SUMS \
--repo "$GITHUB_REPOSITORY" \
$prerelease \
--generate-notes
docker:
@ -239,18 +244,25 @@ jobs:
- name: Build and push
run: |
tag="${{ steps.tag.outputs.tag }}"
# Only move :latest for stable tags. Prereleases (hyphenated, e.g.
# v1.2.3-rc1) still publish :${tag} for testing but must not clobber
# :latest.
latest=""
case "$tag" in *-*) ;; *) latest="-t ghcr.io/0xmassi/webclaw:latest" ;; esac
docker buildx build -f Dockerfile.ci \
--platform linux/amd64,linux/arm64 \
--provenance=false --sbom=false \
-t "ghcr.io/0xmassi/webclaw:${tag}" \
-t ghcr.io/0xmassi/webclaw:latest \
$latest \
--push .
homebrew:
name: Update Homebrew
needs: [release, docker]
# Runs once Docker succeeds, on both tag push and manual re-publish.
if: ${{ always() && needs.docker.result == 'success' }}
# Skipped for prereleases (hyphenated tags like v1.2.3-rc1) so the formula
# keeps pointing at the latest stable, never an rc.
if: ${{ always() && needs.docker.result == 'success' && !contains(github.event.inputs.tag || github.ref_name, '-') }}
runs-on: ubuntu-latest
permissions:
contents: read