diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index e29e963..1f60cc1 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -35,11 +35,33 @@ jobs: - name: Build image run: sudo -E ./build-image.sh - - name: Publish latest Release + - name: Publish image + Imager OS list env: GH_TOKEN: ${{ github.token }} run: | + set -euo pipefail + . .build/image-meta.env TAG="dpea-pi-$(date +%Y%m%d-%H%M)" - gh release create "$TAG" .build/*.img.xz \ + IMG_URL="/${GITHUB_REPOSITORY}/releases/download/${TAG}/${IMG_FILE}" + # os-list.json = a Raspberry Pi Imager repo with one entry. init_format + # enables the Customisation panel; the constant asset name means + # .../releases/latest/download/os-list.json is a stable URL for Imager. + jq -n \ + --arg url "$IMG_URL" \ + --arg date "$(date +%Y-%m-%d)" \ + --arg sha "$EXTRACT_SHA256" \ + --argjson esize "$EXTRACT_SIZE" \ + --argjson dsize "$IMAGE_DOWNLOAD_SIZE" \ + '{os_list: [ { + name: "DPEA Pi", + description: "DPEA exhibit base image (Raspberry Pi OS Trixie 64-bit + DPEA config)", + url: $url, + release_date: $date, + init_format: "systemd", + extract_size: $esize, + extract_sha256: $sha, + image_download_size: $dsize + } ] }' > .build/os-list.json + gh release create "$TAG" ".build/${IMG_FILE}" .build/os-list.json \ --repo "$GITHUB_REPOSITORY" --title "$TAG" \ --notes "Auto-built DPEA Pi image from ${GITHUB_SHA::7}" --latest diff --git a/.gitignore b/.gitignore index 30bcfa4..f42e980 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .build/ +.idea/ diff --git a/README.md b/README.md index 77c91ec..36c1f83 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,23 @@ demand, then publishes the result as this repo's latest Release. It runs `build-image.sh`, which customizes the stock Raspberry Pi OS image: download, grow, loop-mount, run `customize.sh` in a chroot (packages, avahi, uv, config), recompress. It runs on a native arm64 runner (free while this repo is public), so -the chroot's arm64 binaries run natively. No default user is baked. Set user + -hostname + wifi in the Imager at flash time. Pin `BASE_URL` in `build-image.sh` to -a specific Raspberry Pi OS release for reproducibility. +the chroot's arm64 binaries run natively. No default user is baked. Pin `BASE_URL` +in `build-image.sh` to a specific Raspberry Pi OS release for reproducibility. + +The same job also publishes `os-list.json` (a Raspberry Pi Imager OS list) to the +release, so it is served at a stable URL: +`https://github.com/dpengineering/DPEA-RaspberryPiImage/releases/latest/download/os-list.json`. + +## Flashing + +Launch Imager pointed at that OS list so "DPEA Pi" appears with the Customisation +panel enabled (hostname, SSH, user, wifi): +``` +rpi-imager --repo https://github.com/dpengineering/DPEA-RaspberryPiImage/releases/latest/download/os-list.json +``` +`imager-launchers/` has double-click wrappers of that command for macOS / Windows +/ Linux, meant to be handed to students (e.g. from the student setup repo). The +repo is public, so no GitHub account is needed to download the image. ## Testing @@ -78,7 +92,8 @@ you can reach `172.17.21.2`. | `provision.sh` | apply the same config to an already-running Pi (no reflash) | | `lib/common.sh` | shared shell helpers for `provision.sh` | | `hardware-smoke-test.sh` | on-Pi smoke test of the baked config | -| `.github/workflows/build-image.yml` | build + publish the image | +| `imager-launchers/` | double-click launchers that open Imager with the DPEA OS list | +| `.github/workflows/build-image.yml` | build + publish the image + `os-list.json` | | `.github/workflows/validate.yml` | PR checks (shellcheck + container validation) | The patched avahi `.deb` lives in the `avahi_0.8` repo, not here. diff --git a/build-image.sh b/build-image.sh index c7cd07e..0fe3314 100755 --- a/build-image.sh +++ b/build-image.sh @@ -63,5 +63,18 @@ rm -f "$MNT/tmp/customize.sh" # --- unmount (via trap) + compress --- cleanup; trap - EXIT + +# Record metadata for the Raspberry Pi Imager OS list (os-list.json, built by CI): +# the sha256 + size are of the UNCOMPRESSED image, which Imager verifies. +EXTRACT_SIZE="$(stat -c%s "$OUT_IMG")" +EXTRACT_SHA256="$(sha256sum "$OUT_IMG" | awk '{print $1}')" xz -T0 -f "$OUT_IMG" +{ + echo "IMG_FILE=$(basename "${OUT_IMG}.xz")" + echo "EXTRACT_SIZE=${EXTRACT_SIZE}" + echo "EXTRACT_SHA256=${EXTRACT_SHA256}" + echo "IMAGE_DOWNLOAD_SIZE=$(stat -c%s "${OUT_IMG}.xz")" +} > "$WORK/image-meta.env" + echo "Image: ${OUT_IMG}.xz" +echo "Meta: $WORK/image-meta.env" diff --git a/imager-launchers/README.md b/imager-launchers/README.md new file mode 100644 index 0000000..3846681 --- /dev/null +++ b/imager-launchers/README.md @@ -0,0 +1,15 @@ +# Imager launchers + +Each launcher opens Raspberry Pi Imager preloaded with the DPEA OS list +(`--repo https://github.com/dpengineering/DPEA-RaspberryPiImage/releases/latest/download/os-list.json`), +so "DPEA Pi" appears in the OS list with the **Customisation** panel enabled +(hostname, SSH, user, wifi). Plain "Use custom" on a local file cannot do that. + +- `dpea-pi-imager.command` - macOS (double-click; may need `chmod +x` once, and + right-click -> Open the first time to clear Gatekeeper). +- `dpea-pi-imager.bat` - Windows (double-click). +- `dpea-pi-imager.desktop` - Linux (mark executable / "Allow launching"). + +Requires Raspberry Pi Imager installed and internet access. No GitHub account +needed (public repo). These are meant to be handed to students, e.g. from the +student setup repo. diff --git a/imager-launchers/dpea-pi-imager.bat b/imager-launchers/dpea-pi-imager.bat new file mode 100644 index 0000000..2857134 --- /dev/null +++ b/imager-launchers/dpea-pi-imager.bat @@ -0,0 +1,4 @@ +@echo off +rem Windows: double-click to launch Raspberry Pi Imager preloaded with the DPEA +rem image list, so "DPEA Pi" appears with the Customisation panel enabled. +start "" "%ProgramFiles%\Raspberry Pi Imager\rpi-imager.exe" --repo https://github.com/dpengineering/DPEA-RaspberryPiImage/releases/latest/download/os-list.json diff --git a/imager-launchers/dpea-pi-imager.command b/imager-launchers/dpea-pi-imager.command new file mode 100755 index 0000000..78d072f --- /dev/null +++ b/imager-launchers/dpea-pi-imager.command @@ -0,0 +1,5 @@ +#!/bin/bash +# macOS: double-click to launch Raspberry Pi Imager preloaded with the DPEA image +# list, so "DPEA Pi" appears in the OS list with the Customisation panel enabled. +exec "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/Applications/Raspberry Pi Imager.app/Contents/MacOS/rpi-imager" \ + --repo https://github.com/dpengineering/DPEA-RaspberryPiImage/releases/latest/download/os-list.json diff --git a/imager-launchers/dpea-pi-imager.desktop b/imager-launchers/dpea-pi-imager.desktop new file mode 100755 index 0000000..3ee3992 --- /dev/null +++ b/imager-launchers/dpea-pi-imager.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Name=DPEA Pi Imager +Comment=Raspberry Pi Imager preloaded with the DPEA image list +Exec=rpi-imager --repo https://github.com/dpengineering/DPEA-RaspberryPiImage/releases/latest/download/os-list.json +Icon=rpi-imager +Terminal=false +Categories=Utility;