Skip to content

feat(release): single nix-backed build per target (#18) #15

feat(release): single nix-backed build per target (#18)

feat(release): single nix-backed build per target (#18) #15

Workflow file for this run

name: release
on:
push:
tags: ["v*"]
workflow_dispatch:
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
jobs:
build:
name: ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
runner: ubuntu-24.04
builder: nix
- target: aarch64-unknown-linux-gnu
runner: ubuntu-24.04-arm
builder: nix
- target: x86_64-pc-windows-gnu
runner: ubuntu-24.04
builder: rustup
bin: abgen.exe
- target: aarch64-pc-windows-gnullvm
runner: ubuntu-24.04
builder: rustup
bin: abgen.exe
cargo_flags: --features rquickjs/bindgen
- target: aarch64-apple-darwin
runner: macos-15
builder: rustup
bin: abgen
- target: x86_64-apple-darwin
runner: macos-15-intel
builder: rustup
bin: abgen
steps:
- if: matrix.builder == 'nix'
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
- name: setup (checkout + toolchains)
run: |
git init -q .
git remote add origin "https://github.com/$GITHUB_REPOSITORY"
git fetch -q --depth 1 origin "$GITHUB_SHA"
git checkout -q FETCH_HEAD
echo "SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)" >> "$GITHUB_ENV"
if [ "${{ matrix.builder }}" = "nix" ]; then
exit 0
fi
(
if ! command -v rustup >/dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs \
| sh -s -- -y --default-toolchain none --profile minimal --no-modify-path
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.cargo/bin:$PATH"
fi
rustup toolchain install 1.97.1 --profile minimal --no-self-update
rustup default 1.97.1
rustup target add ${{ matrix.target }}
) > /tmp/rustup.log 2>&1 &
rustup_pid=$!
if [ "${{ matrix.target }}" = "x86_64-pc-windows-gnu" ]; then
sudo apt-get update
sudo apt-get install -y --no-install-recommends g++-mingw-w64-x86-64-posix cmake
cat > /tmp/mingw-toolchain.cmake <<'EOF'
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
EOF
{
echo "CMAKE_TOOLCHAIN_FILE=/tmp/mingw-toolchain.cmake"
echo "CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc-posix"
echo "CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc-posix"
echo "CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++-posix"
echo "AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar"
} >> "$GITHUB_ENV"
fi
if [ "${{ matrix.target }}" = "aarch64-pc-windows-gnullvm" ]; then
curl -fsSL -o llvm-mingw.tar.xz https://github.com/mstorsjo/llvm-mingw/releases/download/20260721/llvm-mingw-20260721-ucrt-ubuntu-22.04-x86_64.tar.xz
echo "4a9fd7ac5bda8a0a514f33c4ad7864a76e58c56ed958be18221c5ca0ac0a2b10 llvm-mingw.tar.xz" | sha256sum -c
sudo tar -xJf llvm-mingw.tar.xz -C /opt && rm llvm-mingw.tar.xz
cat > /tmp/aarch64-mingw-toolchain.cmake <<'EOF'
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-w64-mingw32-clang)
set(CMAKE_CXX_COMPILER aarch64-w64-mingw32-clang++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
EOF
sudo rm /opt/llvm-mingw-20260721-ucrt-ubuntu-22.04-x86_64/aarch64-w64-mingw32/lib/libc++.dll.a \
/opt/llvm-mingw-20260721-ucrt-ubuntu-22.04-x86_64/aarch64-w64-mingw32/lib/libunwind.dll.a
echo "/opt/llvm-mingw-20260721-ucrt-ubuntu-22.04-x86_64/bin" >> "$GITHUB_PATH"
{
echo "CMAKE_TOOLCHAIN_FILE=/tmp/aarch64-mingw-toolchain.cmake"
echo "CARGO_TARGET_AARCH64_PC_WINDOWS_GNULLVM_LINKER=aarch64-w64-mingw32-clang"
echo "CC_aarch64_pc_windows_gnullvm=aarch64-w64-mingw32-clang"
echo "CXX_aarch64_pc_windows_gnullvm=aarch64-w64-mingw32-clang++"
echo "AR_aarch64_pc_windows_gnullvm=aarch64-w64-mingw32-ar"
echo "BINDGEN_EXTRA_CLANG_ARGS=--target=aarch64-w64-mingw32 --sysroot=/opt/llvm-mingw-20260721-ucrt-ubuntu-22.04-x86_64/aarch64-w64-mingw32"
} >> "$GITHUB_ENV"
fi
wait "$rustup_pid" || { cat /tmp/rustup.log; exit 1; }
cat /tmp/rustup.log
rustflags="--remap-path-prefix $PWD=/build --remap-path-prefix $HOME=/home"
if [ "${{ matrix.target }}" = "x86_64-pc-windows-gnu" ]; then
rustflags="$rustflags -C link-arg=-Wl,--no-insert-timestamp"
fi
if [ "${{ matrix.target }}" = "aarch64-pc-windows-gnullvm" ]; then
rustflags="$rustflags -C target-feature=+crt-static -C link-arg=-Wl,--no-insert-timestamp"
fi
{
echo "RUSTFLAGS=$rustflags"
echo "CFLAGS=-ffile-prefix-map=$PWD=/build"
echo "CXXFLAGS=-ffile-prefix-map=$PWD=/build"
} >> "$GITHUB_ENV"
- if: matrix.builder == 'nix'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: /tmp/nix-deps-cache
key: nix-deps-${{ matrix.target }}-${{ hashFiles('Cargo.lock', 'Cargo.toml', 'crate/Cargo.toml', 'flake.lock', 'flake.nix', 'rust-toolchain.toml') }}
- if: matrix.builder == 'rustup'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: cargo-${{ matrix.target }}-1.97.1-${{ hashFiles('Cargo.lock') }}
restore-keys: cargo-${{ matrix.target }}-1.97.1-
- name: build
run: |
if [ "${{ matrix.builder }}" = "nix" ]; then
flags="--extra-experimental-features nix-command --extra-experimental-features flakes"
if [ -d /tmp/nix-deps-cache ]; then
nix copy $flags --from file:///tmp/nix-deps-cache --all --no-check-sigs || true
fi
nix build .#default --print-build-logs $flags
deps=$(nix build .#default.cargoArtifacts --print-out-paths --no-link $flags)
nix copy $flags --to file:///tmp/nix-deps-cache "$deps"
else
cargo build --release --locked --target ${{ matrix.target }} ${{ matrix.cargo_flags }} --bin abgen
fi
- name: package, smoke test, publish
env:
GH_TOKEN: ${{ github.token }}
run: |
dist="abgen-${GITHUB_REF_NAME:-dev}-${{ matrix.target }}"
mkdir -p "$dist/shader"
cp -R template "$dist/template"
cp crate/shader/scene_ignore_windows "$dist/shader/"
cp LICENSE README.md "$dist/"
if [ "${{ matrix.builder }}" = "nix" ]; then
mkdir -p "$dist/bin" "$dist/lib"
install -m755 result/bin/abgen "$dist/bin/abgen.bin"
for lib in $(ldd result/bin/abgen | awk '$3 ~ /^\// {print $3}'); do
install -m644 "$lib" "$dist/lib/"
done
interp=$(readelf -l result/bin/abgen | sed -n 's/.*interpreter: \(.*\)]/\1/p')
install -m755 "$interp" "$dist/lib/ld.so"
cat > "$dist/abgen" <<'EOF'
#!/bin/sh
here="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)"
export ABGEN_ROOT="${ABGEN_ROOT:-$here}"
export ABGEN_SHADER_BUNDLE="${ABGEN_SHADER_BUNDLE:-$here/shader/scene_ignore_windows}"
exec "$here/lib/ld.so" --library-path "$here/lib" "$here/bin/abgen.bin" "$@"
EOF
chmod 755 "$dist/abgen"
else
cp "target/${{ matrix.target }}/release/${{ matrix.bin }}" "$dist/"
if [ "${{ matrix.target }}" = "x86_64-pc-windows-gnu" ]; then
for dll in libstdc++-6.dll libgcc_s_seh-1.dll libwinpthread-1.dll; do
cp "$(x86_64-w64-mingw32-g++-posix -print-file-name=$dll)" "$dist/"
done
fi
fi
TAR=tar; command -v gtar >/dev/null && TAR=gtar
"$TAR" --sort=name --owner=0 --group=0 --numeric-owner \
--mtime="@${SOURCE_DATE_EPOCH}" -czf "$dist.tar.gz" "$dist"
shasum -a 256 "$dist.tar.gz" > "$dist.tar.gz.sha256"
if ! echo "${{ matrix.target }}" | grep -q windows; then
rm -rf /tmp/smoke && mkdir /tmp/smoke
tar -xzf "$dist.tar.gz" -C /tmp/smoke
(
cd "/tmp/smoke/$dist"
./abgen --version
HTTP_SERVER_PORT=5199 ./abgen &
server=$!
for _ in $(seq 1 40); do
curl -sf http://127.0.0.1:5199/readyz && ok=1 && break
sleep 0.5
done
kill "$server" || true
test "${ok:-0}" = 1
)
fi
case "$GITHUB_REF" in refs/tags/v*) ;; *) exit 0 ;; esac
gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1 \
|| gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" \
--title "abgen $GITHUB_REF_NAME" --notes-file .github/release-notes.md \
|| gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null
gh release upload "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --clobber \
"$dist.tar.gz" "$dist.tar.gz.sha256"
publish:
needs: build
runs-on: ubuntu-24.04
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
id-token: write
steps:
- name: verify, checksums, npm
env:
GH_TOKEN: ${{ github.token }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
git init -q .
git remote add origin "https://github.com/$GITHUB_REPOSITORY"
git fetch -q --depth 1 origin "$GITHUB_SHA"
git checkout -q FETCH_HEAD
gh release download "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" \
--pattern 'abgen-*.tar.gz' --pattern 'abgen-*.tar.gz.sha256' -D dist
cd dist
test "$(ls ./*.tar.gz | wc -l)" -eq 6
sha256sum -c ./*.sha256
cat ./*.sha256 > SHA256SUMS.txt
cat SHA256SUMS.txt
gh release upload "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --clobber SHA256SUMS.txt
for f in ./*.sha256; do
gh release delete-asset "$GITHUB_REF_NAME" "$(basename "$f")" --repo "$GITHUB_REPOSITORY" --yes
done
cd ..
if [ -z "$NODE_AUTH_TOKEN" ]; then
echo "NPM_TOKEN secret not configured - skipping npm publish"
exit 0
fi
printf '//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}\n' > "$HOME/.npmrc"
bash npm/publish.sh "${GITHUB_REF_NAME#v}" dist