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>
67 lines
1.6 KiB
Bash
67 lines
1.6 KiB
Bash
# Shared assertion helpers for the shell test scripts. Sourced, not run.
|
|
#
|
|
# Each test_*.sh increments PASS_COUNT/FAIL_COUNT/SKIP_COUNT as it goes and
|
|
# prints one line per check, so a caller sees passed/skipped/failed as
|
|
# separate numbers rather than a single pass/fail verdict -- a skip must
|
|
# never read as a pass.
|
|
|
|
PASS_COUNT=0
|
|
FAIL_COUNT=0
|
|
SKIP_COUNT=0
|
|
|
|
pass() { PASS_COUNT=$((PASS_COUNT + 1)); echo "PASS: $1"; }
|
|
fail() { FAIL_COUNT=$((FAIL_COUNT + 1)); echo "FAIL: $1" >&2; }
|
|
skip() { SKIP_COUNT=$((SKIP_COUNT + 1)); echo "SKIP: $1"; }
|
|
|
|
assert_success() {
|
|
# assert_success <label> <command...>
|
|
local label=$1; shift
|
|
if "$@" >/tmp/assert_out.$$ 2>&1; then
|
|
pass "$label"
|
|
else
|
|
fail "$label (exit $?, see /tmp/assert_out.$$)"
|
|
cat /tmp/assert_out.$$ >&2
|
|
fi
|
|
rm -f /tmp/assert_out.$$
|
|
}
|
|
|
|
assert_failure() {
|
|
# assert_failure <label> <command...> -- must exit non-zero
|
|
local label=$1; shift
|
|
if "$@" >/tmp/assert_out.$$ 2>&1; then
|
|
fail "$label (expected non-zero exit, got 0)"
|
|
cat /tmp/assert_out.$$ >&2
|
|
else
|
|
pass "$label"
|
|
fi
|
|
rm -f /tmp/assert_out.$$
|
|
}
|
|
|
|
assert_file_exists() {
|
|
local label=$1 path=$2
|
|
if [ -s "$path" ]; then
|
|
pass "$label"
|
|
else
|
|
fail "$label (missing or empty: $path)"
|
|
fi
|
|
}
|
|
|
|
assert_contains() {
|
|
# assert_contains <label> <haystack-file-or-string> <needle>
|
|
local label=$1 haystack=$2 needle=$3
|
|
if [ -f "$haystack" ]; then
|
|
haystack=$(cat "$haystack")
|
|
fi
|
|
if [[ "$haystack" == *"$needle"* ]]; then
|
|
pass "$label"
|
|
else
|
|
fail "$label (expected to find '$needle')"
|
|
fi
|
|
}
|
|
|
|
report_and_exit() {
|
|
echo
|
|
echo "passed=$PASS_COUNT skipped=$SKIP_COUNT failed=$FAIL_COUNT"
|
|
[ "$FAIL_COUNT" -eq 0 ]
|
|
}
|