Bake the channel manifest's closure instead of a pinned app version
Production builds failed CI's baseline preflight because flake.nix pinned the app to tag 1.8 (channel.appVersion = "1.8") while the published manifest had moved on to 1.9; dev was likewise pinned to a stale commit. Stop pinning the app anywhere. flake.nix now fetches the channel's published manifest at eval time (builtins.fetchurl) and bakes its storePath verbatim, so every image carries exactly the closure RadiantWave published to Attic and never compiles the app from source. - flake.nix: drop the radiantwave/radiantwave-dev inputs, appInput, appVersion, channelVersion and baselineOutPaths; add channelAtticUrl, channelManifestDir and publishedApp; builders consume the published path. - configuration.nix: wrap the published store path in a symlinkJoin so it can live in environment.systemPackages; add --impure to autoUpgrade flags and set tarball-ttl = 0 so eval reads the current manifest. - radiantwave-updater.nix: baselinePackage (package) -> baselinePath (str), seeded from the exact manifest path. - CI (build.yml, build-rpi.yml): replace the version-equality preflight with a fail-fast check that the announced closure is in the channel's Attic; set tarball-ttl = 0. - build-rpi.sh: pass --impure. - AGENTS.md: document the manifest-driven baseline.
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
# 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`.
|
||||
# block picks the channel manifest whose closure is baked as the app, the Attic
|
||||
# repo, and the 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
|
||||
@@ -25,10 +26,13 @@ on:
|
||||
|
||||
env:
|
||||
# Both channel caches plus the Raspberry Pi cachix, so a build can substitute
|
||||
# from whichever channel the checked-out ref selects.
|
||||
# from whichever channel the checked-out ref selects. tarball-ttl=0 keeps the
|
||||
# eval-time manifest fetch (builtins.fetchurl in flake.nix) from reusing a
|
||||
# stale copy cached by an earlier build on this persistent runner.
|
||||
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=
|
||||
tarball-ttl = 0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -65,45 +69,29 @@ jobs:
|
||||
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
|
||||
# Fail fast if the closure the channel manifest announces is not in the
|
||||
# channel's Attic cache. We bake that exact storePath, so without it the
|
||||
# image would try to compile RadiantWave from source (which never works:
|
||||
# this repo has no app source). Runs for both channels; RadiantWave CI
|
||||
# publishes the manifest only after the matching Attic push succeeds.
|
||||
- name: Verify published app closure is in the channel cache
|
||||
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"
|
||||
echo "channel : $CHANNEL"
|
||||
echo "attic : $ATTIC"
|
||||
echo "manifest: $MANIFEST_URL"
|
||||
echo "closure : $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)
|
||||
HASH=$(basename "$PUB_PATH" | 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."
|
||||
echo "ERROR: $PUB_PATH is not in $ATTIC; the image would compile RadiantWave from source."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user