diff options
| author | Lena <lena@omega> | 2026-08-16 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-08-16 00:00:00 +0000 |
| commit | 8c6390571d28ff21a98ed3802458aceddbb6d2a0 (patch) | |
| tree | 1903e6a19389b127d4857f20a8cf06195d68daae /ci/verify-repro.sh | |
| parent | 0e8a87f2ad2bd40d34996374aebb6dff070e4b5f (diff) | |
| download | rsend-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-x | ci/verify-repro.sh | 51 |
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 |