Build the shared F-Droid publishing tooling: sign, index, publish
Adds sign-apk.sh (align-check + apksigner), fdroid-update.sh (fdroid update over a binary repo, signing the index with its own separate key), publish.sh (S3-compatible upload) and the composite action tying them together, matching weblib-ci's shape. zipalign is not a standalone nixpkgs attribute; resolved by measurement rather than assumption that Gradle/AGP already aligns its output (Android's own docs, corroborated by fdroidserver never shelling out to zipalign) and added check_zip_alignment.py as the safety net, since apksigner itself does not check alignment at all. nixpkgs is pinned via a committed nixpkgs-pin revision, since this repo has no flake.lock of its own for with-nixpkgs.sh to read (fdroid-repo-ci#1, weblib-ci#9) -- a missing or malformed pin fails loudly rather than degrading to an unpinned nix shell. No consumer repo, bucket, hostname or channel name is hard-coded: which repo holds the keys and runs the publish has already changed once during this issue and may again, so every example uses a placeholder. 42 offline/local-only test assertions across five suites (run_tests.sh), including fault injection on the alignment check, the password/argument validation, and the with-nixpkgs.sh fail-loud paths. Co-authored-by: bit <bit@das-labor.org>
This commit is contained in:
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Offline tests for with-nixpkgs.sh's fail-loud paths. Deliberately does not
|
||||
# exercise the happy path here -- resolving a real `github:nixos/nixpkgs/...`
|
||||
# reference needs network (or an already-warm local cache) the same way
|
||||
# weblib-ci's own with-nixpkgs.sh does, and weblib-ci does not carry an
|
||||
# automated test for that half either. It was measured by hand instead (see
|
||||
# the PR description) by running `with-nixpkgs.sh apksigner apksigner
|
||||
# version` and `with-nixpkgs.sh "fdroidserver jdk21 apksigner" bash -c
|
||||
# 'which fdroid jarsigner apksigner'` and reading the resolved store paths
|
||||
# back.
|
||||
#
|
||||
# What *is* fully offline and belongs in an automated suite: every way this
|
||||
# script is supposed to refuse rather than silently fall back to an unpinned
|
||||
# `nix shell nixpkgs#foo` -- none of these reach `nix` at all, so they run
|
||||
# with no network and no local nix store required.
|
||||
set -euo pipefail
|
||||
here=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
source "$here/test_lib.sh"
|
||||
|
||||
work=$(mktemp -d)
|
||||
trap 'rm -rf "$work"' EXIT
|
||||
|
||||
# --- too few arguments -------------------------------------------------
|
||||
assert_failure "too few args exits non-zero" \
|
||||
bash "$here/with-nixpkgs.sh" onlyoneattr
|
||||
|
||||
# --- missing pin file ---------------------------------------------------
|
||||
mkdir -p "$work/no-pin"
|
||||
cp "$here/with-nixpkgs.sh" "$work/no-pin/"
|
||||
out=$(bash "$work/no-pin/with-nixpkgs.sh" apksigner true 2>&1) && rc=0 || rc=$?
|
||||
if [ "${rc:-0}" -ne 0 ]; then pass "missing pin exits non-zero"; else fail "missing pin exits non-zero (got 0)"; fi
|
||||
assert_contains "missing pin names the problem, not a stack trace" "$out" "no $work/no-pin/nixpkgs-pin"
|
||||
assert_contains "missing pin says it refuses to fall back" "$out" "refusing to fall back"
|
||||
|
||||
# --- malformed pin (not 40 hex chars) -----------------------------------
|
||||
mkdir -p "$work/bad-pin"
|
||||
cp "$here/with-nixpkgs.sh" "$work/bad-pin/"
|
||||
echo "not-a-revision" > "$work/bad-pin/nixpkgs-pin"
|
||||
out=$(bash "$work/bad-pin/with-nixpkgs.sh" apksigner true 2>&1) && rc=0 || rc=$?
|
||||
if [ "${rc:-0}" -ne 0 ]; then pass "malformed pin exits non-zero"; else fail "malformed pin exits non-zero (got 0)"; fi
|
||||
assert_contains "malformed pin names what's wrong" "$out" "does not hold a 40-character"
|
||||
|
||||
# --- a well-formed pin is accepted up to the point of invoking nix ------
|
||||
# (proves the regex/parsing logic itself, without needing nix on PATH or
|
||||
# reachable: a bogus command name still gets past validation and only fails
|
||||
# once nix actually tries to run it.)
|
||||
mkdir -p "$work/good-pin"
|
||||
cp "$here/with-nixpkgs.sh" "$work/good-pin/"
|
||||
echo "0123456789abcdef0123456789abcdef01234567" > "$work/good-pin/nixpkgs-pin"
|
||||
out=$(bash "$work/good-pin/with-nixpkgs.sh" apksigner true 2>&1) && rc=0 || rc=$?
|
||||
# whatever happens next is nix's business (missing binary, no network,
|
||||
# etc) -- the point is it got *past* this script's own validation, i.e. it
|
||||
# must not repeat either of the loud-failure messages above.
|
||||
if [[ "$out" != *"refusing to fall back"* ]] && [[ "$out" != *"does not hold a 40-character"* ]]; then
|
||||
pass "well-formed pin passes this script's own validation"
|
||||
else
|
||||
fail "well-formed pin passes this script's own validation (got: $out)"
|
||||
fi
|
||||
|
||||
report_and_exit
|
||||
Reference in New Issue
Block a user