The appliance boot gate reports success when it skips the boot #14
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Keel-Linux/tracker#14
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Measured on Keel-Linux/keel-redis#5, run 36369705307, job 108763227333,
2026-09-28. The job
appliance / build-and-bootreported success after11 seconds. Its steps:
So the gate that is supposed to prove an appliance boots reported that it does,
having never built, pulled, verified or booted anything.
This is by design.
.github/workflows/test-appliance.ymlline 29 says "A layerthat has never been published is not a failure: the job says so", and steps 6
through 10 are all guarded by
if: steps.layer.outputs.published == 'true'.Why it is still a defect
The intent is reasonable — you cannot boot a layer that does not exist, and a
brand new appliance repository has to be able to open its first pull request.
The consequence is not reasonable:
publishes its layer, and nothing reminds anyone to.
appliance / build-and-bootis satisfied bythat green, so the protection is inert during exactly the window where the
code is newest and least proven.
gh pr checks,from a green that booted a container and ran the real service. A reviewer
reading "pass" has no way to know which one they got without opening the job
and reading the step list.
keel-redis#5is in that state right now and looks ready to merge.What closes this
A skipped boot must not be reportable as a pass. Any of these would do, and the
choice should be argued in the pull request rather than assumed:
unpublished, so branch protection is not satisfied by it.
allow_unpublished: true) thata new appliance sets deliberately and removes once its layer is published,
so the exemption is visible in the caller's own workflow file and dies
naturally.
only to the genuine bootstrap case and cannot regress.
Whatever is chosen, the check's name or conclusion must differ between
"booted the appliance" and "did not boot anything", because the failure here is
that the two are indistinguishable.
Scope
Every repository that calls the shared
test-applianceworkflow is affected.Audit which of them currently rely on it while unpublished, and say so in the
pull request — a green that was never earned may exist on more than one repo.
Two corrections after auditing, one in the workflow's favour and one against.
In its favour: the skip is not silent. Step 5 writes a
::notice::and ajob summary that says, in as many words, "Nothing was built, assembled or
booted", and tells the reader to build and publish the layer. So the workflow
does record what it did. The defect is narrower than first stated, and it is
this: the conclusion is
success, and a conclusion is what branchprotection reads and what
gh pr checksprints. A summary nobody opens doesnot stop an unearned merge.
Against it: the audit. Asking the mirror for each appliance's manifest at
https://mirror.keellinux.org/layers/<name>.manifest, 2026-09-28:So exactly one repository is in the unearned-green state today,
keel-redis,and the other eleven gates are real. That bounds the damage, and it also shows
the exemption behaves exactly as designed — which is the point: the design is
what needs changing, not an accident to be patched.
The practical unblock for
keel-redis#5is to publish the redis layer andre-run the gate, which is already in progress. That fixes the instance. This
issue stays open for the design.
A code review of keel-mariadb#11 and keel-postgresql#7 found a second, wider
face of this defect, and it is worse than the one this issue was opened for.
Even when the layer is published, the gate does not test the pull
request.
appliance / build-and-bootfetches the published layer from themirror and boots that. On a pull request that changes the recipe, the published
layer is the one built from
main— i.e. the code before the change. The jobboots it, the service answers, the check goes green, and nothing in the pull
request was exercised at all.
So the failure mode this issue records ("skipped the boot, still green") is the
special case. The general case is: the boot gate is green on the strength of
code that is already merged, whatever the branch contains.
That makes the required check
appliance / build-and-bootunable to do the jobbranch protection is asking of it on any recipe change. It still has real value
— it catches a published layer that does not boot, and it caught the parent
mismatch it was written for — but it is not evidence about a branch.
Both of those pull requests state this honestly in their own bodies, with the
box left unticked, so this was known to their author and is not a
misrepresentation. It was not known to me when I applied branch protection
requiring that check on keel-lamp, keel-lapp and keel-apache-php, nor when I
was about to merge on the strength of three green ticks.
What this adds to the fix
Whatever is decided for the unpublished case, the published case needs an
answer too:
boots that. That is expensive and needs the build host, which is serialised
behind a lock, so it may not be a per-pull-request check at all.
actually does — it verifies the published layer, not the change — so nobody
reads it as proof of a branch again, and stop requiring it for merge.
Today the only evidence for such a change is a hand-run build that is not
reproducible (see the review's finding on the measurement harness).
Naming a check for what it proves is the whole of this issue. It applies to
both faces.