ci(release): conventional-commit auto-release engine for the APK #12

Merged
whitlocktech merged 1 commits from ci/android-release-engine into main 2026-07-20 09:35:21 +00:00
Member

Follow-up to #11. The M6 merge (de79bf) landed the tag-driven release.yml; this replaces it with link/'s language-agnostic release engine, adapted for Android (the commit was pushed to the #11 branch too late to be part of that merge, so it needs its own PR off current main).

What it does

On every push to main it:

  • Derives the next version from conventional-commit subjects since the last v* tag — feat!/BREAKING → major, feat → minor, fix/perf → patch; nothing releasable → no release; first-ever run (no tag) ships the committed build.gradle.kts version as-is.
  • Generates a grouped changelog (Features / Fixes / All changes).
  • Bumps versionName in build.gradle.kts; versionCode is derived from it (major*10000+minor*100+patch, monotonic).
  • Builds the signed release APK (keystore decoded from a base64 Gitea secret).
  • Commits the bump [skip ci], tags vX.Y.Z, and creates the Gitea release with notes + APK + SHA256SUMS.

Mirrors link/ down to the REGISTRY_USER/REGISTRY_TOKEN (write:repository) usage for pushing the bump + creating the release; main must allow that account to push (the bump lands on main, guarded by [skip ci] + the head-commit check against a loop). Same self-hosted-runner handling as pr-checks.yml (apt JDK 17, sdkmanager, in-step chmod +x gradlew).

Notes

  • The engine's shell logic (version extract, bump, versionCode derive, the two build.gradle.kts seds) was validated against the real file — it edits exactly the two version-default lines.
  • Signing secrets unchanged from #11 (ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD); this adds the REGISTRY_USER/REGISTRY_TOKEN requirement + the main-push allowance.
  • ⚠️ Once merged, the next release-worthy push to main auto-cuts v0.1.0. If the secrets/push-permission aren't set, that run fails at keystore-decode but creates no tag or release.
  • Docs already describe this engine (docs #19).

AI-assisted (Claude Code); commit carries Co-Authored-By: Claude <noreply@anthropic.com>.

Follow-up to #11. The M6 merge (`de79bf`) landed the **tag-driven** `release.yml`; this replaces it with **`link/`'s language-agnostic release engine, adapted for Android** (the commit was pushed to the #11 branch too late to be part of that merge, so it needs its own PR off current `main`). ### What it does On **every push to `main`** it: - Derives the next version from **conventional-commit** subjects since the last `v*` tag — `feat!`/BREAKING → major, `feat` → minor, `fix`/`perf` → patch; **nothing releasable → no release**; first-ever run (no tag) ships the committed `build.gradle.kts` version as-is. - Generates a grouped **changelog** (Features / Fixes / All changes). - Bumps `versionName` in `build.gradle.kts`; `versionCode` is derived from it (`major*10000+minor*100+patch`, monotonic). - Builds the **signed** release APK (keystore decoded from a base64 Gitea secret). - Commits the bump `[skip ci]`, **tags `vX.Y.Z`**, and creates the **Gitea release** with notes + APK + `SHA256SUMS`. Mirrors `link/` down to the `REGISTRY_USER`/`REGISTRY_TOKEN` (write:repository) usage for pushing the bump + creating the release; `main` must allow that account to push (the bump lands on `main`, guarded by `[skip ci]` + the head-commit check against a loop). Same self-hosted-runner handling as `pr-checks.yml` (apt JDK 17, `sdkmanager`, in-step `chmod +x gradlew`). ### Notes - The engine's shell logic (version extract, bump, `versionCode` derive, the two `build.gradle.kts` seds) was validated against the real file — it edits exactly the two version-default lines. - Signing secrets unchanged from #11 (`ANDROID_KEYSTORE_BASE64`, `ANDROID_KEYSTORE_PASSWORD`, `ANDROID_KEY_ALIAS`, `ANDROID_KEY_PASSWORD`); this adds the `REGISTRY_USER`/`REGISTRY_TOKEN` requirement + the `main`-push allowance. - ⚠️ Once merged, the **next release-worthy push to `main` auto-cuts `v0.1.0`**. If the secrets/push-permission aren't set, that run fails at keystore-decode but creates **no tag or release**. - Docs already describe this engine (docs #19). AI-assisted (Claude Code); commit carries `Co-Authored-By: Claude <noreply@anthropic.com>`.
wtclaude added 1 commit 2026-07-20 09:31:40 +00:00
Replace the tag-triggered release.yml with link/'s language-agnostic release
engine, adapted for Android. On every push to main it derives the next version
from conventional-commit subjects since the last v* tag (feat!/BREAKING -> major,
feat -> minor, fix|perf -> patch; nothing releasable -> no release), generates a
grouped changelog, bumps versionName in build.gradle.kts (versionCode derived
major*10000+minor*100+patch, monotonic), builds the SIGNED release APK, then
commits the bump [skip ci], tags vX.Y.Z, and creates the Gitea release with the
notes + APK + SHA256SUMS.

Uses REGISTRY_USER/REGISTRY_TOKEN (write:repository) to push the bump + create
the release, matching link/. main must allow that account to push (bump lands on
main; the [skip ci] + head-commit guard prevent a re-trigger loop). Signing
secrets (ANDROID_KEYSTORE_BASE64/_PASSWORD, ANDROID_KEY_ALIAS/_PASSWORD) unchanged.
Same self-hosted-runner handling as pr-checks.yml (apt JDK 17, sdkmanager, chmod).

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech approved these changes 2026-07-20 09:32:27 +00:00
whitlocktech merged commit bc09593550 into main 2026-07-20 09:35:21 +00:00
whitlocktech deleted branch ci/android-release-engine 2026-07-20 09:35:21 +00:00
Sign in to join this conversation.
No description provided.