Files
calendula/docs/fdroid-official
Jean-Luc Makiola 5c80f99179
All checks were successful
CI / ci (pull_request) Successful in 5m57s
build(fdroid): drop AGP dependency-metadata block; release v2.7.5
F-Droid's binary scanner (the fdroiddata `check apk` job) rejects any
"extra signing block". Our release APK carried AGP's dependency-metadata
block (id 0x504b4453, ~8 KB) in the APK Signing Block. Disable it with
`dependenciesInfo { includeInApk = false; includeInBundle = false }`.

The block lives in the signing block, not the zip entries, so removing it
changes no build output — v2.7.5 is functionally identical to 2.7.4 and
still reproduces byte-for-byte. Verified locally: a releaseTest build now
carries only the v2 signature + verity padding (no 0x504b4453 block).

This was the last F-Droid blocker: v2.7.5 now clears vcsInfo (since 2.7.3),
foojay (since 2.7.4) and the dependency-metadata block. Bumps versionName
to 2.7.5 and retargets the official recipe draft at v2.7.5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 20:48:59 +02:00
..

Official F-Droid submission (draft)

Goal: publish Calendula to the official F-Droid repo alongside the self-hosted repo, as one app — same signed binary in both channels, so existing self-hosted users migrate with no reinstall and no data loss.

This folder holds the draft fdroiddata recipe. Nothing here is submitted yet. The self-hosted pipeline (../../fdroid-metadata/, .gitea/workflows/release.yaml) is unaffected by these files.

Publishing model: reproducible build + developer-signed binary

F-Droid builds Calendula from source on its buildserver, then verifies the output is byte-for-byte identical to our signed APK (fetched via the Binaries URL). On a match it publishes our binary, signed with our key — identified by AllowedAPKSigningKeys. Result: official and self-hosted both carry the same signature. If a build ever fails to match, F-Droid simply skips that version (fails safe — no bad publish).

Verification status (2026-06-21)

  • Run-to-run reproduciblev2.7.0 built twice from a clean worktree (R8 minify + resource-shrink, build cache off) → byte-for-byte identical (sha256 568c944a…).
  • Cross-JDK reproducible — rebuilt with JDK 17 and JDK 21 → identical APK. JDK version is not a sensitivity, so it need not be pinned.
  • Tag self-consistent — committed versionCode/versionName already equal the tag-derived values, so F-Droid building the tag as-is matches the CI-published binary (CI's sed substitution is a no-op).
  • App signing cert SHA-256 extracted from published APKs (identical across v1.0.0 / v2.0.0 / v2.4.0): 5cdaee8e…. No keystore needed.
  • Eligibility — MIT, 100% FOSS deps (no Play Services / Firebase / analytics / billing), no INTERNET permission, no native code.
  • End-to-end reproducible vs the DISTRIBUTED binary — built tag v2.7.1 from source and compared against the published calendula_v2.7.1.apk: every app entry (dex / resources / assets / manifest) byte-identical. The only difference was META-INF/version-control-info.textproto (AGP's git metadata, env-dependent). Fixed with vcsInfo { include = false } on the release build; re-validated → 0 non-signature differences. Takes effect from the first release built after that change — submit the recipe starting at that version (v2.7.1 and earlier still embed the textproto and won't verify).
  • ⚠️ Not yet proven: cross-host / fixed-build-path reproducibility on F-Droid's buildserver (low risk for a no-NDK pure-JVM app; with vcsInfo disabled, the env-dependent field is gone; F-Droid confirms at review).
  • Buildserver toolchain supported (checked 2026-06-21):
    • Gradle 9.5.1 is in F-Droid's gradle-transparency-log (checksums.json) with a verified sha256, so gradlew.py will download + verify + run it.
    • AGP 9.2 is in gradlew.py's MIN_GRADLE_VERSION map (9.2 -> 9.4.1).
    • JDK 17 is standard on the buildserver (AGP 9.2 requires exactly 17).
    • build-tools 36.0.0 / android-37: not statically preinstalled (baseline stops at 33), but provision-android-sdk makes $ANDROID_HOME/build-tools and /platforms group-writable so AGP/Gradle install newer ones on demand.

Before submitting — checklist

  1. Confirm the Binaries URL is publicly reachable and stable long-term, e.g. https://apps.dev.jeanlucmakiola.de/dev/fdroid/repo/calendula_v2.7.0.apk resolves to the dev-signed APK. F-Droid re-fetches it on every build.
  2. Confirm F-Droid's buildserver supports the toolchain (see timing risk).
  3. (Recommended) Reproduce one published release end-to-end: build the tag from source, strip signatures, and diff against the downloaded calendula_v<ver>.apk to confirm the from-source build matches the distributed binary — not just another local build.

Submission steps (fdroiddata, GitLab)

  1. Fork https://gitlab.com/fdroid/fdroiddata.
  2. Copy de.jeanlucmakiola.calendula.yml to metadata/ in the fork.
  3. Test locally with fdroid build -v de.jeanlucmakiola.calendula and fdroid lint de.jeanlucmakiola.calendula (and fdroid readmeta).
  4. Open a Merge Request. Initial review can take weeks to months; the self-hosted repo keeps serving in the meantime, so there's no rush.

Listing metadata (descriptions, screenshots, icon)

These are not in the recipe .yml. F-Droid's fdroid update harvests them automatically from the fastlane tree in the app's source repo:

fastlane/metadata/android/<locale>/
  short_description.txt   full_description.txt   title.txt
  images/icon.png         images/phoneScreenshots/*.png
  changelogs/<versionCode>.txt   (optional, per release)

This is the single source of truth: en-US + de-DE already exist there, and the self-hosted repo is generated from the same tree at release time via scripts/fastlane_to_fdroid_localized.sh. Nothing extra to add to fdroiddata — F-Droid picks the listing up from source. (Screenshots may not be committed to the fdroiddata repo anyway, so the source-tree fastlane layout is required.)

Per-version changelogs: the self-hosted release workflow generates changelogs/<versionCode>.txt at release time. For the official repo to show a changelog, that file must be committed into fastlane/metadata/android/<locale>/changelogs/ at the tagged commit — wire this into the release/version-bump step, or accept no in-client changelog for the official listing initially.