Document and hint at the APK-filename/versionCode naming contract

publish.sh's overwrite guard (fdroid-repo-ci#6) is correct but implies a
contract nothing states: a colliding filename with no versionCode in it
means only the first publish into a prefix can ever succeed. Flutter's
constant app-<flavor>-release.apk hit this in weblib-viewer (#29), and the
failure only surfaces on the second publish with an error that reads like a
bucket-state problem.

Add the naming contract to the README, and append a hint to the refusal
message when the colliding object's basename has no digits at all -- a
pure text addition, never changing which publishes are refused.

Closes fdroid-repo-ci#13.

Co-authored-by: bit <bit@das-labor.org>
This commit is contained in:
2026-09-10 02:00:30 +00:00
co-authored by bit
parent 760583b7e3
commit af32b7ca12
3 changed files with 74 additions and 0 deletions
+22
View File
@@ -272,6 +272,28 @@ collision; it prevents the collision from silently corrupting the repo.
Skipped entirely for a plain `--index-only` invocation (below), since that
pass can never upload a `*.apk` in the first place.
### APK filenames must carry the versionCode (fdroid-repo-ci#13)
That guard is correct -- a published versionCode's artifact has to stay
immutable -- but it has a consequence nothing else here states: **the
filename has to carry the versionCode**, or the guard permits exactly one
publish into a prefix, ever. `publish.sh` checks the destination *key*, not
the artifact's contents, so a build that always emits the same filename
collides with itself on its second run regardless of what actually changed
inside the APK.
Name the APK `<applicationId>_<versionCode>.apk` -- F-Droid's own
convention, and what `fdroid update` expects -- before handing it to
`fdroid-update.sh`/`publish.sh`. Concretely: Flutter's
`flutter build apk` always emits `app-<flavor>-release.apk`, independent of
`--build-number`, so a consumer that publishes that path unchanged gets a
successful first publish and then a permanent refusal on every publish
after it -- exactly what happened to weblib-viewer (weblib-viewer#29) before
it started renaming the artifact to `<applicationId>_<versionCode>.apk`
ahead of this step. The failure only shows up on the *second* publish, long
after the integration looks finished, and reads like a bucket-state problem
(see the error text below) rather than the naming contract it actually is.
### `--files-only` and `--index-only`
The two passes can also be run as two separate invocations: