Fix release APK signing, and stop the two jobs interleaving

5b6cd9c · Gabriel Morell · 2026-09-12 17:57

7 files +31 -2
Message
{commit_body(@commit)}

Files changed

modified .forgejo/workflows/build.yml
+9 −1
@@ -173,7 +173,15 @@ jobs:
173 173 # lives in OpenBao and never comes near CI — see docs/fdroid-registry.md.
174 174 android:
175 175 runs-on: self-hosted
176 − needs: [build]
176 + # After `deb` rather than beside it. Both drive `docker buildx` on
177 + # the same self-hosted runner, so running them together interleaves
178 + # their output into one unreadable log — and has them competing for
179 + # the same daemon and build cache besides.
180 + #
181 + # The cost is that a broken .deb now blocks publishing the APK, for
182 + # two jobs that are otherwise independent. Worth it while there is
183 + # one runner; drop back to `needs: [build]` when there are two.
184 + needs: [build, deb]
177 185 steps:
178 186 - uses: actions/checkout@v4
179 187
modified android/Dockerfile
+9 −1
@@ -83,6 +83,15 @@ RUN ./gradlew --no-daemon :app:assembleRelease
83 83 # zipalign before apksigner, not after: aligning rewrites offsets, and
84 84 # doing it to an already-signed APK invalidates the v2 signature that
85 85 # covers them.
86 +#
87 +# No --key-pass. apksigner reads each `file:` password as a *sequential*
88 +# read from that file, so passing the same one-line file to both
89 +# --ks-pass and --key-pass makes the second read hit EOF:
90 +#
91 +# Failed to read Key "gitgud" password: end of file reached
92 +#
93 +# Omitted, the key password defaults to the store password, which is
94 +# what PKCS12 keystores use anyway.
86 95 RUN --mount=type=secret,id=keystore,target=/tmp/release.jks \
87 96 --mount=type=secret,id=keystore_password,target=/tmp/keystore.pass \
88 97 set -eu; \
@@ -93,7 +102,6 @@ RUN --mount=type=secret,id=keystore,target=/tmp/release.jks \
93 102 "${tools}/apksigner" sign \
94 103 --ks /tmp/release.jks \
95 104 --ks-pass "file:/tmp/keystore.pass" \
96 − --key-pass "file:/tmp/keystore.pass" \
97 105 --out /out/app-release.apk \
98 106 /tmp/aligned.apk; \
99 107 "${tools}/apksigner" verify --print-certs /out/app-release.apk
modified android/app/build.gradle.kts
+13 −0
@@ -34,6 +34,19 @@ android {
34 34 buildFeatures {
35 35 compose = true
36 36 }
37 +
38 + lint {
39 + // `assembleRelease` is a packaging step here, not a review gate.
40 + //
41 + // lintVital doubles the release build and fails for reasons that
42 + // have nothing to do with the code: AGP 8.5's lint throws on
43 + // JDK 25 with only the version string ("25.0.4.1") as the error,
44 + // so a release built on a modern local JDK fails while the same
45 + // commit builds fine in CI's JDK 17 container.
46 + //
47 + // Lint still runs on demand: ./gradlew :app:lint
48 + checkReleaseBuilds = false
49 + }
37 50 packaging {
38 51 resources {
39 52 excludes += "/META-INF/{AL2.0,LGPL2.1}"

Parents: 97698e4