Merging two PRs seconds apart can leave the older merge sha with no run at all — Gitea attributes the window's runs to the newer head. 1e5dca4c (PR #235, the pad Select/KEYCODE_BACK fix, 20:10:04Z) lost its run to b5cace3a 12 s later, and since #236 touches only Swift and docs, android's paths: correctly declined to fire for it. Net effect: the fix reached main having never been built, and no canary carries it — Play beta+alpha is still on versionCode 13728 (36e133ae).
Re-running the PR run cannot recover that. A re-run replays the original event, so run #13731 stayed pull_request and all four publish steps skipped again — verified on its 20:47 re-run, which went green with Version + channel, Build Release, Publish to generic registry and Upload to Google Play all skipped. (Its first attempt hadn't skipped at all: it died before step 0 on failed to create container: No such image: 192.168.1.58:5010/punktfunk-android-ci:latest, which paints every step cancelled and reads like a code failure.)
Until now the only cure was inventing a filler push touching one of android.yml's paths.
What this does
workflow_dispatch gains a publish input, default "false", and the four publish gates widen to accept a dispatch that opts in:
A plain manual run stays build-only, exactly as today — a stray click cannot reach testers.
The input is string-typed and compared against 'true', matching apple.yml's testflight, which is the form proven to evaluate on this Gitea. Not a YAML boolean.
All four gates move together on purpose: PLAY_TRACK/PLAY_ALSO_TRACK are exported by the Version + channel step, so un-gating only the upload would run it with an empty --track.
Dispatching a tag with publish=true reaches production at 100%, same as a tag push. Deliberate — it's the same recovery path when a release run dies on a runner flake. The release-notes gate still guards it (ref-based, not event-based).
docs/releases/README.md gets the recovery note, including the "match your own merge sha in the run list" check — CI ran is not the same as your commit ran.
Note on merging
workflow_dispatch runs the workflow file from the selected ref, so the hatch only becomes usable once it's on main. The merge push touches .gitea/workflows/android.yml, which is in android's own paths: — so merging this triggers a normal canary run that carries the Select fix to beta+alpha on its own. The hatch is insurance for next time rather than the tool needed for this instance.
Validated by parsing the YAML and printing each resolved if (the folded block scalar collapses to one line); the tag-only notes gate and the always() artifact step are untouched.
Merging two PRs seconds apart can leave the older merge sha with **no run at all** — Gitea attributes the window's runs to the newer head. `1e5dca4c` (PR #235, the pad Select/`KEYCODE_BACK` fix, 20:10:04Z) lost its run to `b5cace3a` 12 s later, and since #236 touches only Swift and docs, android's `paths:` correctly declined to fire for it. Net effect: the fix reached `main` having never been built, and no canary carries it — Play beta+alpha is still on versionCode 13728 (`36e133ae`).
Re-running the PR run cannot recover that. A re-run replays the *original* event, so run #13731 stayed `pull_request` and all four publish steps skipped again — verified on its 20:47 re-run, which went green with `Version + channel`, `Build Release`, `Publish to generic registry` and `Upload to Google Play` all skipped. (Its first attempt hadn't skipped at all: it died before step 0 on `failed to create container: No such image: 192.168.1.58:5010/punktfunk-android-ci:latest`, which paints every step `cancelled` and reads like a code failure.)
Until now the only cure was inventing a filler push touching one of `android.yml`'s paths.
## What this does
`workflow_dispatch` gains a `publish` input, **default `"false"`**, and the four publish gates widen to accept a dispatch that opts in:
```yaml
if: >-
(github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish == 'true'))
&& (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
```
- A plain manual run stays **build-only**, exactly as today — a stray click cannot reach testers.
- The input is **string-typed and compared against `'true'`**, matching `apple.yml`'s `testflight`, which is the form proven to evaluate on this Gitea. Not a YAML boolean.
- All four gates move together on purpose: `PLAY_TRACK`/`PLAY_ALSO_TRACK` are exported by the `Version + channel` step, so un-gating only the upload would run it with an empty `--track`.
- Dispatching a **tag** with `publish=true` reaches production at 100%, same as a tag push. Deliberate — it's the same recovery path when a release run dies on a runner flake. The release-notes gate still guards it (ref-based, not event-based).
`docs/releases/README.md` gets the recovery note, including the "match your own merge sha in the run list" check — *CI ran* is not the same as *your commit ran*.
## Note on merging
`workflow_dispatch` runs the workflow file from the selected ref, so the hatch only becomes usable once it's on `main`. The merge push touches `.gitea/workflows/android.yml`, which is in android's own `paths:` — so **merging this triggers a normal canary run that carries the Select fix to beta+alpha on its own**. The hatch is insurance for next time rather than the tool needed for this instance.
Validated by parsing the YAML and printing each resolved `if` (the folded block scalar collapses to one line); the tag-only notes gate and the `always()` artifact step are untouched.
Merging two PRs seconds apart can leave the older merge sha with no run at all -
Gitea attributes the window's runs to the newer head. 1e5dca4c (PR #235, the pad
Select/KEYCODE_BACK fix) lost its run to b5cace3a 12 s later and reached main
having never been built, so no canary carries it.
Re-running the PR run cannot recover that: a re-run replays the original
pull_request event, and all four publish steps are gated on a push, so they stay
skipped. Until now the only cure was inventing a filler push touching one of
android.yml's paths.
Add a workflow_dispatch 'publish' input, default false, and widen the four gates
to accept a dispatch that opts in. A plain manual run stays build-only, so a
stray click still cannot reach testers. String-typed and compared against 'true'
to match apple.yml's testflight input, the form proven on this Gitea.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Merging two PRs seconds apart can leave the older merge sha with no run at all — Gitea attributes the window's runs to the newer head.
1e5dca4c(PR #235, the pad Select/KEYCODE_BACKfix, 20:10:04Z) lost its run tob5cace3a12 s later, and since #236 touches only Swift and docs, android'spaths:correctly declined to fire for it. Net effect: the fix reachedmainhaving never been built, and no canary carries it — Play beta+alpha is still on versionCode 13728 (36e133ae).Re-running the PR run cannot recover that. A re-run replays the original event, so run #13731 stayed
pull_requestand all four publish steps skipped again — verified on its 20:47 re-run, which went green withVersion + channel,Build Release,Publish to generic registryandUpload to Google Playall skipped. (Its first attempt hadn't skipped at all: it died before step 0 onfailed to create container: No such image: 192.168.1.58:5010/punktfunk-android-ci:latest, which paints every stepcancelledand reads like a code failure.)Until now the only cure was inventing a filler push touching one of
android.yml's paths.What this does
workflow_dispatchgains apublishinput, default"false", and the four publish gates widen to accept a dispatch that opts in:'true', matchingapple.yml'stestflight, which is the form proven to evaluate on this Gitea. Not a YAML boolean.PLAY_TRACK/PLAY_ALSO_TRACKare exported by theVersion + channelstep, so un-gating only the upload would run it with an empty--track.publish=truereaches production at 100%, same as a tag push. Deliberate — it's the same recovery path when a release run dies on a runner flake. The release-notes gate still guards it (ref-based, not event-based).docs/releases/README.mdgets the recovery note, including the "match your own merge sha in the run list" check — CI ran is not the same as your commit ran.Note on merging
workflow_dispatchruns the workflow file from the selected ref, so the hatch only becomes usable once it's onmain. The merge push touches.gitea/workflows/android.yml, which is in android's ownpaths:— so merging this triggers a normal canary run that carries the Select fix to beta+alpha on its own. The hatch is insurance for next time rather than the tool needed for this instance.Validated by parsing the YAML and printing each resolved
if(the folded block scalar collapses to one line); the tag-only notes gate and thealways()artifact step are untouched.