Skip to content

fix(app): pin AboutLibraries license JSON so F-Droid reproduces - #90

Merged
vitofico merged 1 commit into
mainfrom
fix/aboutlibraries-reproducible
Jul 13, 2026
Merged

fix(app): pin AboutLibraries license JSON so F-Droid reproduces#90
vitofico merged 1 commit into
mainfrom
fix/aboutlibraries-reproducible

Conversation

@vitofico

Copy link
Copy Markdown
Owner

Problem

F-Droid's reproducible-build verification failed for v2026.07.10.218. The build itself succeeded — only the copied-signature integrity check failed, and the sole differing file was:

res/M7.json  (AboutLibraries license list, res/raw/aboutlibraries.json renamed by resource shrinking)

Root cause

The AboutLibraries build-time collector scans whatever dependency configurations happen to be resolvable in a given build, so the embedded library set is not reproducible:

Build environment Library count Notes
Our published APK 55+ leaked debug/test artifacts (ui-tooling, ui-test-manifest)
F-Droid's isolated builder 31 under-collected — missing even release transitives like androidx.core
Clean local build 175 everything

The existing excludeFields = arrayOf("generated") fixed the build-timestamp but not this membership drift.

Fix

Stop generating the resource at build time and check in a pre-generated, release-only JSON, so every builder (dev, CI, F-Droid) packages byte-identical bytes:

  • registerAndroidTasks = false — plugin no longer generates into the APK
  • filterVariants = arrayOf("release") — keeps the regenerated file release-scoped
  • committed app/src/main/res/raw/aboutlibraries.json (178 libs) → R.raw.aboutlibraries, which LibrariesContainer in LicensesScreen already reads (in-app Licenses screen unchanged)
  • CI drift check regenerates and diffs, failing if the committed file goes stale after a dependency change

Regenerate with:

scripts/dgradle :app:exportLibraryDefinitions \
  -PaboutLibraries.exportVariant=release \
  -PaboutLibraries.exportPath=src/main/res/raw

Verification

  • Three consecutive exports are byte-identical (sha 3053e3b1) — deterministic
  • Release APK's res/M7.json matches the committed source exactly (sha 3053e3b1)
  • Committed JSON is release-scoped: no ui-tooling / ui-test-manifest / unit-test libs; timestamp-free
  • The PR's own CI drift-check run doubles as the cross-environment determinism test (dgradle vs GitHub runner)

Note

v218 is already published and immutable — F-Droid won't verify it retroactively. This makes the next release reproducible; that's the first tag where the check should pass.

F-Droid's reproducible-build verification failed for v2026.07.10.218:
the only differing file was res/M7.json — the AboutLibraries-generated
license list (res/raw/aboutlibraries.json, renamed by resource
shrinking). Its library set is not reproducible because the plugin's
build-time collector scans whatever dependency configurations happen to
be resolvable in a given build: debug/test artifacts (ui-tooling,
ui-test-manifest) leaked into our published APK (55+ libs) while
F-Droid's isolated builder under-collected (31 libs, missing even
release transitives like androidx.core). A clean local build produced a
third set (175). excludeFields=["generated"] fixed the timestamp but not
this membership drift.

Fix: stop generating the resource at build time (registerAndroidTasks =
false) and check in a pre-generated, release-only JSON. Every builder now
packages byte-identical bytes. Verified: three consecutive exports are
byte-identical (sha 3053e3b1), and the release APK's res/M7.json matches
the committed source exactly. filterVariants=["release"] keeps the
regenerated file release-scoped; a CI drift check fails if it goes stale.

The already-published v218 APK is immutable, so this makes the next
release reproducible, not that one.
@vitofico
vitofico merged commit 295335f into main Jul 13, 2026
6 of 7 checks passed
@vitofico
vitofico deleted the fix/aboutlibraries-reproducible branch July 13, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant