The guard fix, and the APK and image #4 never published #5

Merged
bvandeusen merged 1 commits from dev into main 2026-08-29 14:19:50 -04:00
Owner

One commit: 6e524ec, the fix for the guard failure that PR #4 triggered.

Why this merge exists

#4's Android lane failed (run 4857) and ci.yml's gate correctly withheld the image behind it. So main's current tip has published only two of its three artifacts:

after #4 after this
desktop stable 1.0.3502363 1.0.3503145
android stable nothing first APK + sidecar
server image :latest still pre-merge :latest + :<sha> for this commit

The bug

guard-forward.sh has a branch for "this channel has published nothing yet — pass, there is nothing to go backwards from." It was unreachable. published="$(published_for ...)" under set -e dies on the substitution before it, and silently, because everything the pipeline would have printed goes into the capture rather than the log.

Which lookups carried it was decided by the last command in the pipeline — sed on empty input exits 0, grep exits 1. Three of the four end in sed. Android's version_code ends in grep -oE '[0-9]+$', so it was the only one, and only on a channel with no APK on it. dev has had one since day one; stable never did. The bug could not fire until #4 created its one precondition, which is why a week of green dev pushes ran past it.

Each lookup is now wrapped so it returns empty rather than failing, with a comment naming the pipeline-tail asymmetry at the point where the next lookup will be copied from one of these four.

Tests

The guard's feed-facing half had no coverage at all — only its pure compare mode did, which is the half that worked. A curl_stub fixture shadows curl on PATH so the other half is testable and still hermetic: an empty channel passes the guard and reports true from should-build.sh, a lower published version passes, a higher one fails the lane, and an equal Android versionCode is refused because Android will not install it.

All four lanes green on 6e524ec — Android 4864, CI & Build 4865, Desktop 4866, and the dispatched image build 4869.

Recorded as issue #3233.

One commit: `6e524ec`, the fix for the guard failure that PR #4 triggered. ## Why this merge exists #4's Android lane failed (run 4857) and `ci.yml`'s gate correctly withheld the image behind it. So `main`'s current tip has published only two of its three artifacts: | | after #4 | after this | |---|---|---| | desktop `stable` | `1.0.3502363` ✓ | `1.0.3503145` | | android `stable` | **nothing** | first APK + sidecar | | server image | **`:latest` still pre-merge** | `:latest` + `:<sha>` for this commit | ## The bug `guard-forward.sh` has a branch for "this channel has published nothing yet — pass, there is nothing to go backwards from." It was unreachable. `published="$(published_for ...)"` under `set -e` dies on the substitution before it, and silently, because everything the pipeline would have printed goes into the capture rather than the log. Which lookups carried it was decided by the last command in the pipeline — `sed` on empty input exits 0, `grep` exits 1. Three of the four end in `sed`. Android's `version_code` ends in `grep -oE '[0-9]+$'`, so it was the only one, and only on a channel with no APK on it. `dev` has had one since day one; `stable` never did. The bug could not fire until #4 created its one precondition, which is why a week of green `dev` pushes ran past it. Each lookup is now wrapped so it returns empty rather than failing, with a comment naming the pipeline-tail asymmetry at the point where the next lookup will be copied from one of these four. ## Tests The guard's feed-facing half had no coverage at all — only its pure `compare` mode did, which is the half that worked. A `curl_stub` fixture shadows `curl` on `PATH` so the other half is testable and still hermetic: an empty channel passes the guard and reports `true` from `should-build.sh`, a lower published version passes, a higher one fails the lane, and an equal Android `versionCode` is refused because Android will not install it. All four lanes green on `6e524ec` — Android 4864, CI & Build 4865, Desktop 4866, and the dispatched image build 4869. Recorded as issue #3233.
bvandeusen added 1 commit 2026-08-29 14:19:43 -04:00
guard: an empty channel killed the lane instead of passing it
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / integration (push) Successful in 15s
CI & Build / Build & push image (push) Skipped
Android / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 6s
CI & Build / Python tests (push) Successful in 9s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m33s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m14s
Desktop (Tauri) / Update manifest (push) Successful in 5s
Android / Kotlin + Rust (APK) (push) Successful in 7m46s
6e524ec616
The first merge to `main` took the Android lane down (run 4857): the decide
job exited 1 in 0.16 seconds with no output at all, and the image build
skipped behind it because a failing lane must not publish.

`stable` had never published an APK, which the guard treats as a pass — there
is nothing to go backwards from, and `[ -z "$published" ]` says so in a branch
of its own. That branch was unreachable. `published="$(published_for ...)"`
under `set -e` dies on the substitution before it, and everything the pipeline
would have printed goes into the capture rather than the log.

What decided which lookups had the bug is the last command in the pipeline.
`sed` on empty input exits 0; `grep` exits 1. Three of the four end in `sed`.
Android's version_code ends in `grep -oE '[0-9]+$'`, so it was the only one —
and only on a channel with nothing on it, which is why a week of dev pushes
never saw it.

The tests now reach the half of the guard that talks to a feed, with `curl`
shadowed on PATH so they stay hermetic: an empty channel passes and builds, a
lower published version passes, a higher one fails the lane, and an equal
Android code is refused because Android will not install it.
bvandeusen merged commit b6673c6420 into main 2026-08-29 14:19:50 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/thoughtsync#5