Add a dispatch-only workflow for the API 37 CI question #53

Merged
JMR-dev merged 1 commits from ci/api37-debug into main 2026-08-23 14:15:50 +00:00
JMR-dev commented 2026-08-23 14:15:34 +00:00 (Migrated from github.com)

status_check.yml stops its E2E matrix at API 36 and points at docs/api-37-emulator-crash.md
for why. That file establishes the gralloc abort locally, under -gpu host and under ANGLE. It
does not establish anything about CI: runners use -gpu swiftshader_indirect, and the only
local measurement of that mode was void for a purely local reason — Fedora's SELinux denies
execheap to SwiftShader's Reactor JIT, so the host emulator segfaulted before the guest
mattered. What CI actually does at API 37 has never been measured.

This adds .github/workflows/api37-debug.yml: the API 37 E2E job with the matrix replaced by
workflow_dispatch inputs, so one hypothesis costs one dispatch instead of one commit —
renderer, API level, image target, SDK channel, SystemUI disable, boot timeout, whether the
suite runs at all, plus free-form emulator and Gradle arguments.

  • Triggers on workflow_dispatch only. No push, no pull_request, no schedule. Nothing
    else in the repository can start it and it gates nothing.
  • Does not fork .github/scripts/e2e-run.sh — it invokes it, exactly as status_check.yml
    does, and drives its existing E2E_EXTRA_GRADLE_ARGS hook.
  • Does not touch status_check.yml. If a configuration turns out to work, the change to the
    real matrix is proposed separately.
  • Keeps the pinned action SHAs, disk-size: 8G, ram-size: 2560M and the KVM step byte for
    byte, so a run measures the renderer and not a different device.

The one thing it adds is a watchdog, and it is load-bearing: the emulator action calls
killEmulator() from its own catch block, so a run whose emulator never boots is torn down
before a single script: line executes and leaves nothing behind — which is precisely the
failure shape API 37 is suspected of. The watchdog starts before the action and samples
sys.boot_completed, the surfaceflinger and zygote64 pids and the hasReadColorBufferDma
abort count every 20 s, keeping a rolling copy of the crash buffer so the last read survives the
teardown.

Merged with --admin deliberately: a workflow_dispatch workflow cannot be exercised at all
until it is on the default branch, and this one cannot affect any other job because nothing
triggers it.

Linted with actionlint 1.7.12 (exit 0) and parsed with PyYAML; both embedded helper scripts
pass bash -n.

🤖 Generated with Claude Code

`status_check.yml` stops its E2E matrix at API 36 and points at `docs/api-37-emulator-crash.md` for why. That file establishes the gralloc abort locally, under `-gpu host` and under ANGLE. It does **not** establish anything about CI: runners use `-gpu swiftshader_indirect`, and the only local measurement of that mode was void for a purely local reason — Fedora's SELinux denies `execheap` to SwiftShader's Reactor JIT, so the host emulator segfaulted before the guest mattered. What CI actually does at API 37 has never been measured. This adds `.github/workflows/api37-debug.yml`: the API 37 E2E job with the matrix replaced by `workflow_dispatch` inputs, so one hypothesis costs one dispatch instead of one commit — renderer, API level, image target, SDK channel, SystemUI disable, boot timeout, whether the suite runs at all, plus free-form emulator and Gradle arguments. - **Triggers on `workflow_dispatch` only.** No push, no `pull_request`, no schedule. Nothing else in the repository can start it and it gates nothing. - **Does not fork `.github/scripts/e2e-run.sh`** — it invokes it, exactly as `status_check.yml` does, and drives its existing `E2E_EXTRA_GRADLE_ARGS` hook. - **Does not touch `status_check.yml`.** If a configuration turns out to work, the change to the real matrix is proposed separately. - Keeps the pinned action SHAs, `disk-size: 8G`, `ram-size: 2560M` and the KVM step byte for byte, so a run measures the renderer and not a different device. The one thing it adds is a watchdog, and it is load-bearing: the emulator action calls `killEmulator()` from its own catch block, so a run whose emulator never boots is torn down before a single `script:` line executes and leaves nothing behind — which is precisely the failure shape API 37 is suspected of. The watchdog starts before the action and samples `sys.boot_completed`, the `surfaceflinger` and `zygote64` pids and the `hasReadColorBufferDma` abort count every 20 s, keeping a rolling copy of the crash buffer so the last read survives the teardown. Merged with `--admin` deliberately: a `workflow_dispatch` workflow cannot be exercised at all until it is on the default branch, and this one cannot affect any other job because nothing triggers it. Linted with `actionlint` 1.7.12 (exit 0) and parsed with PyYAML; both embedded helper scripts pass `bash -n`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.