From eafa4b6e264eeef2c703a2cfe8a57a89f88e9c6f Mon Sep 17 00:00:00 2001 From: NeilClack Date: Sun, 4 Oct 2026 18:34:31 -0500 Subject: [PATCH] Split raspberry pi build into a separate workflow --- .gitea/workflows/build-rpi.yml | 128 +++++++++++++++++++++++++++++++++ .gitea/workflows/build.yml | 23 ++---- 2 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 .gitea/workflows/build-rpi.yml diff --git a/.gitea/workflows/build-rpi.yml b/.gitea/workflows/build-rpi.yml new file mode 100644 index 0000000..61c5c7d --- /dev/null +++ b/.gitea/workflows/build-rpi.yml @@ -0,0 +1,128 @@ +# One build workflow per hardware family, identical on every branch — do not +# add per-branch copies. build-x86.yaml is the same file with a different matrix. +# +# The branch/ref selects the channel, nothing else does: the flake's `channel` +# block picks the app input, Attic repo, and upgrade ref, so the same config +# names build dev images on `dev` and prod images on `main`. +# +# Trigger model: +# * push to `dev` -> build every development image +# * new git tag -> build every production image (tags live on main) +# * manual dispatch -> build the channel of the selected branch +# +# This file builds the Raspberry Pi variant: +# Raspberry Pi -> .config.system.build.sdImage +# `orion-lxc` emulates aarch64-linux, so this runs on the same runner. +name: Build Kiosk Image (Raspberry Pi) + +on: + workflow_dispatch: + push: + branches: + - dev + tags: + - "*" + +env: + # Both channel caches plus the Raspberry Pi cachix, so a build can substitute + # from whichever channel the checked-out ref selects. + NIX_CONFIG: | + extra-substituters = https://attic.radiantwavetech.com/radiantwave https://attic.radiantwavetech.com/radiantwave-dev https://nixos-raspberrypi.cachix.org + extra-trusted-public-keys = radiantwave:QADrjpBWJssTZ3KmiZtcWEf4uAm66oOlHmtQI3jkrgA= radiantwave-dev:B8FhLu3MQ9JfeEIHIKNrKxnP+3akzzkqMbTZR4hRfj0= nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI= + +jobs: + build: + name: ${{ matrix.label }} + runs-on: orion-lxc + strategy: + fail-fast: false + matrix: + include: + - label: rpi + system: radiantwavekiosk-rpi + target: sdImage + outdir: sd-image + ext: img.zst + arch: aarch64-linux + manifest: aarch64-manifest.json + + steps: + - name: Clone repository + run: | + rm -rf ./* ./.[!.]* 2>/dev/null || true + ref="${GITHUB_REF#refs/heads/}" + ref="${ref#refs/tags/}" + git clone --depth 1 --branch "$ref" \ + ssh://git@gitea.radiantwavetech.com:2222/RadiantWaveTech/KioskConfig.git . + git log --oneline -1 + + - name: Determine channel + run: | + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + CHANNEL=$(nix eval --impure --raw .#channelName) + if [ "$CHANNEL" = "radiantwave" ]; then LABEL=prod; else LABEL=dev; fi + echo "CHANNEL=$CHANNEL" >> "$GITHUB_ENV" + echo "CHANNEL_LABEL=$LABEL" >> "$GITHUB_ENV" + echo "Building the '$CHANNEL' channel ($LABEL)" + + # Production only: fail fast unless the baked closure is exactly what + # RadiantWave CI published to Attic. The dev channel churns on every + # dispatch, so this is skipped there. + - name: Verify baked baseline matches the published channel + run: | + set -euo pipefail + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + + if [ "$CHANNEL" != "radiantwave" ]; then + echo "channel '$CHANNEL' is not production; skipping baseline preflight" + exit 0 + fi + + VERSION=$(nix eval --impure --raw .#channelVersion) + ATTIC=$(nix eval --impure --raw .#channelAtticUrl) + MANIFEST_URL="$(nix eval --impure --raw .#channelManifestDir)/${{ matrix.manifest }}" + BASELINE=$(nix eval --impure --raw .#baselineOutPaths.${{ matrix.arch }}) + + MANIFEST=$(curl -fsSL "$MANIFEST_URL") + PUB_VERSION=$(MANIFEST="$MANIFEST" nix eval --impure --raw --expr '(builtins.fromJSON (builtins.getEnv "MANIFEST")).version') + PUB_PATH=$(MANIFEST="$MANIFEST" nix eval --impure --raw --expr '(builtins.fromJSON (builtins.getEnv "MANIFEST")).storePath') + + echo "channel version : $VERSION" + echo "manifest version: $PUB_VERSION" + echo "baseline path : $BASELINE" + echo "manifest path : $PUB_PATH" + + if [ "$VERSION" != "$PUB_VERSION" ]; then + echo "ERROR: channel.appVersion '$VERSION' != published manifest version '$PUB_VERSION'." + exit 1 + fi + if [ "$BASELINE" != "$PUB_PATH" ]; then + echo "ERROR: baseline '$BASELINE' is not the published closure '$PUB_PATH'." + echo " Run 'nix flake update radiantwave' so the pinned input resolves to the released commit." + exit 1 + fi + HASH=$(basename "$BASELINE" | cut -d- -f1) + if ! curl -fsS -o /dev/null "$ATTIC/${HASH}.narinfo"; then + echo "ERROR: $BASELINE is not in $ATTIC; the image would compile RadiantWave from source." + exit 1 + fi + + - name: Prepare output directory + run: mkdir -p /var/lib/gitea-runner/radiantwave + + - name: Build ${{ matrix.label }} + run: | + export NIXPKGS_ALLOW_UNFREE=1 + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + nix build -L --impure \ + ".#nixosConfigurations.${{ matrix.system }}.config.system.build.${{ matrix.target }}" + + - name: Publish ${{ matrix.label }} + run: | + ISO_DATE=$(date +%Y-%m-%d_%H-%M-%S) + FILENAME="radiantwave-${{ matrix.label }}-${CHANNEL_LABEL}-${ISO_DATE}.${{ matrix.ext }}" + cp -L result/${{ matrix.outdir }}/*.${{ matrix.ext }} \ + "/var/lib/gitea-runner/radiantwave/${FILENAME}" + scp "/var/lib/gitea-runner/radiantwave/${FILENAME}" \ + 157.245.124.103:/mnt/infrastructure_data/files/images/ + rm -f "/var/lib/gitea-runner/radiantwave/${FILENAME}" \ No newline at end of file diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index d6ac0e8..a6099bf 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -1,20 +1,18 @@ -# One build workflow for every branch — do not add per-branch copies. +# One build workflow per hardware family, identical on every branch — do not +# add per-branch copies. build-rpi.yaml is the same file with a different matrix. # # The branch/ref selects the channel, nothing else does: the flake's `channel` # block picks the app input, Attic repo, and upgrade ref, so the same config -# names build dev images on `dev` and prod images on `main`. This file itself -# is identical on both branches. +# names build dev images on `dev` and prod images on `main`. # # Trigger model: # * push to `dev` -> build every development image # * new git tag -> build every production image (tags live on main) # * manual dispatch -> build the channel of the selected branch # -# Hardware variants come from an include-matrix: +# This file builds the x86_64 ISO variants: # ISO variants -> .config.system.build.isoImage (storeContents pulls in the closure) -# Raspberry Pi -> .config.system.build.sdImage -# `orion-lxc` emulates aarch64-linux, so the Pi build runs alongside the rest. -name: Build Kiosk Images +name: Build Kiosk Images (x86) on: workflow_dispatch: @@ -41,14 +39,7 @@ jobs: include: # NOTE: Gitea schedules matrix jobs in reverse definition order on # the single orion-lxc runner, so the list is reversed on purpose: - # rpi -> android -> commercial -> kiosk means kiosk builds FIRST. - - label: rpi - system: radiantwavekiosk-rpi - target: sdImage - outdir: sd-image - ext: img.zst - arch: aarch64-linux - manifest: aarch64-manifest.json + # android -> commercial -> kiosk means kiosk builds FIRST. - label: android system: android-iso target: isoImage @@ -150,4 +141,4 @@ jobs: "/var/lib/gitea-runner/radiantwave/${FILENAME}" scp "/var/lib/gitea-runner/radiantwave/${FILENAME}" \ 157.245.124.103:/mnt/infrastructure_data/files/images/ - rm -f "/var/lib/gitea-runner/radiantwave/${FILENAME}" + rm -f "/var/lib/gitea-runner/radiantwave/${FILENAME}" \ No newline at end of file