aboutsummaryrefslogtreecommitdiff
path: root/ci/verify-repro.sh
diff options
context:
space:
mode:
authorLena <lena@omega>2026-08-16 00:00:00 +0000
committerLena <lena@omega>2026-08-16 00:00:00 +0000
commit8c6390571d28ff21a98ed3802458aceddbb6d2a0 (patch)
tree1903e6a19389b127d4857f20a8cf06195d68daae /ci/verify-repro.sh
parent0e8a87f2ad2bd40d34996374aebb6dff070e4b5f (diff)
downloadrsend-8c6390571d28ff21a98ed3802458aceddbb6d2a0.tar.gz
build: pin and verify release inputs
Support Alpine/musl and Debian/glibc hosts, lock downloaded and Gradle artifacts, and verify native and APK security properties.
Diffstat (limited to 'ci/verify-repro.sh')
-rwxr-xr-xci/verify-repro.sh51
1 files changed, 37 insertions, 14 deletions
diff --git a/ci/verify-repro.sh b/ci/verify-repro.sh
index 580ccd0..605ec77 100755
--- a/ci/verify-repro.sh
+++ b/ci/verify-repro.sh
@@ -1,26 +1,49 @@
#!/bin/sh
-# Build the complete unsigned APK twice and compare it byte for byte.
+# Build the same committed source in two different absolute paths and compare
+# the unsigned APKs byte for byte.
set -eu
-root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
-a=$(mktemp -d)
-b=$(mktemp -d)
-trap 'rm -rf "$a" "$b"' 0
+root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
+# shellcheck source=versions
+. "$root/versions"
+tmp=$(mktemp -d)
+trap 'rm -rf "$tmp"' 0 1 2 3 15
+a="$tmp/a/src"
+b="$tmp/a-much-longer-path/b/src"
-[ ! -f "$root/keystore.properties" ] || {
- echo "verify-repro: keystore.properties must be absent" >&2
+git -C "$root" diff --quiet
+git -C "$root" diff --cached --quiet
+status=$(git -C "$root" status --porcelain --untracked-files=normal)
+[ -z "$status" ] || {
+ echo "verify-repro: tracked and untracked source must be clean" >&2
exit 1
}
-make -C "$root" app
-cp "$root/app/build/outputs/apk/release/app-release-unsigned.apk" "$a/app.apk"
+mkdir -p "$a" "$b"
+archive="$tmp/source.tar"
+git -C "$root" archive --format=tar HEAD > "$archive"
+tar -xf "$archive" -C "$a"
+tar -xf "$archive" -C "$b"
-rm -rf "$root/app/build" "$root/app/src/main/jniLibs" "$root/rsync/work" "$root/out"
-make -C "$root" app
-cp "$root/app/build/outputs/apk/release/app-release-unsigned.apk" "$b/app.apk"
+# Reuse a locally cached, verified source tarball when present. Otherwise the
+# first build fetches it and the second consumes that exact verified file.
+tarball="rsync/rsync-${RSYNC_VERSION}.tar.gz"
+if [ -f "$root/$tarball" ]; then
+ ( cd "$root/rsync" && sha256sum -c "rsync-${RSYNC_VERSION}.tar.gz.sha256" )
+ cp "$root/$tarball" "$a/$tarball"
+ cp "$root/$tarball" "$b/$tarball"
+fi
+
+make -C "$a" app
+if [ ! -f "$b/$tarball" ]; then
+ cp "$a/$tarball" "$b/$tarball"
+fi
+make -C "$b" app
-if cmp "$a/app.apk" "$b/app.apk"; then
- echo "verify-repro: APKs are bit-identical"
+first="$a/app/build/outputs/apk/release/app-release-unsigned.apk"
+second="$b/app/build/outputs/apk/release/app-release-unsigned.apk"
+if cmp "$first" "$second"; then
+ echo "verify-repro: APKs are bit-identical across different paths"
else
echo "verify-repro: NONDETERMINISM detected" >&2
exit 1