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>
144 lines
7.6 KiB
Bash
144 lines
7.6 KiB
Bash
#!/bin/sh
|
|
# Runs INSIDE an `openwrt/sdk:<target>-<ver>` container (CWD = SDK root
|
|
# /builder). The job's workspace is shared into this container via
|
|
# `docker run --volumes-from`, so the repo is visible at $REPO and output goes
|
|
# to $OUT (a dir under the repo, hence also visible to the runner afterwards).
|
|
#
|
|
# Unlike Shater v0.1 (which compiled ONLY xrayctl in the SDK and hand-packed the
|
|
# pure-data packages with tar), v0.2 builds ALL FOUR packages the canonical way,
|
|
# via the SDK feed + `make package/<p>/compile`:
|
|
#
|
|
# shaterd prebuilt binary — Build/Compile only VALIDATES that
|
|
# openwrt/shaterd/files/shaterd-<amd64|arm64>.upx was staged
|
|
# by scripts/build-shaterd.sh on the runner BEFORE this ran.
|
|
# (arch-specific .ipk: RSTRIP/STRIP disabled — packed ELF.)
|
|
# shater-core PKGARCH=all data glue (procd init, sysctl, uci-defaults).
|
|
# luci-app-shater PKGARCH=all LuCI thin launcher — its Makefile does
|
|
# `include $(TOPDIR)/feeds/luci/luci.mk`, so the `luci` feed
|
|
# MUST be updated first (that is what creates feeds/luci/luci.mk).
|
|
# byedpi arch-specific C — the SDK cross-compiles ciadpi from the
|
|
# upstream tarball (needs network for PKG_SOURCE_URL).
|
|
#
|
|
# Env (required): ARCH, REPO, OUT.
|
|
set -eu
|
|
ARCH="${ARCH:?ARCH env required}"
|
|
REPO="${REPO:?REPO env required}"
|
|
OUT="${OUT:?OUT env required}"
|
|
mkdir -p "$OUT"
|
|
|
|
echo "[sdk] arch=$ARCH repo=$REPO out=$OUT"
|
|
# Package version, derived from the git tag by ci/version.sh and handed in by
|
|
# ci/build-feed.sh. openwrt/{shaterd,shater-core,luci-app-shater}/Makefile read
|
|
# these straight out of the environment ($(if $(SHATER_PKG_VERSION),...)); make
|
|
# imports every environment variable as a variable, and it propagates through
|
|
# `make package/<p>/compile`, the metadata dump and the sub-makes alike.
|
|
# byedpi deliberately keeps its own upstream version (see its Makefile).
|
|
echo "[sdk] package version: ${SHATER_PKG_VERSION:-<unset -> Makefile fallback>}-r${SHATER_PKG_RELEASE:-?}"
|
|
test -f "$REPO/openwrt/shaterd/Makefile" || {
|
|
echo "[sdk] ERROR: feed not mounted ($REPO/openwrt/shaterd/Makefile missing)"; ls -la "$REPO" || true; exit 9; }
|
|
|
|
# The prebuilt shaterd artifact must already be staged for this arch.
|
|
case "$ARCH" in
|
|
x86_64) sfx=amd64 ;;
|
|
aarch64_cortex-a53) sfx=arm64 ;;
|
|
*) echo "[sdk] ERROR: unsupported ARCH '$ARCH'"; exit 2 ;;
|
|
esac
|
|
test -f "$REPO/openwrt/shaterd/files/shaterd-$sfx.upx" || {
|
|
echo "[sdk] ERROR: openwrt/shaterd/files/shaterd-$sfx.upx not staged."
|
|
echo " scripts/build-shaterd.sh must run on the runner before the SDK build."; exit 3; }
|
|
|
|
# --- register this repo's openwrt/ as a src-link feed named `shater` ---------
|
|
# src-link REQUIRES an absolute path; $REPO/openwrt is exactly a feed root (it
|
|
# contains the 4 package dirs and nothing else that looks like a package).
|
|
cp -f feeds.conf.default feeds.conf
|
|
grep -q '^src-link shater ' feeds.conf || echo "src-link shater $REPO/openwrt" >> feeds.conf
|
|
|
|
# Update metadata for ALL feeds: our `shater` feed + the SDK defaults (base,
|
|
# luci, packages, routing, telephony). We need `luci` for feeds/luci/luci.mk and
|
|
# `base`/`packages` for the runtime deps (kmod-nft-tproxy, kmod-nft-socket,
|
|
# ip-full, rpcd, luci-base) to resolve.
|
|
#
|
|
# Persistent feeds checkouts: $FEEDS_CACHE (a workspace dir the runner restores
|
|
# via actions/cache, shared into this container via --volumes-from) replaces
|
|
# the SDK's ephemeral feeds/ dir, so `feeds update` git-fetches deltas instead
|
|
# of re-cloning base+packages+luci every run (~7 min on the runner's slow
|
|
# github.com link). Correctness-safe: update always checks out feeds.conf's
|
|
# pinned revisions; if it ever fails on a cached checkout (e.g. a force-pushed
|
|
# upstream), the cache is wiped and the update retried with fresh clones.
|
|
if [ -n "${FEEDS_CACHE:-}" ] && mkdir -p "$FEEDS_CACHE" 2>/dev/null; then
|
|
rm -rf feeds
|
|
ln -s "$FEEDS_CACHE" feeds
|
|
echo "[sdk] feeds/ -> $FEEDS_CACHE (persistent cache)"
|
|
fi
|
|
echo "[sdk] feeds update -a"
|
|
if ! ./scripts/feeds update -a; then
|
|
[ -L feeds ] || { echo "[sdk] ERROR: feeds update failed"; exit 8; }
|
|
echo "[sdk] WARNING: feeds update failed on cached checkouts — wiping cache, cloning fresh"
|
|
find "$FEEDS_CACHE" -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true
|
|
./scripts/feeds update -a
|
|
fi
|
|
|
|
echo "[sdk] feeds install (prefer shater feed)"
|
|
./scripts/feeds install -p shater shaterd shater-core byedpi luci-app-shater
|
|
|
|
# Select our packages, then defconfig. `make package/<p>/compile` builds the
|
|
# explicit target regardless, but selecting first makes deps visible to defconfig.
|
|
for p in shaterd shater-core byedpi luci-app-shater; do
|
|
echo "CONFIG_PACKAGE_$p=m" >> .config
|
|
done
|
|
# Route source downloads through OpenWrt's fast CDN mirror FIRST — sourceware.org
|
|
# (elfutils) and other upstreams intermittently stall mid-transfer, and curl's
|
|
# --connect-timeout doesn't cover a stalled stream, so the SDK download hangs the
|
|
# build. LOCALMIRROR is tried before each package's own PKG_SOURCE_URL. (lx CI)
|
|
echo 'CONFIG_LOCALMIRROR="https://sources.cdn.openwrt.org"' >> .config
|
|
# Persistent dl/ across runs: $DL_DIR is a workspace dir the runner restores via
|
|
# actions/cache (see ci/build-feed.sh). Correctness-safe: the buildroot verifies
|
|
# PKG_HASH on every file already in dl/ and re-downloads on mismatch, so a stale
|
|
# cache can never leak a wrong source into the build.
|
|
if [ -n "${DL_DIR:-}" ]; then
|
|
echo "CONFIG_DOWNLOAD_FOLDER=\"$DL_DIR\"" >> .config
|
|
fi
|
|
echo "[sdk] defconfig"
|
|
make defconfig >/dev/null
|
|
|
|
# --- compile the 4 packages --------------------------------------------------
|
|
for p in shaterd shater-core byedpi luci-app-shater; do
|
|
echo "[sdk] === build $p ==="
|
|
make "package/$p/compile" V=s -j"$(nproc)"
|
|
done
|
|
|
|
# --- collect ONLY our 4 packages' .ipk (per-arch shaterd/byedpi + _all core/luci)
|
|
# NOT `find bin -name '*.ipk'`: the openwrt/sdk image ships HUNDREDS of prebuilt
|
|
# kmod/base .ipk under bin/, which a blanket copy would pull into the feed and
|
|
# get signed under OUR key. Match each package's own `<name>_<ver>_<arch>.ipk`.
|
|
found=0
|
|
for p in shaterd shater-core byedpi luci-app-shater; do
|
|
for ipk in $(find bin -type f -name "${p}_*.ipk"); do
|
|
cp -f "$ipk" "$OUT/"; found=$((found+1))
|
|
done
|
|
done
|
|
[ "$found" -ge 4 ] || { echo "[sdk] ERROR: expected >=4 of OUR .ipk, collected $found"; echo "[sdk] (all .ipk under bin/:)"; find bin -type f -name '*.ipk' | head -20; exit 4; }
|
|
|
|
# --- assert the tag-derived version actually reached the packages -------------
|
|
# The whole point of B4 is that a WRONG-but-plausible version ships silently. The
|
|
# env -> make hand-off has several layers (docker -e, make's env import, the
|
|
# metadata dump), so verify the result instead of trusting it: every one of our
|
|
# three tag-versioned packages must be named `<name>_<ver>-r<rel>_<arch>.ipk`.
|
|
# byedpi is excluded on purpose — it keeps upstream ByeDPI's own version.
|
|
if [ -n "${SHATER_PKG_VERSION:-}" ] && [ -n "${SHATER_PKG_RELEASE:-}" ]; then
|
|
want="${SHATER_PKG_VERSION}-r${SHATER_PKG_RELEASE}"
|
|
for p in shaterd shater-core luci-app-shater; do
|
|
ls "$OUT/${p}_${want}_"*.ipk >/dev/null 2>&1 || {
|
|
echo "[sdk] ERROR: $p was not built as version '$want'."
|
|
echo " SHATER_PKG_VERSION/SHATER_PKG_RELEASE did not reach the package"
|
|
echo " Makefile — the build would have shipped a stale version (bug B4)."
|
|
echo "[sdk] collected:"; ls -1 "$OUT" | sed 's/^/ /'
|
|
exit 12; }
|
|
done
|
|
echo "[sdk] version check OK — our 3 packages are $want"
|
|
fi
|
|
|
|
chmod -R a+rwX "$OUT" 2>/dev/null || true
|
|
echo "[sdk] OK arch=$ARCH — collected $found of our .ipk:"
|
|
ls -l "$OUT"
|