Files
op-packages/luci-theme-footstrap/build-apk.sh
T
github-actions[bot] 410d762592
Merge-upstream / merge (push) Canceled after 0s
🎄 Sync 2026-08-27 02:13:09
2026-08-27 02:13:09 +08:00

121 lines
6.0 KiB
Bash
Executable File

#!/bin/sh
# Build luci-theme-footstrap as an OpenWrt .apk via the SDK. The theme is noarch, so the package
# installs on any router of that release whatever its CPU architecture.
#
# ./build-apk.sh # download SDK if needed, then build
# BUILD_DIR=~/x ./build-apk.sh
#
# This is NOT how the release is built — `./tools/stage.sh && owfeed build` is, and it produces both
# formats in seconds without a toolchain. What this exercises is the OTHER path: the Makefile,
# luci.mk, jsmin and the SDK's own packaging, which has to keep working for anyone building the
# theme in an SDK or a feed without owfeed.
set -e
# The point release and the compiler are both baked into the SDK's filename, so this default goes
# stale twice over: downloads.openwrt.org keeps only the CURRENT point release of a branch, and a
# toolchain bump changes the gcc string. Kept in step with owfeed.lock's `point:` for the 25.12
# branch, which is what the release builds against. Override with OPENWRT_RELEASE=… and
# OPENWRT_SDK_FILE=… for any other.
REL="${OPENWRT_RELEASE:-25.12.5}"
SDK_BASE="https://downloads.openwrt.org/releases/${REL}/targets/mediatek/filogic"
SDK_FILE="${OPENWRT_SDK_FILE:-openwrt-sdk-${REL}-mediatek-filogic_gcc-14.3.0_musl.Linux-x86_64.tar.zst}"
SDK_URL="$SDK_BASE/$SDK_FILE"
# MUST be a case-sensitive fs (ext4/…), NOT an NTFS/9p Windows mount.
BUILD_DIR="${BUILD_DIR:-/tmp/ow-footstrap-build}"
# FORCE=1 overrides buildroot's host-prereq bail-outs (see step 4).
export FORCE=1
THEME_DIR="$(cd "$(dirname "$0")" && pwd)" # this package
REPO="$(cd "$THEME_DIR/.." && pwd)" # repo root (holds tools/, .github/)
SDK_DIR="$BUILD_DIR/sdk"
# The SDK channel (major.minor) the release SDK is signed under — derived from REL, never a
# second copy: 25.12.2 -> 25.12.
CHANNEL="${REL%.*}"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# 1. SDK
if [ ! -d "$SDK_DIR" ]; then
echo ">> downloading SDK $REL ..."
# --https-only: GNU wget follows https -> http redirects, and this tarball is a toolchain
# that will build a package a maintainer may hand to someone.
wget -q --https-only -O sdk.tar.zst "$SDK_URL"
# Verify the SDK: signature first, checksum under it. This is the least verified input in this
# repo and the only one that ends up INSIDE the built package (jsmin.c and i18n-scan.pl are
# LINTERS pinned by commit and sha256; the toolchain that compiles the artifact arrives on TLS).
# `sha256sums` alone is NOT a verification — it is served by the same host from the same
# directory, unsigned, so whoever can replace the tarball replaces the checksum beside it (see
# docs/conventions.md on GitHub's asset digest). What makes it one is the ed25519 signature over that file,
# checked with a key pinned from a DIFFERENT host (github.com/openwrt/keyring). Fails CLOSED.
#
# Every pin comes from luci-upstream.pin — the keyring commit, usign, and the branch's own
# signing key. The keys used to live in .github/workflows/build.yml's matrix and were read out
# of it here; that matrix went with the SDK build when the release moved to owfeed, so they now
# have one home and this script has one source.
. "$THEME_DIR/luci-upstream.pin"
[ -n "${OPENWRT_KEYRING_PIN:-}" ] || { echo "OPENWRT_KEYRING_PIN missing from luci-upstream.pin" >&2; exit 1; }
# sdk_key / sdk_key_sha256 for CHANNEL: 25.12 -> OPENWRT_SDK_KEY_2512. Indirection through
# eval because the pin file is plain shell assignments and /bin/sh has no associative arrays.
CH_VAR="$(printf '%s' "$CHANNEL" | tr -d .)"
eval "SDK_KEY=\${OPENWRT_SDK_KEY_$CH_VAR:-}"
eval "SDK_KEY_SHA256=\${OPENWRT_SDK_KEY_${CH_VAR}_SHA256:-}"
[ -n "$SDK_KEY" ] && [ -n "$SDK_KEY_SHA256" ] \
|| { echo "no SDK signing key for channel $CHANNEL in luci-upstream.pin" >&2; exit 1; }
echo ">> verifying SDK signature (key $SDK_KEY, channel $CHANNEL) ..."
rm -rf "$BUILD_DIR/usign"
U="$("$REPO/tools/build-usign.sh" "$BUILD_DIR/usign")"
wget -q --https-only -O sha256sums "$SDK_BASE/sha256sums"
wget -q --https-only -O sha256sums.sig "$SDK_BASE/sha256sums.sig"
wget -q --https-only -O openwrt.pub \
"https://raw.githubusercontent.com/openwrt/keyring/$OPENWRT_KEYRING_PIN/usign/$SDK_KEY"
echo "$SDK_KEY_SHA256 openwrt.pub" | sha256sum -c - >/dev/null \
|| { echo "OpenWrt's $CHANNEL key does not match its pin — refusing to verify with it" >&2; exit 1; }
"$U" -V -m sha256sums -p openwrt.pub -x sha256sums.sig \
|| { echo "BAD SIGNATURE on OpenWrt's sha256sums — refusing to build with this SDK." >&2; exit 1; }
echo ">> signature verified; now the checksum means something."
WANT="$(grep -F " *$SDK_FILE" sha256sums | cut -d' ' -f1)"
[ -n "$WANT" ] || { echo "no sha256 published for $SDK_FILE" >&2; exit 1; }
GOT="$(sha256sum sdk.tar.zst | cut -d' ' -f1)"
[ "$WANT" = "$GOT" ] || { echo "SDK checksum mismatch: want $WANT, got $GOT" >&2; exit 1; }
rm -f sha256sums sha256sums.sig openwrt.pub
echo ">> SDK verified."
echo ">> extracting ..."
mkdir -p "$SDK_DIR"
tar --zstd -xf sdk.tar.zst -C "$SDK_DIR" --strip-components=1
rm -f sdk.tar.zst
fi
cd "$SDK_DIR"
# 2. feeds (need luci for luci.mk + BuildPackage macros)
if [ ! -f feeds/luci.index ] && [ ! -d feeds/luci ]; then
./scripts/feeds update base luci
fi
./scripts/feeds install -a -p luci >/dev/null 2>&1 || true
# 3. drop our theme into the luci themes feed (fresh copy)
DEST="feeds/luci/themes/luci-theme-footstrap"
rm -rf "$DEST"
cp -a "$THEME_DIR" "$DEST"
rm -rf "$DEST/build-apk.sh" "$DEST/dev-sync.sh" "$DEST/.git" 2>/dev/null || true
./scripts/feeds update -i luci
./scripts/feeds install luci-theme-footstrap
# 4. build. ncurses is only needed for interactive menuconfig, not for a noarch
# theme, so satisfy the host prereq stamp to skip that check.
mkdir -p staging_dir/host
touch staging_dir/host/.prereq-build
make defconfig FORCE=1
make package/luci-theme-footstrap/clean FORCE=1 V=s >/dev/null 2>&1 || true
make package/luci-theme-footstrap/compile FORCE=1 V=s
# 5. locate the artifact
echo
echo ">> built packages:"
find bin -name 'luci-theme-footstrap*' \( -name '*.apk' -o -name '*.ipk' \) -print