Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ what it replaced, and the second round of tapping is always the expensive one.
- The version is the git tag, not a number in the tree. `AndroidManifest.xml` carries no
`versionCode`/`versionName`; `app/build.gradle` derives both from `-Podr.version`
(`v4.8.0` -> name `4.8.0`, code `40800`, two digits per part, parts above 99 are an
error), and a build handed no version is `0.0.0`. Do not put the attributes back in the
error), and a build handed no version is `0.0.0`. All three parts are required: a
two-part `v4.7` was once padded to `4.7.0`, which let one build carry two names and is
why the tags before `v4.8.0` are in two formats. Do not put the attributes back in the
manifest: gradle's values win in the merged manifest, so a second copy can only ever
disagree with the tag. The release workflow passes the tag it ran on; a dispatched run
passes its `version` input
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ which the build refuses rather than folding `4.100.0` onto the same code as `5.0
Nothing has to be raised by hand before tagging, and no number on `main` can describe a
release that already went out.

All three parts have to be spelled out. A two-part `v4.7` used to be padded to `4.7.0`,
which meant one build could be tagged under two names, and the tags older than `v4.8.0`
are in both formats because of it. They are left as they are - a release asset is served
from a URL carrying its tag name, and F-Droid rebuilds old versions from those names -
so the rule only holds for what is tagged from here on.

Builds handed no version - local ones, PR builds, `assembleProDebug` - are `0.0.0`.
Nothing reads it: no code in the app looks at its own version, and only what the release
workflow builds ever leaves the machine. Any build can be given a real one anyway, with
Expand Down
11 changes: 6 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ def hasReleaseSigning = releaseKeystore.isPresent() && releaseKeystorePassword.i
def parseVersion = { String version ->
// split rather than tokenize, which would swallow the empty part in '4..8'
def parts = (version - ~/^v/).split('\\.', -1) as List
if (parts.isEmpty() || parts.size() > 3 || !parts.every { it ==~ /\d+/ }) {
// all three parts, spelled out. a missing one used to be padded with a zero, so
// 'v4.7' and 'v4.7.0' were the same build under two names - which is how the tags
// ended up in two formats. the padding is gone rather than the spelling made a
// convention, because a convention cannot fail the build
if (parts.size() != 3 || !parts.every { it ==~ /\d+/ }) {
throw new GradleException(
"odr.version must look like 4.8 or v4.8.0, not '${version}'")
"odr.version must look like 4.8.0 or v4.8.0, not '${version}'")
}
def numbers = parts*.toInteger()
while (numbers.size() < 3) {
numbers << 0
}
// two digits per component: v4.8.0 is 40800. That is a one way step past the codes
// that used to be counted by hand (204 and below) - the play store accepts a higher
// code than the last one it saw and never a lower one.
Expand Down
Loading