M .builds/publish.yml => .builds/publish.yml +6 -0
@@ 92,6 92,12 @@ tasks:
cp ci-cacher/dist/cacher_darwin_amd64_v1/cacher /home/build/pages/cacher-darwin-amd64
cp ci-cacher/dist/cacher_darwin_arm64_v8.0/cacher /home/build/pages/cacher-darwin-arm64
chmod +x /home/build/pages/cacher-*
+ # The one-line bootstrap: `curl -sSL …/install.sh | sh`. Published
+ # from the repo verbatim; it fetches the binaries and checksums.txt
+ # from this same directory.
+ cp ci-cacher/install.sh /home/build/pages/install.sh
+ # Glob stays cacher-* on purpose: install.sh must not appear in the
+ # manifest it verifies against.
( cd /home/build/pages && sha256sum cacher-* > checksums.txt )
cat /home/build/pages/checksums.txt
A install.sh => install.sh +90 -0
@@ 0,0 1,90 @@
+#!/bin/sh
+# Bootstrap the cacher binary in one line, for CI manifests and dev boxes:
+#
+# curl -sSL https://bigbes.pages.srht.bigb.es/ci-cacher/install.sh | sh
+#
+# Detects the platform, verifies the download against the published
+# checksums.txt, installs into ~/.local/bin (override with CACHER_BINDIR or
+# a single positional argument), and — on builds.sr.ht, where ~/.buildenv is
+# sourced before every task — appends the PATH export so later tasks find
+# the binary without repeating it.
+#
+# Env:
+# CACHER_BASE_URL where to fetch from (default: the pages.sr.ht release)
+# CACHER_BINDIR install directory (default: $HOME/.local/bin)
+set -eu
+
+BASE_URL="${CACHER_BASE_URL:-https://bigbes.pages.srht.bigb.es/ci-cacher}"
+BINDIR="${1:-${CACHER_BINDIR:-$HOME/.local/bin}}"
+
+os=$(uname -s | tr '[:upper:]' '[:lower:]')
+case "$os" in
+ linux | darwin) ;;
+ *) echo "install.sh: unsupported OS '$os'; build from source: go install go.bigb.es/cacher@latest" >&2; exit 1 ;;
+esac
+
+case "$(uname -m)" in
+ x86_64 | amd64) arch=amd64 ;;
+ aarch64 | arm64) arch=arm64 ;;
+ *) echo "install.sh: unsupported architecture '$(uname -m)'" >&2; exit 1 ;;
+esac
+
+asset="cacher-${os}-${arch}"
+
+# curl on most CI images, wget on the minimal ones. Fail loudly on HTTP
+# errors so a 404 can't be installed as an executable.
+if command -v curl >/dev/null 2>&1; then
+ fetch() { curl -fsSL "$1" -o "$2"; }
+elif command -v wget >/dev/null 2>&1; then
+ fetch() { wget -q "$1" -O "$2"; }
+else
+ echo "install.sh: neither curl nor wget is available" >&2
+ exit 1
+fi
+
+tmp=$(mktemp -d)
+trap 'rm -rf "$tmp"' EXIT
+
+echo "install.sh: fetching ${BASE_URL}/${asset}"
+fetch "${BASE_URL}/${asset}" "${tmp}/cacher"
+
+# checksums.txt lists every published asset; --ignore-missing lets us
+# verify just the one we downloaded. Skipped, with a warning, when the
+# host has no sha256 tool rather than failing the install.
+if fetch "${BASE_URL}/checksums.txt" "${tmp}/checksums.txt"; then
+ if command -v sha256sum >/dev/null 2>&1; then
+ sum_cmd="sha256sum --ignore-missing -c"
+ elif command -v shasum >/dev/null 2>&1; then
+ sum_cmd="shasum -a 256 --ignore-missing -c"
+ else
+ sum_cmd=""
+ echo "install.sh: no sha256sum/shasum — skipping checksum verification" >&2
+ fi
+ if [ -n "$sum_cmd" ]; then
+ # The manifest names files without a path, so verify from inside $tmp
+ # with the asset under its published name.
+ cp "${tmp}/cacher" "${tmp}/${asset}"
+ ( cd "$tmp" && $sum_cmd checksums.txt >/dev/null ) \
+ || { echo "install.sh: checksum mismatch for ${asset}" >&2; exit 1; }
+ echo "install.sh: checksum ok"
+ fi
+else
+ echo "install.sh: checksums.txt unavailable — skipping verification" >&2
+fi
+
+mkdir -p "$BINDIR"
+install -m 0755 "${tmp}/cacher" "${BINDIR}/cacher"
+
+# builds.sr.ht sources ~/.buildenv before every task; adding the export
+# here saves each manifest a PATH line of its own.
+if [ -f "$HOME/.buildenv" ] && ! grep -q "$BINDIR" "$HOME/.buildenv" 2>/dev/null; then
+ echo "export PATH=\"${BINDIR}:\$PATH\"" >> "$HOME/.buildenv"
+ echo "install.sh: added ${BINDIR} to ~/.buildenv PATH"
+fi
+
+echo "install.sh: installed → ${BINDIR}/cacher"
+"${BINDIR}/cacher" version
+case ":${PATH}:" in
+ *":${BINDIR}:"*) ;;
+ *) echo "install.sh: note — ${BINDIR} is not on your PATH" >&2 ;;
+esac