Skip to content

builder

builder #36

Workflow file for this run

name: builder
permissions:
contents: write
pull-requests: write
on:
workflow_dispatch:
inputs:
tag_name:
description: "Tag name (e.g. cli-v1.0.0, target-ttf-v1.0.0, abi-v1.0.0)"
required: true
# ── Tag conventions ───────────────────────────────────────────────────────────
# cli-v{version} → builds spfc (executable)
# target-{name}-v{version} → builds spfc-target-{name} (cdylib)
# abi-v{version} → generates spfc_abi.h via cbindgen only
jobs:
parse-tag:
name: Parse Tag
runs-on: ubuntu-latest
outputs:
component: ${{ steps.parse.outputs.component }}
type: ${{ steps.parse.outputs.type }}
version: ${{ steps.parse.outputs.version }}
sha: ${{ steps.parse.outputs.sha }}
target_name: ${{ steps.parse.outputs.target_name }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Parse tag → component metadata
id: parse
run: |
TAG="${{ inputs.tag_name }}"
SHA=$(git rev-list -n 1 "$TAG")
echo "sha=$SHA" >> $GITHUB_OUTPUT
if [[ "$TAG" == cli-* ]]; then
VERSION=$(echo "$TAG" | sed 's/cli-v//')
echo "component=spfc" >> $GITHUB_OUTPUT
echo "type=cli" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
elif [[ "$TAG" == target-*-* ]]; then
# target-ttf-v1.0.0 → prefix=ttf, version=1.0.0
PREFIX=$(echo "$TAG" | awk -F'-v' '{print $1}' | sed 's/target-//')
VERSION=$(echo "$TAG" | awk -F'-v' '{print $2}')
echo "component=spfc-target-$PREFIX" >> $GITHUB_OUTPUT
echo "type=target" >> $GITHUB_OUTPUT
echo "target_name=$PREFIX" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
elif [[ "$TAG" == abi-* ]]; then
echo "component=spfc-abi" >> $GITHUB_OUTPUT
echo "type=abi" >> $GITHUB_OUTPUT
fi
# ── ABI header generation (no cross-compile needed) ──────────────────────────
build-abi:
name: Generate ABI Header
needs: parse-tag
if: needs.parse-tag.outputs.type == 'abi'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install cbindgen
run: cargo install cbindgen --locked
- name: Generate header
run: |
mkdir -p artifacts
cbindgen --crate spfc-abi --output artifacts/spfc_abi.h --lang c --cpp-compat
- uses: actions/upload-artifact@v4
with:
name: abi-header
path: artifacts/
# ── Cross-compile matrix ──────────────────────────────────────────────────────
# macOS targets run on macos-latest: aws-lc-sys requires the real Apple SDK
# (CoreServices.h and friends) which zigbuild's bundled SDK doesn't ship.
# All other targets run on ubuntu-latest and cross-compile via cargo-zigbuild.
build:
name: Build ${{ needs.parse-tag.outputs.component }} (${{ matrix.target }})
needs: parse-tag
if: needs.parse-tag.outputs.type != 'abi'
strategy:
fail-fast: false
matrix:
include:
# ── Linux (cross-compiled from ubuntu via zigbuild) ──────────────────
- { target: x86_64-unknown-linux-gnu, os: ubuntu-latest }
# - { target: x86_64-unknown-linux-musl, os: ubuntu-latest }
- { target: aarch64-unknown-linux-gnu, os: ubuntu-latest }
# - { target: aarch64-unknown-linux-musl, os: ubuntu-latest }
- { target: i686-unknown-linux-gnu, os: ubuntu-latest }
- { target: armv7-unknown-linux-gnueabihf, os: ubuntu-latest }
# ── Windows (cross-compiled from ubuntu via zigbuild) ────────────────
- { target: x86_64-pc-windows-gnu, os: ubuntu-latest }
# ── FreeBSD (cross-compiled from ubuntu via zigbuild) ────────────────
- { target: x86_64-unknown-freebsd, os: ubuntu-latest }
# ── macOS (native runners — aws-lc-sys needs the real Apple SDK) ─────
- { target: x86_64-apple-darwin, os: macos-latest }
- { target: aarch64-apple-darwin, os: macos-latest }
runs-on: ${{ matrix.os }}
env:
COMPONENT: ${{ needs.parse-tag.outputs.component }}
TAG_NAME: ${{ inputs.tag_name }}
TARGET: ${{ matrix.target }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.parse-tag.outputs.sha }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
# zigbuild only needed on Linux runners
- name: Install Zig + cargo-zigbuild
if: matrix.os == 'ubuntu-latest'
run: |
pip install ziglang --quiet
cargo install cargo-zigbuild --locked
- name: Build
run: bash .ci/build.sh
- uses: actions/upload-artifact@v4
with:
name: artifact-${{ matrix.target }}
path: artifacts/*.tar.gz
# ── Collect and publish ───────────────────────────────────────────────────────
release:
name: Upload Release Assets
needs: [parse-tag, build]
if: always() && needs.build.result != 'cancelled'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: artifact-*
merge-multiple: true
path: artifacts/
- name: List collected artifacts
run: ls -lh artifacts/
- uses: softprops/action-gh-release@v1
with:
tag_name: ${{ inputs.tag_name }}
files: artifacts/*
release-abi:
name: Upload ABI Header
needs: [parse-tag, build-abi]
if: needs.parse-tag.outputs.type == 'abi'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: abi-header
path: artifacts/
- uses: softprops/action-gh-release@v1
with:
tag_name: ${{ inputs.tag_name }}
files: artifacts/*
# ── Registry update (target releases only) ───────────────────────────────────
update-registry:
name: Update Target Registry
needs: [parse-tag, release]
if: needs.parse-tag.outputs.type == 'target' && needs.release.result == 'success'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: main
- uses: julia-actions/setup-julia@v2
with:
version: "1"
- name: Update registry
run: julia .ci/update_registry.jl
env:
GH_TOKEN: ${{ secrets.TOKEN }}
TARGET_NAME: ${{ needs.parse-tag.outputs.target_name }}
VERSION: ${{ needs.parse-tag.outputs.version }}