ADR-0081: Android validation runs on PRs (and the merge queue when used), not again on main pushes
- Status: Accepted
- Date: 2026-11-01
Context
ADR-0041/issue #343 added a push: branches: [main] trigger to
android-tests.yml so the default branch re-ran the unit/lint and
instrumented suites after merge. That made main a second full-device
validation point: every merge requeued the same emulator-heavy suite that the
PR run had just executed. When a merge queue is enabled, the merge_group run
has also already tested the exact tree being merged. The duplicated main run
consumes the shared KVM runner for roughly another instrumented-lane duration
while adding no new source coverage; release artifacts already have their own
tag-triggered gates. A merge queue is optional, so the policy must not assume
it is always present.
Decision
android-tests.yml validates pull requests targeting main and, when a
merge queue is enabled, its merge-group entries. It deliberately has no
push trigger. The PR-head run is the single required validation for a direct
or admin merge that does not pass through a merge queue.
- The required check names stay
Unit Testing & Linting Android AppandInstrumented Testing on Emulator, so branch protection keeps waiting on the same jobs. - The PR
paths-ignorefilter stays unchanged (.idea/**,.opencode/**,docs/**,**.md); workflow edits and Android sources still trigger the gates. merge_groupremains enabled so a merge queue can wait on the same required checks when it is used; merge-group runs are never cancelled by a later submission, while only supersededpull_requestruns are cancelled.- Release, build, publish and Play promotion workflows are untouched. Their tag/release checks remain the artifact gate.
A direct push to main that bypasses PR validation therefore does not re-run
this suite. That is a technical enforcement limit, not a policy allowance: the
policy requires PR validation, and a merge queue is an additional exact-tree
check when the repository enables one, not a precondition for every merge. The
supporting contract tests fail if the pull_request or merge_group triggers
disappear, if push returns, or if the required check names change.
Consequences
A tree is device-tested on its PR once. When a merge queue is configured, its
run adds validation of the exact landing tree instead of a duplicate main-push
run; without a merge queue, the PR-head result is the accepted evidence for a
direct/admin merge. Contributors must not rely on a post-merge main run to
catch a regression; local full-gate requirements and the PR checks are the
contract.
Workflow-only PRs still validate the configuration they change because
.github/** is not ignored.
Verification
scripts/test-workflow-paths.sh asserts the PR filter, required names,
merge_group, and the absence of push. scripts/test-ci-hygiene.sh asserts
the same trigger shape alongside its timeout and coverage wiring. Both run in
the docs-guard workflow. Release/build workflow contracts
(test-ci-smoke-matrix.sh, test-build-artifacts-version.sh,
test-play-release-workflow.sh) continue to pin their unchanged gates.