Files
ashvale-station/.github/workflows/image.yml
T
kemal 4eefd8816b Fix image build: pi-gen wants qemu-user-binfmt, not qemu-user-static
The first CI build failed in under a second with 'Required dependencies not
installed: qemu-user-binfmt'. pi-gen checks for the binfmt handler rather than
the emulator binary, and I had guessed the package name. The list now comes
from pi-gen's own depends file at the pinned commit, and the workflow asserts
the aarch64 handler is registered before spending an hour discovering it is
not.
2026-08-16 18:34:38 +01:00

119 lines
4.5 KiB
YAML

name: Pi image
# Builds a ready-to-flash Raspberry Pi OS Lite image with Ashvale Station
# preinstalled, and attaches it to a GitHub Release.
#
# Built in CI rather than on a laptop on purpose. The artifact is something
# other people flash onto their own hardware, so it should be reproducible from
# a public log by anyone who wants to check what went into it, rather than
# appearing from a machine only I can see.
on:
workflow_dispatch:
inputs:
publish:
description: "Attach the image to a release"
type: boolean
default: false
push:
tags:
- "v*"
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 180
steps:
- name: Check out Ashvale
uses: actions/checkout@v4
with:
path: ashvale
# pi-gen needs about 10 GB and a stock runner does not have it spare.
- name: Reclaim disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \
/usr/local/share/boost "$AGENT_TOOLSDIRECTORY"
df -h / | tail -1
- name: Install build dependencies
run: |
sudo apt-get update
# Taken from pi-gen's own `depends` file at the pinned commit rather
# than guessed. My first attempt installed qemu-user-static, and
# pi-gen wants qemu-user-binfmt: it checks for the binfmt handler, not
# the emulator binary, and failed in under a second.
sudo apt-get install -y --no-install-recommends \
quilt parted coreutils qemu-user-binfmt debootstrap zerofree zip \
dosfstools e2fsprogs libcap2-bin libarchive-tools grep rsync \
xz-utils curl xxd file git kmod bc gpg pigz arch-test
# Prove the handler is actually registered before spending an hour.
test -f /proc/sys/fs/binfmt_misc/qemu-aarch64 \
|| sudo systemctl restart systemd-binfmt || true
ls /proc/sys/fs/binfmt_misc/ | head
# Pinned to a commit, not a branch. An image other people flash should not
# change because an upstream branch moved between builds.
- name: Check out pi-gen
uses: actions/checkout@v4
with:
repository: RPi-Distro/pi-gen
ref: ca8aeed0ae300c2a89f55ce9617d5f96a27e99e5 # arm64 branch, pinned
path: pi-gen
fetch-depth: 1
- name: Assemble the custom stage
run: |
cp ashvale/deploy/pi-image/config pi-gen/config
cp -r ashvale/deploy/pi-image/stage-ashvale pi-gen/stage-ashvale
# Lite only: everything from stage3 up is the desktop.
touch pi-gen/stage3/SKIP pi-gen/stage4/SKIP pi-gen/stage5/SKIP
touch pi-gen/stage4/SKIP_IMAGES pi-gen/stage5/SKIP_IMAGES
# stage2 stops exporting so ours is the only image produced.
rm -f pi-gen/stage2/EXPORT_IMAGE
echo "ASHVALE_SRC=${GITHUB_WORKSPACE}/ashvale" >> pi-gen/config
echo "--- config ---" && cat pi-gen/config
- name: Build
working-directory: pi-gen
run: sudo -E ./build.sh
- name: Collect artifact
id: artifact
run: |
IMG=$(find pi-gen/deploy -name '*.img.xz' | head -1)
test -n "$IMG" || { echo "no image produced"; ls -R pi-gen/deploy; exit 1; }
mkdir -p out && mv "$IMG" out/
cd out
NAME=$(basename *.img.xz)
sha256sum "$NAME" > "$NAME.sha256"
echo "name=$NAME" >> "$GITHUB_OUTPUT"
ls -lh
# A release asset is capped at 2 GB; Lite compresses to well under that,
# but fail loudly here rather than at upload time.
SIZE=$(stat -c%s "$NAME")
echo "compressed size: $((SIZE/1024/1024)) MiB"
test "$SIZE" -lt 2000000000 || { echo "image exceeds the 2 GB release limit"; exit 1; }
- name: Upload as a workflow artifact
uses: actions/upload-artifact@v4
with:
name: ashvale-pi-image
path: out/*
retention-days: 14
- name: Attach to release
if: startsWith(github.ref, 'refs/tags/') || inputs.publish
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${GITHUB_REF_NAME}"
gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1 \
|| gh release create "$TAG" --repo "$GITHUB_REPOSITORY" \
--title "$TAG" --notes "Ashvale Station image for Raspberry Pi."
gh release upload "$TAG" out/* --repo "$GITHUB_REPOSITORY" --clobber