ndk { debugSymbolLevel = "SYMBOL_TABLE" } needs the NDK's llvm-objcopy
to extract native symbol tables into the .aab's BUNDLE-METADATA. The
image shipped no NDK, so AGP silently skipped the step and Play warned
"no debug symbols" on every bundle with native code (confirmed by
inspecting Dade's 0.0.2 .aab: onnxruntime .so present, debugsymbols
metadata dir absent).
Install ndk;27.0.12077973 (AGP 8.13's default, so app repos need no
android.ndkVersion), export ANDROID_NDK_ROOT/HOME, and add llvm-objcopy
to the image sanity check so an arch/version mismatch fails the image
build instead of silently dropping symbols downstream.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Playbook for taking any Heluca app from repo to Google Play, learned from
shipping Dade to internal testing: one-time publisher account + upload keystore
setup, per-app checklist (signing via -Pandroid.injected.signing.*, AAB,
versionCode encoding, native symbols), internal-testing flow, gotchas, and
production promotion. Bakes in Heluca conventions and documents where Dade
deliberately diverges (custom signingConfig, UPLOAD_* secret names, :latest pin)
so the next app can follow the template instead.
Link it from the README.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The image pinned build-tools 36.0.0, whose aapt2/d8 are x86_64-only (Google
publishes no arm64 Linux build-tools). Built for and run on arm64, packaging
died with `aapt2: Syntax error: newline unexpected` (an x86_64 binary the
kernel can't exec).
Build the image for linux/amd64 on an amd64 runner, and point the template +
README at ubuntu-24.04. The APK output is architecture-neutral, so this costs
nothing downstream. Also execute aapt2 in the image sanity check so an arch
mismatch fails the image build, not every app build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When this image is used as a Gitea Actions `container:`, the runner exec's
`node` inside it to run JS-based actions (actions/checkout, upload-artifact).
The image had no Node, so consuming app builds failed at the checkout step
with `exec: "node": executable file not found in $PATH`.
Pull Node 24 from NodeSource (Noble's apt nodejs is v18) and assert it in
the image sanity check.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GITEA_TOKEN is not set in these repos — the registry login sent a blank
password and Gitea's /v2/ endpoint returned unauthorized. Switch the
image-build login, the app template, and the README to PACKAGE_TOKEN, the
PAT the other repos already use (Syrinx pairs gitea.actor + PACKAGE_TOKEN
successfully). The PAT needs write:package here and read:package in app
repos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>