Skip to content

Commit 59f79ba

Browse files
authored
Makefile, build.gradle: switch back to wall-clock playstore versioning (#831)
Makefile, build.gradle: switch to wall-clock playstore versioning updates tailscale/android# Our strategy of using the tailscale version to derive a playstore version has a flaw in that an uploaded unstable prevents us from bumping our stable releases since the new derived version doesn't respect the versions-shall-increment rule. Instead, let's just use a version derived from the timestamp when we bump or tag. Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
1 parent 1e7afb4 commit 59f79ba

3 files changed

Lines changed: 46 additions & 18 deletions

File tree

Makefile

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,12 @@ $(RELEASE_AAB): version gradle-dependencies
165165
(cd android && ./gradlew test bundleRelease)
166166
install -C ./android/build/outputs/bundle/release/android-release.aab $@
167167

168-
# PLATFORM=tv signals to gradle that we should build for AndroidTV. To
169-
# distinguish the TV variant from the phone/tablet build in the Play Store,
170-
# we temporarily increment the versionCode in android/build.gradle by 1 for
171-
# the duration of the build, then restore the original value via a shell trap
168+
# PLATFORM=tv signals to gradle that we should build for AndroidTV. The stamped
169+
# versionCode reserves its last digit for the variant: phone/tablet builds end
170+
# in 0 and TV builds end in 1, so the two are distinguishable in the Play Store.
171+
# build.gradle keeps a bare integer literal (external tooling greps it), so we
172+
# add the +1 here: temporarily increment the versionCode in android/build.gradle
173+
# for the duration of the build, then restore the original value via a shell trap
172174
# so the working tree is left clean even if the gradle build fails.
173175
$(RELEASE_TV_AAB): version gradle-dependencies
174176
@echo "Building TV release AAB"
@@ -310,14 +312,25 @@ bumposs: update-oss tailscale.version bump-version-code
310312
source tailscale.version && git commit -sm "android: bump OSS" -m "OSS and Version updated to $${VERSION_LONG}" go.toolchain.rev android/build.gradle go.mod go.sum
311313
source tailscale.version && git tag -a "$${VERSION_LONG}" -m "OSS and Version updated to $${VERSION_LONG}"
312314

313-
# Recomputes the base versionCode from tailscale.version and rewrites the
314-
# `versionCode <n>` line in android/build.gradled
315+
# Stamps android/build.gradle's versionCode from wall-clock time: minutes since
316+
# the Unix epoch, times 10. Time is a global, monotonically increasing authority,
317+
# so releases cut from different branches never collide or regress (see the
318+
# versionCode comment in android/build.gradle). The last digit is reserved for
319+
# the build variant; the AndroidTV build adds 1 at build time. If the machine
320+
# clock would produce a value not strictly greater than the current one (clock
321+
# skew, or two bumps within the same minute), fall back to bumping the current
322+
# value by 10 so the code always advances.
315323
.PHONY: bump-version-code
316-
bump-version-code: tailscale.version
317-
@source tailscale.version && \
318-
BASE_VERSION_CODE=$$((VERSION_MAJOR * 100000000 + VERSION_MINOR * 100000 + VERSION_PATCH * 10)) && \
319-
echo "Setting android/build.gradle versionCode to $$BASE_VERSION_CODE" && \
320-
sed -i.bak -E "s/versionCode [0-9]+/versionCode $$BASE_VERSION_CODE/" android/build.gradle && \
324+
bump-version-code:
325+
@CUR_VERSION_CODE=$$(grep -oE 'versionCode [0-9]+' android/build.gradle | awk '{print $$2}') && \
326+
TIME_VERSION_CODE=$$(( $$(date +%s) / 60 * 10 )) && \
327+
if [ "$$TIME_VERSION_CODE" -gt "$$CUR_VERSION_CODE" ]; then \
328+
NEXT_VERSION_CODE=$$TIME_VERSION_CODE; \
329+
else \
330+
NEXT_VERSION_CODE=$$((CUR_VERSION_CODE + 10)); \
331+
fi && \
332+
echo "Setting android/build.gradle versionCode $$CUR_VERSION_CODE -> $$NEXT_VERSION_CODE" && \
333+
sed -i.bak -E "s/versionCode [0-9]+/versionCode $$NEXT_VERSION_CODE/" android/build.gradle && \
321334
rm android/build.gradle.bak
322335

323336
.PHONY: update-oss ## Update the tailscale.com go module

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,11 @@ make install
132132

133133
## Building a release
134134

135-
Use `make tag_release` to bump the Android version code, update the version
136-
name, and tag the current commit.
135+
Use `make tag_release` to stamp the Play Store version code, update the version
136+
name, and tag the current commit. The version code is derived from wall-clock
137+
time (minutes since the Unix epoch) at release time and committed into
138+
`android/build.gradle`, so it increases monotonically across all builds and
139+
branches while staying fixed for any given commit.
137140

138141
We only guarantee to support the latest Go release and any Go beta or
139142
release candidate builds (currently Go 1.14) in module mode. It might

android/build.gradle

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,23 @@ android {
3939
defaultConfig {
4040
minSdkVersion 26
4141
targetSdkVersion androidApiLevel
42-
// versionCode is written here by `make bumposs` / `make tag_release`
43-
// (base = major*100000000 + minor*100000 + patch*10). AndroidTV builds
44-
// increment this by 1 in the Makefile's release-tv target so the two
45-
// variants are distinguishable in the Play Store.
46-
versionCode 110300150
42+
// versionCode is stamped here by `make bump-version-code` (run via
43+
// `make bumposs` / `make tag_release`) from wall-clock time: minutes
44+
// since the Unix epoch, times 10. Time is a global, monotonically
45+
// increasing authority, so releases cut from different branches never
46+
// collide or go backwards -- unlike a counter stored in this file, which
47+
// each branch would bump independently. (The Play Store requires
48+
// versionCode to strictly increase across uploads, and stable point
49+
// releases ship after higher-numbered unstable builds, so anything
50+
// version-derived or per-branch eventually regresses.)
51+
//
52+
// This MUST stay a bare `versionCode <integer>` literal with no
53+
// surrounding logic: external build tooling greps this line and parses
54+
// the number directly. The last digit is reserved for the build variant;
55+
// the Makefile's release-tv target rewrites this integer to end in 1 for
56+
// AndroidTV builds so phone (...0) and TV (...1) uploads stay
57+
// distinguishable in the Play Store.
58+
versionCode 297588040
4759
versionName getVersionProperty("VERSION_LONG")
4860
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
4961

0 commit comments

Comments
 (0)