Android was the last job still downloading its world every run: ~3 GB of SDK/NDK/CMake from Google, a from-source cargo-ndk build, and one monolithic cache key where a gradle edit invalidated the cargo registry and the Rust target/ with it. punktfunk-android-ci (content-keyed, LAN registry) bakes JDK 21 + SDK + NDK + cargo-ndk + sccache; the workflow shrinks to checkout → two caches → gradle. The cargo-home cache joins the fleet-wide namespace (same lockfile, same layout — it was the same bytes under a private key), gradle gets its own key shared with android-screenshots (which stored the identical content under a second name), and target/ leaves the cache — sccache covers the three ABI builds now. Apple: sccache (self-healing ~/.local/bin install + already provisioned on the mini) covers every cargo invocation build-xcframework.sh makes across the swift job, the screenshots job and release.yml — three jobs that each recompiled the same core. screenshots.sh learns PF_SHOT_DERIVED_DATA so CI pins one stable DerivedData root instead of cold-building into two throwaway mktemp trees per run (release.yml's disease, same cure), and the Simulators get shut down after capture (the 846-leaked-sims lesson). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61 lines
2.9 KiB
YAML
61 lines
2.9 KiB
YAML
# Android client screenshots for the Play listing / marketing. Roborazzi renders the real Compose
|
||
# UI with mock state on the host JVM via Robolectric — NO emulator, GPU, KVM, host, or JNI core
|
||
# (`-PskipRustBuild` skips the cargo-ndk native build). The Android analogue of apple.yml's
|
||
# `screenshots` job, gated to STABLE RELEASE tags only. Standalone + best-effort: a failure here
|
||
# reds nothing else. PNGs land as a 30-day artifact; not committed or published.
|
||
name: android-screenshots
|
||
# One pending run per workflow+ref: a newer push supersedes the queued/running one and cancels
|
||
# it (a canary only needs the latest commit; each release tag is its own ref so tag runs never
|
||
# cancel each other). Keeps a busy push cadence from piling ~10 queued runs per commit onto the
|
||
# runner fleet. Gitea honors this for push triggers (PR triggers: see gitea#35933).
|
||
concurrency:
|
||
group: ${{ github.workflow }}-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
|
||
on:
|
||
push:
|
||
tags: ["v*"]
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
screenshots:
|
||
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
|
||
runs-on: ubuntu-24.04
|
||
# JDK 21 + SDK baked (AGP 9.3 + Robolectric's SDK-36 android-all jar both want 17–21).
|
||
# The tests are pure JVM (no NDK), but sharing android.yml's image means one image to
|
||
# keep warm instead of a per-run setup-java + sdkmanager download pair.
|
||
container:
|
||
image: 192.168.1.58:5010/punktfunk-android-ci:latest
|
||
timeout-minutes: 45
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Cache (gradle)
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: |
|
||
~/.gradle/caches
|
||
~/.gradle/wrapper
|
||
# gradle-wrapper.properties is in the key on purpose: `~/.gradle/wrapper` caches the
|
||
# Gradle DISTRIBUTION, so a wrapper bump with no .gradle.kts change would otherwise
|
||
# restore a key that can never hold the new one. Namespace shared with android.yml —
|
||
# it is the same content; two keys just stored it twice in the central cache.
|
||
key: gradle-${{ hashFiles('clients/android/**/*.gradle.kts', 'clients/android/gradle/wrapper/gradle-wrapper.properties') }}
|
||
restore-keys: gradle-
|
||
|
||
# Roborazzi renders Compose on the JVM (Robolectric Native Graphics). `-PskipRustBuild` keeps
|
||
# the cargo-ndk native build out of the graph — the tests never load libpunktfunk_android.so.
|
||
- name: Capture screenshots (Roborazzi)
|
||
working-directory: clients/android
|
||
run: ./gradlew :app:testDebugUnitTest -PskipRustBuild --stacktrace
|
||
|
||
- name: Upload screenshots
|
||
if: always()
|
||
# v3: Gitea's API rejects upload-artifact@v4 (see apple.yml). Download is a zip.
|
||
uses: actions/upload-artifact@v3
|
||
with:
|
||
name: punktfunk-android-screenshots
|
||
path: clients/android/app/build/outputs/roborazzi
|
||
retention-days: 30
|