Files
android/README.md
Robert Helewka 44064b6364
Some checks failed
build-android-builder-image / build-image (push) Failing after 9s
ci: wire up the builder-image workflow and fix repo layout
The repo was committed with the CI files misnamed/misplaced, so nothing
ran. Move them into place and fix the issues that surfaced against the
Syrinx reference and the Dade target:

- Dockerfile.yml -> Dockerfile (the workflow references ./Dockerfile)
- builder-image.yml -> .gitea/workflows/builder-image.yml (Gitea only
  runs files under .gitea/workflows)
- build.yml -> templates/build.yml (it's the app-repo template, not a
  workflow for this repo; keep it out of the run path)
- runs-on [self-hosted, arm64] -> ubuntu-24.04-arm64 (the real Gitea
  label, matching Syrinx) in the workflow, template, and README
- bump image SDK android-35/build-tools 35.0.0 -> android-36/36.0.0 to
  match Dade's compileSdk 36 (avoids a job-time SDK download)
- template upload-artifact@v4 -> @v3 (v4 is unsupported on Gitea)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:03:43 -04:00

3.6 KiB

android-builder

Native linux/arm64 Android build toolchain for CI, published to the Gitea container registry at git.helu.ca/r/android.

App repos consume this image to build signed release artifacts. Instrumented tests are not part of this toolchain — by design, CI builds are promotions of code already tested in Dev (on Apple silicon, where the emulator runs natively). The OCI Ampere (aarch64) runner has no /dev/kvm (the guest VM boots at EL1, so KVM can't access HYP/EL2), so there's no accelerated emulator here — and we don't need one.

What's in the image

  • Eclipse Temurin JDK 21 (native arm64)
  • Android cmdline-tools, platform, and build-tools — baked in, so prod builds don't depend on Google's download endpoint at job time
  • git, curl, unzip

Pinned versions live as ARGs at the top of the Dockerfile:

ARG Default Where to check
CMDLINE_TOOLS_VERSION 13114758 https://developer.android.com/studio#command-line-tools-only
BUILD_TOOLS_VERSION 36.0.0 SDK Manager / release notes
PLATFORM_VERSION android-36 your app's compileSdk

aapt2 and the build-tools binaries ship native arm64 for 36.x, so packaging runs without emulation.

Tagging model

The whole point of owning this image is that app repos pin a tag and a new toolchain never lands in a prod build by accident.

  • Immutable — a git tag like 2026.06 produces git.helu.ca/r/android:2026.06. This is what app repos pin to.
  • Moving — pushes to main (and any tag build) refresh git.helu.ca/r/android:latest for convenience. Don't pin prod builds to this.

Cutting a new toolchain

  1. Update the ARG defaults in the Dockerfile if you're moving SDK/tool versions. Verify CMDLINE_TOOLS_VERSION against the link above — a stale number 404s the image build.
  2. Commit to main. The workflow builds and pushes :latest; confirm it's green.
  3. Tag the release with the year-month you want app repos to reference:
    git tag 2026.06
    git push origin 2026.06
    
    This publishes the immutable git.helu.ca/r/android:2026.06.
  4. Roll app repos forward deliberately by bumping their pinned tag (see below) — one at a time if you want to validate, all at once if you trust the bump.

Using it in an app repo

Drop .gitea/workflows/build.yml (the template alongside this repo) into the app and pin the toolchain:

jobs:
  build:
    runs-on: ubuntu-24.04-arm64
    container:
      image: git.helu.ca/r/android:2026.06
      credentials:
        username: ${{ gitea.actor }}
        password: ${{ secrets.GITEA_TOKEN }}

The build task is selectable: assembleRelease (APK, the default) or bundleRelease (AAB — only needed for Google Play distribution).

Required secrets in each app repo (or org-level)

Signing happens at job time; nothing sensitive lives in the repo or the image.

Secret What it is
KEYSTORE_BASE64 release keystore, base64-encoded: base64 -w0 release.keystore
KEYSTORE_PASSWORD keystore password
KEY_ALIAS signing key alias
KEY_PASSWORD key password

GITEA_TOKEN needs write:package here (to push) and read:package in app repos (to pull). The built-in token usually covers this; if your instance scopes it tightly, use a PAT.

First-run sequencing

The image must exist in the registry before any app workflow can pull it. So: cut and push 2026.06 from this repo first, confirm it's in the registry, then the app workflows that pin it will resolve.