mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-17 04:37:03 +00:00
The shipped aarch64-unknown-linux-musl binary segfaulted at startup on every arm64 runtime (Apple Silicon, Graviton, Ampere, Docker arm64). Root cause: a glibc-vs-musl .init_array calling-convention mismatch -- a C static library in the dep graph has an __attribute__((constructor)) that expects (argc, argv, envp) per glibc, but musl on aarch64 calls it with no args, so register garbage propagates into pointer arithmetic and faults before main runs. Switch the musl compile steps to cargo-zigbuild (zig 0.13.0). Zig's bundled cc + lld produce working static-PIE binaries for both musl targets, sidestepping Ubuntu musl-tools' -no-pie quirk and the init_array ordering that triggered the crash. Drop the CARGO_TARGET_* linker overrides and the musl-tools apt install -- zig handles both. bin/dev/docker-build.sh mirrors the same toolchain so the local Docker image build matches CI. Verified by running fabro version from the resulting arm64 image on ghcr.io/fabro-sh/dhi-alpine-base:3.23-dev, alpine:3.22, and debian:stable-slim -- all print the version banner with exit 0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
338 lines
12 KiB
YAML
338 lines
12 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
|
|
id-token: write
|
|
attestations: write
|
|
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:
|
|
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: Set up Rust
|
|
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
|
|
- name: Set up zig
|
|
if: matrix.musl
|
|
uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # v2.0.5
|
|
with:
|
|
version: 0.13.0
|
|
|
|
- name: Install cargo-zigbuild
|
|
if: matrix.musl
|
|
uses: taiki-e/install-action@773334c0e05d7e699e4d78234494308223f3a2cf # v2
|
|
with:
|
|
tool: cargo-zigbuild
|
|
|
|
- uses: taiki-e/install-action@773334c0e05d7e699e4d78234494308223f3a2cf # nextest
|
|
|
|
- name: Test
|
|
# aarch64-musl test runs have not been validated on the compile
|
|
# runner yet; shipping binary is exercised via Docker smoke tests.
|
|
# Re-enable after verifying the workspace passes on this target.
|
|
if: matrix.target != 'aarch64-unknown-linux-musl'
|
|
run: cargo nextest run --workspace --target ${{ matrix.target }} --release --status-level slow --profile ci
|
|
|
|
- name: Build (musl via cargo-zigbuild)
|
|
if: matrix.musl
|
|
run: cargo zigbuild --target ${{ matrix.target }} --release -p fabro-cli
|
|
|
|
- name: Build
|
|
if: ${{ !matrix.musl }}
|
|
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
|
|
|
|
- name: Attest build provenance
|
|
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
|
|
with:
|
|
subject-path: fabro-${{ matrix.target }}.tar.gz
|
|
|
|
- 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
|
|
id-token: write
|
|
attestations: 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@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
|
|
|
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
|
|
|
- uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- id: meta
|
|
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.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.') }}
|
|
|
|
- name: Build amd64 image for smoke test
|
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
|
with:
|
|
context: .
|
|
file: Dockerfile
|
|
platforms: linux/amd64
|
|
load: true
|
|
tags: fabro-smoke:amd64
|
|
|
|
- name: Smoke-test amd64 image
|
|
run: docker run --rm --platform linux/amd64 fabro-smoke:amd64 fabro version
|
|
|
|
- name: Build arm64 image for smoke test
|
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
|
with:
|
|
context: .
|
|
file: Dockerfile
|
|
platforms: linux/arm64
|
|
load: true
|
|
tags: fabro-smoke:arm64
|
|
|
|
- name: Smoke-test arm64 image
|
|
run: docker run --rm --platform linux/arm64 fabro-smoke:arm64 fabro version
|
|
|
|
- id: build
|
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
|
with:
|
|
context: .
|
|
file: Dockerfile
|
|
platforms: linux/amd64,linux/arm64
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
|
|
- name: Attest image provenance
|
|
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
|
|
with:
|
|
subject-name: ghcr.io/fabro-sh/fabro
|
|
subject-digest: ${{ steps.build.outputs.digest }}
|
|
push-to-registry: true
|
|
|
|
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)
|