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>
62 lines
3.1 KiB
Bash
Executable File
62 lines
3.1 KiB
Bash
Executable File
#!/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
|