Skip to content

ci: trim JDK matrix, add gha layer cache, image smoke test and NDK variant - #29

Closed
azlekov wants to merge 1 commit into
mainfrom
feat/ci-matrix-cache
Closed

azlekov wants to merge 1 commit into
mainfrom
feat/ci-matrix-cache

Conversation

@azlekov

@azlekov azlekov commented Oct 19, 2026

Copy link
Copy Markdown

Summary

Workstream W2 (CI). Cuts the matrix, adds layer caching and an image smoke test, publishes the NDK variant, and makes the SDK-update PR actually run CI and merge itself.

Leg counts (before → after)

Pipeline Before After
Deploy builds 32 (8 JDK × 2 Node × 2 arch) 16 std + 2 runner-ndk = 18
Deploy merges 16 8 std + 1 ndk = 9
PR build legs 11 6 (JDK 17/21/25/27 @ node24, node22 @ jdk27, 1 arm64)

Verified by running the workflows' own jq expressions against matrix.json.

Changes

  • matrix.json: JDK 17, 21, 25, 27 (LTS + latest), default 27; Node 22, 24, default 24.
  • build.yml: type=gha cache per platform (PR build matrix has no Docker layer cache — every JDK×Node leg rebuilds shared base layers from scratch #15); timeout-minutes (45 build, 10 scripts, 5 others); shellcheck -x *.sh hosts/*.sh tests/*.sh with nullglob so an empty hosts/*.sh is fine; docker compose config -q using .env.example; smoke step on the default amd64 leg (load: true, then tests/image-smoke.sh). The generic tests/*.sh loop skips image-smoke.sh (it needs an image).
  • tests/image-smoke.sh (new): runs with --entrypoint bash and checks java -version (+ expected major), JAVA_HOME JDK, node -v (+ major), sdkmanager --list_installed shows platforms; and build-tools;, and xxd, flock, jq, git.
  • deploy.yml: same gha cache per platform (NDK gets its own write scope, reads both); timeout-minutes; default builds use target: runner; runner-ndk published for the default JDK/Node pair on both arches with tags ndk and <runner_version>-jdk<j>-sdk<s>-node<n>-ndk. Digest artifacts are now named per variant so the std and ndk merges can't pick up each other's digests. provenance: false and the digest/merge flow are kept.
  • check-sdk-updates.yml:
    • Mints a token with actions/create-github-app-token@v3 (owner/repo from the context), uses it for checkout/push and gh pr create, then gh pr merge --auto --squash. Stale comment removed; workflow permissions reduced to contents: read (Image matrix &amp; contents: 28 images per deploy, non-LTS JDKs, NDK nobody uses, compileSdk 37 not baked, SDK-update PRs never trigger CI #17.3).
    • JDK policy: when a newer GA is added, non-LTS versions that are no longer the newest are dropped; default = newest. LTS = 17, 21, 25, then every 4 majors (29, 33…), i.e. v >= 17 && (v-17) % 4 == 0. Checked: +28 → 17,21,25,28; +29 → 17,21,25,29.
    • Why android-37 was never proposed: in repository2-3.xml, stable platforms (37.0, 37.1, 37.2, 36.1…) carry an empty <codename></codename>; previews carry text (DEV, CinnamonBun). is_preview rejected any <codename> element. It now only counts a non-empty one. Run against the live manifest, detection returns platform 37.2, build-tools 37.0.0, NDK 30.0.16248370 (Dockerfile has COMPILE_SDK=36.1, so the next weekly run will propose 37.2).
    • Commit/PR titles are now chore(deps): ….
  • Also quoted "$GITHUB_OUTPUT" / grouped redirects so actionlint is clean.

Required before merge / for the update workflow

  • Repo secrets APP_ID and APP_PRIVATE_KEY (org GitHub App). The App needs Contents: write and Pull requests: write on this repo; the token is requested with exactly those. app-id is deprecated in favour of client-id in create-github-app-token v3 (still works; warning only).
  • Allow auto-merge in repo settings, and require the All builds passed check on main, otherwise gh pr merge --auto errors or merges unchecked.

Merge order

W1 (Dockerfile) before W2. deploy.yml builds target: runner-ndk, which only exists after W1; without it the deploy's NDK legs fail (the std legs are unaffected). The PR smoke step uses target: runner (the default last stage), which exists today.

Verification

  • actionlint .github/workflows/*.yml: clean
  • shellcheck -x *.sh hosts/*.sh tests/*.sh (nullglob): clean
  • docker compose config -q with .env.example: ok
  • jq matrix expressions: counts above
  • Platform detection script run against the live manifest: 37.2
  • image-smoke.sh negative path exercised (fails and exits 1 on an unrelated image). Not run against a real built runner image (no local build); the first PR CI run on the amd64 default leg is the real test. It assumes ANDROID_SDK_ROOT is set in the final image (it is today).

Notes

  • Cache scope is per platform as specified. While the SDK layers sit on top of the JDK layer, parallel legs of one platform overwrite each other's mode=max cache manifest, so hit rate depends on W1 making the SDK layers JDK-independent. The GHA cache has a 10 GB repo limit.

🤖 Generated with Claude Code

…riant

- matrix.json: JDK 17/21/25/27 (LTS + latest), Node 22/24
- build.yml: gha cache per platform, 45 min timeouts, wider shellcheck, docker compose config,
  image smoke test on the default amd64 leg
- deploy.yml: gha cache per platform, timeouts, publish runner-ndk for the default pair
- check-sdk-updates.yml: App token so PR CI runs, auto-merge, LTS-aware JDK retention,
  fix stable platforms (empty <codename>) being treated as previews

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@azlekov

azlekov commented Oct 19, 2026

Copy link
Copy Markdown
Author

folded into the combined refactor PR

@azlekov azlekov closed this Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant