fabro/.github/workflows/release.yml
Bryan Helmkamp 01dfe2a4fe
ci(release): skip tests on aarch64-musl runner
The aarch64-musl binary SIGSEGVs at startup on the ubuntu-24.04-arm
runner (empty stdout/stderr, non-zero exit), so every test that
spawns 'fabro server start' fails. The shipped binary runs natively
on Alpine via the Docker image, so skip the test step here and rely
on x86_64-musl + both gnu targets for test coverage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 13:04:14 -04:00

289 lines
10 KiB
YAML

name: Release
on:
push:
tags:
- "v*"
permissions: {}
env:
CARGO_TERM_COLOR: always
SEGMENT_BASE_URL: ${{ vars.SEGMENT_BASE_URL }}
SEGMENT_WRITE_KEY: ${{ secrets.SEGMENT_WRITE_KEY }}
jobs:
verify-spa:
name: Verify SPA assets
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
no-cache: true
- run: bun install
- run: scripts/refresh-fabro-spa.sh
- run: git diff --exit-code -- lib/crates/fabro-spa/assets
compile:
name: Compile (${{ matrix.target }})
needs: verify-spa
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
runner: macos-15-xlarge
- target: x86_64-unknown-linux-gnu
runner: ubuntu-24.04-x86-32-cores
- target: aarch64-unknown-linux-gnu
runner: ubuntu-22.04-arm-32-cores
- target: x86_64-unknown-linux-musl
runner: ubuntu-24.04-x86-32-cores
musl: true
- target: aarch64-unknown-linux-musl
runner: ubuntu-24.04-arm-32-cores
musl: true
env:
CC_x86_64_unknown_linux_musl: musl-gcc
CC_aarch64_unknown_linux_musl: musl-gcc
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
LIBZ_SYS_STATIC: "1"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install Linux build tools
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev
- name: Install musl toolchain
if: matrix.musl
run: sudo apt-get install -y musl-tools
- name: Set up Rust
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
with:
targets: ${{ matrix.target }}
- uses: taiki-e/install-action@773334c0e05d7e699e4d78234494308223f3a2cf # nextest
- name: Test
# aarch64-musl binaries SIGSEGV at startup when launched on the
# ubuntu-24.04-arm runner (glibc host + retrofitted musl loader).
# The shipped binary targets Alpine via the Docker image, which
# runs natively. x86_64-musl tests still run for coverage.
if: matrix.target != 'aarch64-unknown-linux-musl'
run: cargo nextest run --workspace --target ${{ matrix.target }} --release --status-level slow --profile ci
- name: Build
run: cargo build --target ${{ matrix.target }} --release -p fabro-cli
- name: Package
run: |
mkdir fabro-${{ matrix.target }}
cp target/${{ matrix.target }}/release/fabro fabro-${{ matrix.target }}/
tar czf fabro-${{ matrix.target }}.tar.gz fabro-${{ matrix.target }}
shasum -a 256 fabro-${{ matrix.target }}.tar.gz > fabro-${{ matrix.target }}.tar.gz.sha256
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: artifacts-fabro-${{ matrix.target }}
path: |
fabro-${{ matrix.target }}.tar.gz
fabro-${{ matrix.target }}.tar.gz.sha256
release:
name: Release
needs: compile
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: target/distrib
pattern: artifacts-fabro-*
merge-multiple: true
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ github.ref_name }}
run: |
PRERELEASE_FLAG=""
if [[ "$TAG_NAME" == *-* ]]; then
PRERELEASE_FLAG="--prerelease"
fi
gh release create "$TAG_NAME" target/distrib/* --generate-notes $PRERELEASE_FLAG
docker:
name: Docker image
needs: compile
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: target/distrib
pattern: artifacts-fabro-*-linux-musl
merge-multiple: true
- name: Stage binaries for Docker build context
run: |
for target in x86_64-unknown-linux-musl aarch64-unknown-linux-musl; do
case "$target" in
x86_64-*) arch=amd64 ;;
aarch64-*) arch=arm64 ;;
esac
mkdir -p "docker-context/$arch"
tar -xzf "target/distrib/fabro-${target}.tar.gz" -C target/distrib
cp "target/distrib/fabro-${target}/fabro" "docker-context/$arch/fabro"
done
- uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.10.0
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: ghcr.io/fabro-sh/fabro
tags: |
type=match,pattern=v(.*),group=1
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') }}
type=raw,value=nightly,enable=${{ contains(github.ref_name, '-nightly.') }}
- uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
update-homebrew:
name: Update Homebrew Formula
needs: release
if: ${{ !contains(github.ref_name, '-') }}
runs-on: ubuntu-latest
environment: release
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: target/distrib
pattern: artifacts-fabro-*
merge-multiple: true
- name: Generate and push formula
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
VERSION="${TAG_NAME#v}"
SHA_AARCH64_DARWIN=$(awk '{print $1}' target/distrib/fabro-aarch64-apple-darwin.tar.gz.sha256)
SHA_X86_64_LINUX=$(awk '{print $1}' target/distrib/fabro-x86_64-unknown-linux-gnu.tar.gz.sha256)
SHA_AARCH64_LINUX=$(awk '{print $1}' target/distrib/fabro-aarch64-unknown-linux-gnu.tar.gz.sha256)
sed \
-e "s/{{VERSION}}/$VERSION/g" \
-e "s/{{SHA_AARCH64_DARWIN}}/$SHA_AARCH64_DARWIN/g" \
-e "s/{{SHA_X86_64_LINUX}}/$SHA_X86_64_LINUX/g" \
-e "s/{{SHA_AARCH64_LINUX}}/$SHA_AARCH64_LINUX/g" \
installer/fabro.rb.template > fabro.rb
git clone https://x-access-token:${GH_TOKEN}@github.com/fabro-sh/homebrew-tap.git tap
cp fabro.rb tap/Formula/fabro.rb
jq --arg version "$VERSION" --arg tag "$TAG_NAME" \
'.stable = {version: $version, tag: $tag}' \
tap/versions.json > tap/versions.json.tmp
mv tap/versions.json.tmp tap/versions.json
cd tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/fabro.rb versions.json
git diff --cached --quiet || (git commit -m "Update fabro to ${TAG_NAME}" && git push)
update-homebrew-nightly:
name: Update Homebrew Nightly Formula
needs: release
if: ${{ contains(github.ref_name, '-') }}
runs-on: ubuntu-latest
environment: release
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: target/distrib
pattern: artifacts-fabro-*
merge-multiple: true
- name: Generate and push nightly formula
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
TAG_NAME: ${{ github.ref_name }}
run: |
VERSION="${TAG_NAME#v}"
SHA_AARCH64_DARWIN=$(awk '{print $1}' target/distrib/fabro-aarch64-apple-darwin.tar.gz.sha256)
SHA_X86_64_LINUX=$(awk '{print $1}' target/distrib/fabro-x86_64-unknown-linux-gnu.tar.gz.sha256)
SHA_AARCH64_LINUX=$(awk '{print $1}' target/distrib/fabro-aarch64-unknown-linux-gnu.tar.gz.sha256)
sed \
-e "s/{{VERSION}}/$VERSION/g" \
-e "s/{{SHA_AARCH64_DARWIN}}/$SHA_AARCH64_DARWIN/g" \
-e "s/{{SHA_X86_64_LINUX}}/$SHA_X86_64_LINUX/g" \
-e "s/{{SHA_AARCH64_LINUX}}/$SHA_AARCH64_LINUX/g" \
installer/fabro-nightly.rb.template > fabro-nightly.rb
git clone https://x-access-token:${GH_TOKEN}@github.com/fabro-sh/homebrew-tap.git tap
cp fabro-nightly.rb tap/Formula/fabro-nightly.rb
jq --arg version "$VERSION" --arg tag "$TAG_NAME" \
'.nightly = {version: $version, tag: $tag}' \
tap/versions.json > tap/versions.json.tmp
mv tap/versions.json.tmp tap/versions.json
cd tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/fabro-nightly.rb versions.json
git diff --cached --quiet || (git commit -m "Update fabro-nightly to ${TAG_NAME}" && git push)