Document the APK filename/versionCode naming contract #14

Merged
bit merged 1 commits from apk-versioncode-naming-contract into main 2026-09-13 08:01:21 +00:00
Member

What

publish.sh's overwrite guard (fdroid-repo-ci#6) is correct -- a published versionCode's artifact must stay immutable -- but nothing tells a consumer that this implies the filename has to carry the versionCode. A build that always emits the same filename (Flutter's app-<flavor>-release.apk, independent of --build-number) gets exactly one successful publish into a prefix, ever, and every publish after that fails with a message that reads like a bucket-state problem rather than a naming contract. weblib-viewer hit this for real (weblib-viewer#29) and it cost a full CI cycle to diagnose, because the failure only shows up on the second publish.

bit replied "Both" on the issue, so this implements both options it proposed:

  1. README: a new subsection states the naming contract -- <applicationId>_<versionCode>.apk, F-Droid's own convention -- with the Flutter/weblib-viewer#29 case spelled out concretely.
  2. Better refusal message: when the colliding object's basename contains no digits at all, publish.sh appends a hint pointing at the naming convention. This is a pure text addition -- the guard's control flow is untouched. A filename with digits that still collides keeps refusing with exactly today's message; a filename with no digits still gets refused, just with an extra line explaining why that is very likely to keep happening.

Not touched

No override, bypass or weakening of the overwrite guard -- it behaved correctly and caught a real overwrite. This is discoverability only.

Testing

Baseline was 104 passed / 4 skipped / 0 failed. Added assertions for both branches of the new heuristic (colliding filename with digits -> no hint; without digits -> hint present, still exits non-zero) plus the existing collision/negative-control/--index-only cases untouched. Full suite (run_tests.sh) now reports 111 passed / 4 skipped / 0 failed -- the 4 skips are the opt-in live-bucket tests, same as baseline.

Closes #13.

## What `publish.sh`'s overwrite guard (fdroid-repo-ci#6) is correct -- a published versionCode's artifact must stay immutable -- but nothing tells a consumer that this implies **the filename has to carry the versionCode**. A build that always emits the same filename (Flutter's `app-<flavor>-release.apk`, independent of `--build-number`) gets exactly one successful publish into a prefix, ever, and every publish after that fails with a message that reads like a bucket-state problem rather than a naming contract. weblib-viewer hit this for real (weblib-viewer#29) and it cost a full CI cycle to diagnose, because the failure only shows up on the *second* publish. bit replied "Both" on the issue, so this implements both options it proposed: 1. **README**: a new subsection states the naming contract -- `<applicationId>_<versionCode>.apk`, F-Droid's own convention -- with the Flutter/weblib-viewer#29 case spelled out concretely. 2. **Better refusal message**: when the colliding object's basename contains no digits at all, `publish.sh` appends a hint pointing at the naming convention. This is a pure text addition -- the guard's control flow is untouched. A filename with digits that still collides keeps refusing with exactly today's message; a filename with no digits still gets refused, just with an extra line explaining why that is very likely to keep happening. ## Not touched No override, bypass or weakening of the overwrite guard -- it behaved correctly and caught a real overwrite. This is discoverability only. ## Testing Baseline was 104 passed / 4 skipped / 0 failed. Added assertions for both branches of the new heuristic (colliding filename with digits -> no hint; without digits -> hint present, still exits non-zero) plus the existing collision/negative-control/`--index-only` cases untouched. Full suite (`run_tests.sh`) now reports **111 passed / 4 skipped / 0 failed** -- the 4 skips are the opt-in live-bucket tests, same as baseline. Closes #13.
claude added 1 commit 2026-09-10 02:00:51 +00:00
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>
bit merged commit c529ca9564 into main 2026-09-13 08:01:21 +00:00
bit deleted branch apk-versioncode-naming-contract 2026-09-13 08:01:22 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weblib/fdroid-repo-ci#14