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
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Run a command with one or more nixpkgs packages on PATH, pinned to the
|
||||
# revision recorded in `nixpkgs-pin`, next to this script.
|
||||
#
|
||||
# bash with-nixpkgs.sh apksigner apksigner verify --print-certs app.apk
|
||||
# bash with-nixpkgs.sh "fdroidserver jdk21 apksigner" fdroid update
|
||||
#
|
||||
# A space-separated list of attributes puts all of them on PATH at once, via
|
||||
# multiple `nix shell` installables in one call -- `fdroid update` shells out
|
||||
# to `jarsigner`/`keytool` (JDK) and `apksigner` itself, so a single package
|
||||
# is not always enough.
|
||||
#
|
||||
# **Call it as `bash <script>`, not `<script>`.** The runner has no
|
||||
# `/usr/bin/env`, so the shebang cannot be relied on there -- the same trap
|
||||
# weblib-ci's with-nixpkgs.sh documents.
|
||||
#
|
||||
# ## Why this is not a copy of weblib-ci's with-nixpkgs.sh
|
||||
#
|
||||
# That script reads *the consuming repo's* `./flake.lock`, relative to the
|
||||
# working directory, so the pin travels with whatever project vendors it.
|
||||
# This repo has no flake.lock of its own -- deliberately; see weblib-ci#9,
|
||||
# which is the same tension one repo over: a `flake.lock` would exist only to
|
||||
# hold one 40-character string, for a repo whose README says it is *run*, not
|
||||
# built. And per fdroid-repo-ci#1, the repo that consumes this one holds
|
||||
# signing keys and is not guaranteed to be a flake at all, so reading a
|
||||
# caller's flake.lock the way weblib-ci's script does would not even find one
|
||||
# to read here.
|
||||
#
|
||||
# So the pin travels with *this* repo instead, in a file named `nixpkgs-pin`
|
||||
# on purpose: it is the exact fallback weblib-ci#9 proposes adding to the
|
||||
# shared script (`./flake.lock` present -> today's behaviour there; else
|
||||
# `./nixpkgs-pin` -> a bare rev; else fail loudly). If that lands, this repo
|
||||
# already speaks its format and nothing here needs to change.
|
||||
#
|
||||
# `fdroidserver`'s output feeds a *signed index* (fdroid-repo-ci#1), so a
|
||||
# drifting nixpkgs is a worse trade here than for a disposable test job --
|
||||
# unlike weblib-ci#9's stdlib-only 1.2s suite, this pin is load-bearing. A
|
||||
# missing or malformed pin is therefore a hard failure, never a silent fall
|
||||
# back to `nix shell nixpkgs#foo`, which would re-resolve the registry and
|
||||
# fetch whatever the channel currently points at -- measured to cost an
|
||||
# unpacked channel tarball in weblib-ci's own job log.
|
||||
set -euo pipefail
|
||||
|
||||
here=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
pin="$here/nixpkgs-pin"
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
echo "usage: $0 <nixpkgs attribute(s), space-separated> <command> [args...]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
attrs=$1
|
||||
shift
|
||||
|
||||
if [ ! -f "$pin" ]; then
|
||||
echo "$0: no $pin -- refusing to fall back to an unpinned nix shell nixpkgs#<attr>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rev=$(tr -d ' \t\n' < "$pin")
|
||||
if ! [[ "$rev" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "$0: $pin does not hold a 40-character git revision (got '$rev')" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
refs=()
|
||||
for attr in $attrs; do
|
||||
refs+=("github:nixos/nixpkgs/${rev}#${attr}")
|
||||
done
|
||||
|
||||
exec nix shell "${refs[@]}" --command "$@"
|
||||
Reference in New Issue
Block a user