docs(release): document self-hosted runner and heap sizing

This commit is contained in:
2026-07-27 18:38:37 +02:00
parent a7e1217e82
commit d6ea73140e
+31 -2
View File
@@ -7,8 +7,9 @@ description: Cut a HealthChat Google Play release of element-x-android by taggin
Releases are driven by git tags of the form `healthchat-v<version>` pushed to
`origin`. The tag triggers `.github/workflows/healthchat-release-playstore.yml`,
which runs on `ubuntu-latest`, builds a signed AAB, and uploads it to the Play
Store **internal** track. No GitHub Release is created.
which runs on the self-hosted `novaloop-incus-large` runner, builds a signed
AAB, and uploads it to the Play Store **internal** track. No GitHub Release is
created.
**Promotion to production is always a manual step** in Play Console after an
internal build has been validated — see "Promoting to production" below.
@@ -65,6 +66,34 @@ Use when retrying a failed run or rebuilding without moving tags.
`HEALTHCHAT_CHANGES.md` lookup. Useful for ad-hoc test builds.
3. Run. The AAB is built and uploaded exactly as the tag path would.
## Runner and build tuning
The job runs on `novaloop-incus-large` — an incus container with 4 cores and
24 GiB, not a GitHub-hosted runner. Two consequences the workflow handles, and
that anyone editing it needs to keep in mind:
- **The image ships no Android SDK.** The `Set up Android SDK` step installs
it. Platform packages are minor-versioned, so `COMPILE_SDK = 37` means
`platforms;android-37.0`. Build-tools follows AGP's own default
(`SdkConstants.CURRENT_BUILD_TOOLS_VERSION`), not `BUILD_TOOLS_VERSION` in
`Versions.kt` — nothing sets `buildToolsVersion`, so bump it when AGP is
upgraded.
- **`GRADLE_OPTS` is deliberately smaller than upstream's.** Upstream's
workflows use `-Xmx8g` with a 4 GB Kotlin daemon, sized for the 4-core/16GB
`ubuntu-latest` that *public* repos get; this repo is private, so its hosted
runners are 2-core/7GB and its container is 24 GiB. At upstream's numbers the
daemon plus the Kotlin daemon plus four parallel lint/R8 workers exceed the
limit and the daemon is SIGKILLed — the symptom is
`DaemonDisappearedException` with **no** `OutOfMemoryError` and no heap dump,
which is what an external kill looks like. `-Xmx6g` with a 2 GB Kotlin daemon
fits.
The `Report runner capacity` step prints `free`, `nproc`, `df` and the enforced
cgroup limit on every run, so a future failure can be read against the runner's
actual capacity rather than guessed at. Note `free` reports the container's
limit only when lxcfs virtualises `/proc/meminfo`; `/sys/fs/cgroup/memory.max`
is the number the kernel enforces.
## Versioning (calendar scheme — differs from the old Classic repo)
Element X uses calendar versioning, defined in