ci: carry the publish hardening back from builder - #2279
Merged
Conversation
Review on OpenIPC/builder#121 found two holes in its publish job. That job was seeded from this one, and both holes are still here. The artifact download runs with continue-on-error, so a transient or real download failure produced an empty dist/, the count guard skipped the publish step, the job went green, and ci-gate accepts publish=success -- a nightly could silently write nothing while the run stayed green. The flag stays, because it is load-bearing for exactly one case: a matrix where every board failed uploads no fw-* artifact at all, and a hard download failure there would mask the real reason in the gate. Collect now turns it back into a failure for every other case: a green matrix with a download that did not succeed is an error, and a green matrix with zero collected assets is an error. Only "matrix failed and produced nothing" is still tolerated, and the gate fails that run on the matrix result anyway. The nightly and latest tag moves were unconditional once any asset existed. dist/ can hold sidecars and no images -- one board producing a size report and no .tgz is enough -- and the script would force-move the two tags flashers pull from to a build with no firmware behind them. Both now move only when there is at least one image to move them to; otherwise they stay on yesterday's build, with a warning. The count is also normalised through tr. On the runner's GNU coreutils wc does not pad, so this was not exploitable here -- padding is BSD behaviour -- but the guard should not depend on which wc is in front of it. While in the area, ci-matrix.py now writes $GITHUB_OUTPUT itself instead of documenting that it does while relying on the workflow to redirect stdout (the docstring inaccuracy was also flagged on builder). Under a redirect every print() is one keystroke away from corrupting the step outputs, and a crash between the first line and the last leaves a half-written file that Actions still reads. Falls back to stdout when the variable is unset; --stdin never touches the file. All four collect states and all output paths checked offline; none of the publish path can run on a pull request. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Summary by QodoCI: Harden nightly publish gating and ci-matrix step outputs
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can route each action level your way: inline, summary, both, or drop |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Review on OpenIPC/builder#121 found two holes in its publish job. That job was seeded from this one — and both holes are still here, where they matter more: this nightly is the one
sysupgradeusers flash from daily.1. A failed artifact download published nothing and stayed green
The download runs with
continue-on-error: true, so a transient failure produced an emptydist/, the count guard skipped publishing, the job succeeded, andCI Gateacceptspublish=success.The flag stays — it is load-bearing for exactly one case: a matrix where every board failed uploads no
fw-*artifact at all, and a hard download failure there would mask the real reason.Collect assetsnow turns it back into a failure everywhere else:2.
nightly/latestcould be force-moved to a build with no firmware behind themThe tag moves were unconditional once any asset existed — and
dist/can hold sidecars and no images (one board producing asizes.*.jsonand no.tgzis enough). Both tags now move only whenIMAGESis non-empty; otherwise they stay on yesterday's build, with a warning.Also normalised the count through
tr. On the runner's GNU coreutilswcdoes not pad — that's BSD behaviour, so this wasn't exploitable here — but the guard shouldn't depend on whichwcis in front of it.3.
ci-matrix.pyowns$GITHUB_OUTPUTSame docstring inaccuracy flagged on builder: it claimed to write
$GITHUB_OUTPUTwhile printing to stdout and relying on the workflow to redirect. Under a redirect everyprint()is one keystroke away from corrupting the step outputs, and a mid-run crash leaves a half-written file Actions still reads. The script now appends to$GITHUB_OUTPUTitself when set, prints when not, and--stdinnever touches the file.Testing
None of the publish path can run on a pull request, so: all four collect states and all four output paths verified offline (the two previously-green failure states now fail), YAML parses,
--self-testgreen. This PR touchesci-matrix.py, so it correctly runs the full 96-board matrix — and tonight's 22:30 UTC nightly is the first live pass over the new publish logic if this merges before then.🤖 Generated with Claude Code