PKG_VERSION/PKG_RELEASE were hand-written literals nobody bumped, so
v0.2.2 … v0.2.6 all shipped as `shaterd 0.2.0-r3` with different binaries
inside (v0.2.6's ELF is 5 491 616 B against r2's 5 488 336 B). Both opkg
and apk offer an upgrade only when the feed's version string differs from
the installed one, so `apk update` saw nothing new and the routers could
not be updated through the normal path at all.
ci/version.sh is now the single source of truth. It derives the version
from `git describe`:
tag `vX.Y.Z` -> PKG_VERSION=X.Y.Z PKG_RELEASE=1
off-tag build -> nearest tag + PKG_RELEASE=<commits since it> + 1
no tag/no git -> 0.0.0-r1 (below everything ever published)
Ordering verified with the real tools, not from memory — apk-tools 3.0.3
(`apk version -t`) and opkg 38eccbb1 (`opkg compare-versions`) agree that
0.2.0-r3 < 0.2.6-r2 < 0.2.6-r10 < 0.2.6-r12 < 0.2.7-r1 < 0.3.0-r1, so a
release always outranks the rolling builds that preceded it and rolling
builds grow monotonically between releases.
The value travels as SHATER_PKG_VERSION/SHATER_PKG_RELEASE in the SDK
build environment of BOTH lanes; the Makefiles keep a literal fallback so
a manual/offline build still works with no CI and no git. Because the
hand-off crosses docker, `su` and make's env import, ci/sdk-build.sh and
ci/sdk-build-apk.sh now ASSERT that the produced .ipk/.apk really carries
that version — the B4 failure mode was a stale version shipping silently,
and that can no longer happen quietly.
The binary agrees with the package: scripts/build-shaterd.sh takes
constant.Version from the same ci/version.sh (vX.Y.Z-rR[-g<sha>]) instead
of its own `git describe`, and the workflow computes it once per job.
Both build jobs now check out with fetch-depth: 0 — `git describe` needs
tags and ancestry, which the default shallow checkout has neither of.
byedpi is deliberately left alone: PKG_VERSION:=0.17.3 is upstream
ByeDPI's own version, what PKG_HASH pins and what tells an operator which
ByeDPI is installed. Stamping our tag on it would also be a downgrade —
every comparator reads 0.2.7 < 0.17.3 (component-wise, 2 < 17), verified.
Docs: INSTALL.md gains §2.1 (the scheme + the ordering evidence), and the
update sections of §5/§6 now explicitly warn against a bare `opkg upgrade`
/ `apk upgrade` and give the targeted form instead, quoting apk-tools 3:
"If list of packages is provided, only those packages are upgraded along
with needed dependencies". README.md and the release bodies match.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
107 lines
5.3 KiB
Bash
107 lines
5.3 KiB
Bash
#!/bin/sh
|
|
# ci/build-feed.sh — build the signed opkg feed for ONE arch.
|
|
#
|
|
# Usage: ci/build-feed.sh <ARCH> <SDK_DOCKER_TAG> <OUTDIR>
|
|
# e.g. ci/build-feed.sh x86_64 x86_64-24.10.4 out/x86_64
|
|
# ci/build-feed.sh aarch64_cortex-a53 mediatek-filogic-24.10.4 out/aarch64_cortex-a53
|
|
#
|
|
# This is the reusable per-arch entrypoint the Gitea workflow calls. It runs on
|
|
# the CI RUNNER and:
|
|
# 1. asserts the prebuilt shaterd binary for this arch was already staged by
|
|
# scripts/build-shaterd.sh (into openwrt/shaterd/files/) — proving artifact
|
|
# order: SPA+shaterd build BEFORE the SDK package build;
|
|
# 2. drives the arch-matched `openwrt/sdk` docker image to compile all 4
|
|
# packages (ci/sdk-build.sh) and collect their .ipk into OUTDIR;
|
|
# 3. builds + usign-signs the opkg `Packages` index over OUTDIR
|
|
# (ci/install-usign.sh + ci/make-index.sh; signs iff $KEY_BUILD is set).
|
|
#
|
|
# Env:
|
|
# KEY_BUILD usign SECRET key (Gitea repo secret). If set, the feed index is
|
|
# signed and verifiable by dist/shater-feed.pub (fp 5ac4b177689cb8e0).
|
|
# If unset, an UNSIGNED feed is produced (make-index warns).
|
|
set -eu
|
|
|
|
ARCH="${1:?arch required (x86_64 | aarch64_cortex-a53)}"
|
|
SDK_TAG="${2:?sdk docker tag required (e.g. x86_64-24.10.4)}"
|
|
OUT="${3:?output dir required}"
|
|
|
|
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
|
mkdir -p "$OUT"; OUT="$(cd "$OUT" && pwd)"
|
|
# $OUT is created here as ROOT on the runner, but the nested `openwrt/sdk`
|
|
# container runs as the unprivileged `buildbot` (uid 1000) — so it must be able
|
|
# to write the collected .ipk into $OUT. World-writable is set HERE (a chmod
|
|
# from inside the container, as buildbot, cannot fix a root-owned dir).
|
|
chmod 0777 "$OUT"
|
|
|
|
# --- 0) the prebuilt shaterd binary must already be staged for this arch ------
|
|
case "$ARCH" in
|
|
x86_64) sfx=amd64 ;;
|
|
aarch64_cortex-a53) sfx=arm64 ;;
|
|
*) echo "[feed] ERROR: unsupported ARCH '$ARCH'"; exit 2 ;;
|
|
esac
|
|
if [ ! -f "$REPO/openwrt/shaterd/files/shaterd-$sfx.upx" ]; then
|
|
echo "[feed] ERROR: openwrt/shaterd/files/shaterd-$sfx.upx not staged."
|
|
echo " Run scripts/build-shaterd.sh BEFORE ci/build-feed.sh." >&2
|
|
exit 3
|
|
fi
|
|
|
|
chmod +x "$REPO"/ci/*.sh 2>/dev/null || true
|
|
|
|
# --- 0.4) package version from the git tag ------------------------------------
|
|
# The workflow normally puts these in the job env (ci/version.sh --env >>
|
|
# $GITHUB_ENV); recompute here when this script is run standalone so a manual
|
|
# `ci/build-feed.sh ...` produces the same versions as CI. They are handed to the
|
|
# SDK container below and read by openwrt/*/Makefile (bug B4 — versions used to
|
|
# be hand-written literals that nobody bumped, so v0.2.2…v0.2.6 all shipped as
|
|
# 0.2.0-r3 and no router could ever see an update).
|
|
if [ -z "${SHATER_PKG_VERSION:-}" ] || [ -z "${SHATER_PKG_RELEASE:-}" ]; then
|
|
eval "$(sh "$REPO/ci/version.sh" --env)"
|
|
fi
|
|
echo "[feed] package version: ${SHATER_PKG_VERSION}-r${SHATER_PKG_RELEASE}"
|
|
|
|
# --- 0.5) persistent dl/ (package source tarballs) ----------------------------
|
|
# Workspace dir restored/saved by actions/cache in the workflow and shared into
|
|
# the nested SDK container via --volumes-from; becomes CONFIG_DOWNLOAD_FOLDER
|
|
# there (ci/sdk-build.sh). PKG_HASH still verifies every file, so a stale cache
|
|
# can never produce a wrong build. Must be writable by the container's
|
|
# unprivileged buildbot user (same reason as the $OUT chmod above).
|
|
DL_DIR="$REPO/.cache/dl"
|
|
mkdir -p "$DL_DIR"
|
|
chmod -R a+rwX "$DL_DIR" 2>/dev/null || true
|
|
|
|
# --- 0.6) persistent feeds/ git checkouts -------------------------------------
|
|
# Workspace dir restored/saved by actions/cache (key: feeds-opkg-<release>) and
|
|
# symlinked over the SDK's feeds/ inside the container (ci/sdk-build.sh), so
|
|
# `scripts/feeds update -a` fetches deltas instead of re-cloning base+packages+
|
|
# luci from scratch (~7 min/run on this runner's slow github.com link).
|
|
# Top-level chmod only: the contents are created by the container's uid-1000
|
|
# build user and restored with the same ownership (tar-as-root preserves it).
|
|
FEEDS_CACHE="$REPO/.cache/feeds/opkg"
|
|
mkdir -p "$FEEDS_CACHE"
|
|
chmod a+rwX "$REPO/.cache" "$REPO/.cache/feeds" "$FEEDS_CACHE" 2>/dev/null || true
|
|
|
|
# --- 1) SDK package build (4 packages) in the arch-matched SDK image ----------
|
|
# We drive the `openwrt/sdk` docker image directly (not openwrt/gh-action-sdk):
|
|
# on a self-hosted Gitea act_runner the marketplace action fetch can be
|
|
# unavailable, and we need a CLEAN single-feed layout. `--volumes-from
|
|
# $(hostname)` shares THIS job container's workspace volume into the nested SDK
|
|
# container — a bare `-v $PWD:...` points at a host path that does not exist
|
|
# under the act_runner DinD setup. (Requires the job to run inside a container,
|
|
# which Gitea Actions does by default.)
|
|
echo "[feed] SDK build arch=$ARCH image=openwrt/sdk:$SDK_TAG"
|
|
docker pull "openwrt/sdk:$SDK_TAG"
|
|
docker run --rm --volumes-from "$(hostname)" \
|
|
-e ARCH="$ARCH" -e REPO="$REPO" -e OUT="$OUT" -e DL_DIR="$DL_DIR" \
|
|
-e FEEDS_CACHE="$FEEDS_CACHE" \
|
|
-e SHATER_PKG_VERSION="$SHATER_PKG_VERSION" \
|
|
-e SHATER_PKG_RELEASE="$SHATER_PKG_RELEASE" \
|
|
"openwrt/sdk:$SDK_TAG" \
|
|
sh "$REPO/ci/sdk-build.sh"
|
|
|
|
# --- 2) index + sign the per-arch feed (usign, KEY_BUILD passed through) -------
|
|
sh "$REPO/ci/install-usign.sh"
|
|
KEY_BUILD="${KEY_BUILD:-}" bash "$REPO/ci/make-index.sh" "$OUT"
|
|
|
|
echo "[feed] done arch=$ARCH -> $OUT"
|
|
ls -l "$OUT"
|