#!/bin/bash # nightly.sh -- the nightly snapshot: boot-check each ISA, build the board images, publish them. # Three stages, run in this order (.gitea/workflows/nightly.yml runs each as a step): # # scripts/nightly.sh boot # Boots that ISA headless in QEMU (scripts/qemu_session.py headless: POST: PASSED, and no # prompt with no Zuse drive), in the foreground; one QEMU at a time, the acceptance order # amd64, aarch64, riscv64. A failure ends the nightly. amd64 also keeps the ISO it booted, # byte for byte, as build/nightly/StarshipOS.iso. # scripts/nightly.sh images # The board images, into build/nightly/: # raspi5.img.xz Raspberry Pi 5 (make boot_image TARGET=RASPI), for Raspberry Pi Imager # MilkV.img.xz Milk-V Mars (make boot_image TARGET=MILKV) # SHA256SUMS of StarshipOS.iso and both images, before and after compression # (Imager's extract_sha256 is the uncompressed one) # QEMU boots the aarch64 and riscv64 kernels, not these images: they are built from the # same sources, for hardware QEMU does not model. # scripts/nightly.sh publish # Deploys the three to a Maven repository (Nexus's starshipos-snapshots) as # org.starship:kernelImage:-SNAPSHOT, one classifier per board -- # pc (iso), raspi5 (img.xz), milkv (img.xz) -- in one deploy, so they share a timestamp. # NEXUS_USER (default ci-publisher) and NEXUS_PASSWORD. Needs mvn and a JRE. # # NIGHTLY_VERSION overrides the version. The serial logs are logs/// and the DoE CSVs # experiments/bare_metal/runs/, as for any boot (.claude/CLAUDE.md). Needs what # make ARCH=amd64,aarch64,riscv64 init INIT_DOCS=0 installs. set -euo pipefail cd "$(dirname "$0")/.." OUT=build/nightly LITHOS=$(sed -n 's/^LITHOS_VERSION *?= *//p' kernel/Makefile) VERSION=${NIGHTLY_VERSION:-$LITHOS-SNAPSHOT} usage() { echo "Usage: scripts/nightly.sh boot | images | publish " >&2; exit 2; } case ${1:-} in boot) arch=${2:-} case $arch in amd64|aarch64|riscv64) ;; *) usage ;; esac [ "$arch" != amd64 ] || { rm -rf "$OUT"; mkdir -p "$OUT"; } # amd64 is the first stage echo "=== nightly: org.starship:kernelImage:$VERSION from $(git rev-parse --short HEAD); boot check $arch" git checkout -q -- disk/zuse-scratch # the committed Zuse pair, as before each acceptance boot python3 scripts/qemu_session.py headless "$arch" --label "nightly-$arch" --make "QEMU_DISPLAY=none" [ "$arch" != amd64 ] || cp build/amd64/kernel/starkernel.iso "$OUT/StarshipOS.iso" ;; images) [ -f "$OUT/StarshipOS.iso" ] || { echo "nightly: no $OUT/StarshipOS.iso -- run boot amd64 first" >&2; exit 1; } for b in "RASPI raspi/lithos-raspi.img raspi5.img" "MILKV milkv/lithos-milkv.img MilkV.img"; do set -- $b echo "=== nightly: image $1" make --no-print-directory boot_image TARGET="$1" cp "build/boards/$2" "$OUT/$3" done # boot_image regenerates these (the source SBOM, and what qemu_session.py also puts back); # the nightly does not change the tree git checkout -q -- sbom.spdx sbom.spdx.json capsules/BLOCK_MAP.md v3/include/version.h (cd "$OUT" && rm -f raspi5.img.xz MilkV.img.xz && sha256sum StarshipOS.iso raspi5.img MilkV.img > SHA256SUMS) xz -T0 -6 "$OUT/raspi5.img" "$OUT/MilkV.img" (cd "$OUT" && sha256sum raspi5.img.xz MilkV.img.xz >> SHA256SUMS && cat SHA256SUMS) ;; publish) url=${2:-} [ -n "$url" ] || usage : "${NEXUS_PASSWORD:?publish needs NEXUS_PASSWORD}" command -v mvn >/dev/null || { echo "nightly: publish needs mvn (apt-get install maven)" >&2; exit 1; } for f in StarshipOS.iso raspi5.img.xz MilkV.img.xz; do [ -f "$OUT/$f" ] || { echo "nightly: no $OUT/$f -- run boot and images first" >&2; exit 1; } done settings=$(mktemp) trap 'rm -f "$settings"' EXIT cat > "$settings" <<'EOF' starship-nexus ${env.NEXUS_USER} ${env.NEXUS_PASSWORD} EOF export NEXUS_USER=${NEXUS_USER:-ci-publisher} echo "=== nightly: publish org.starship:kernelImage:$VERSION -> $url" mvn -B -q -s "$settings" org.apache.maven.plugins:maven-deploy-plugin:3.1.2:deploy-file \ -Durl="$url" -DrepositoryId=starship-nexus \ -DgroupId=org.starship -DartifactId=kernelImage -Dversion="$VERSION" \ -Dfile="$OUT/StarshipOS.iso" -Dpackaging=iso -Dclassifier=pc \ -Dfiles="$OUT/raspi5.img.xz,$OUT/MilkV.img.xz" -Dclassifiers=raspi5,milkv -Dtypes=img.xz,img.xz \ -DgeneratePom=true echo "=== nightly: published" ;; *) usage ;; esac