ci: consolidate retry and failure diagnostics, add swap headroom - #736
Merged
Conversation
…nd failure diagnostics Signed-off-by: Giles Cope <gilescope@gmail.com>
|
| Branch | Total Count |
|---|---|
| main | 4004 |
| This PR | 4012 |
| Difference | +8 (0.2%) |
📁 Changes by file type:
| File Type | Change |
|---|---|
| Go files (.go) | ➖ No change |
| Documentation (.md) | ❌ +3 |
| Earthfiles | ➖ No change |
Keep up the great work migrating from Earthly to Earthbuild! 🚀
💡 Tips for finding more occurrences
Run locally to see detailed breakdown:
./.github/scripts/count-earthly.shNote that the goal is not to reach 0.
There is anticipated to be at least some occurrences of earthly in the source code due to backwards compatibility with config files and language constructs.
janishorsts
reviewed
Aug 1, 2026
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
…ers via docs Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
janishorsts
approved these changes
Aug 11, 2026
janishorsts
left a comment
Collaborator
There was a problem hiding this comment.
LGTM.
I have a slight concern about losing the visibility of indeterministic failures when retrying.
gilescope
enabled auto-merge (squash)
August 11, 2026 08:07
Signed-off-by: Giles Cope <gilescope@gmail.com>
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.
Extracted from #442 (the buildkit upgrade) so the CI flake mitigations can land independently of the bump. Net effect on the workflows is a deletion: two composite actions replace 33 hand-copied blocks.
earth-retry— 16 retry loops become one actionNon-deterministic earthly
Canceledfailures (different targets each run, no signal received) were already retried, by 16 near-identical inline loops across 10 workflows — ~270 lines that had drifted into 11 distinct shapes, varying in attempt count,sleep, re-bootstrap, and log capture. They are now one composite action.Attempts are harmonised at 3 everywhere, previously 2 or 3 depending on which copy you landed on. Genuine failures still fail: the final attempt's exit code propagates.
Between attempts the buildkitd container, cache volumes and
~/.earthly/buildkitare dropped. Dropping the container alone isn't enough — earthly's client-side state still references the dead session and the retry fails immediately withno active sessions.The buildkitd log is now dumped before the reset destroys it at all 16 sites. Exactly one of the previous copies did this; the other 15 discarded the only evidence that made attempt-1 session-loss failures diagnosable.
failure-diagnostics— 17Buildkit logssteps become one actionEvery workflow had a hand-rolled
docker logs earthly-buildkitdfailure step. Two of them sat immediately beside afailure-diagnosticsstep that already did strictly more, dumping the same log twice.All 17 now use the action, which loops four daemon names rather than one, and adds the memory, swap and kernel-OOM context needed to tell an OOM kill from a real failure.
LOG_TAILdefaults to 2000 so the consolidation isn't a coverage regression against the copies that dumped the log in full.The action is written to be usable outside this repo — every input defaults (
BINARY: autoprobes docker/podman/nerdctl), Linux-only probes are skipped on macOS runners rather than failing noisily, it warns and continues when no engine is present, and it always exits 0 so diagnostics never mask the failure that triggered them. It ships with a README, anddocs/ci-integration/now points users at it.Also fixes
build-earthly.yml's old handler, which loggedearth-buildkitd— a container name that has never existed — and so had been silently logging nothing on every failed build.Memory headroom
Swap setup moves from two duplicated inline blocks into
scripts/ci/add-swap.sh:mkswapplus ~25G of toolchain deletion costs a minute, and nothing downstream needs to block on it. Output goes to$RUNNER_TEMP/add-swap.log, whichfailure-diagnosticsdumps./mnt, the ~70 GiB ephemeral disk, on GitHub images) instead of/, so the swapfile stops competing with docker and buildkit layers for the root disk. Selection is dynamic — fstype and free space are checked, with/as the fallback.stage2-setupnow adds swap on the test path too, matching the build path.+lint-scriptscoversscripts/ci/*.sh, so the script is shellchecked by+lint-all.Swap is framed as removing memory from the list of suspects, not as a diagnosis. The same signatures in this repo's history have also been a wget flake and a fatal stats decode, so the mix is workload-specific; what makes memory worth pre-empting is that an OOM kill leaves no trace in the job log and so cannot be ruled out after the fact.
Follow-up filed
#795 proposes making this reliable in the engine rather than in CI:
earth --retries N --retry-timeout 5mwithRUN --no-retryas a poison marker, and a configurable regex list for classifying retryable output. BuildKit already retries 5xx/ECONNRESET/io.EOFwith exponential backoff inutil/resolver/retryhandler, but only on the registry path —RUNand the HTTP/git sources get nothing. Cross-references moby/buildkit#6429, which covers the per-RUNhalf that needs layer reset.Not in this PR
Stays in #442, each for its own review:
buildkitd-v0.8.17-fix.1→fix.5) and theactions-setuppinWAITblocks,group13/group14)buildkit_max_parallelism 1— not needed on mainAn earlier revision of this branch also made the earthly-next (Tick-Tock) workflow opt-in. The merge of
mainsuperseded that: #615 restructurednextinto anext-testsjob under the sharedci-test-suite.ymland deleted the standalone workflow the opt-in change depended on.main's structure was taken; the load-reduction change is not in this PR.Verification
yqparses every workflow and composite action;actionlintclean on all changed files.shellcheckclean onadd-swap.shand both extracted action scripts, using the repo's pinned alpine shellcheck.earth-retryexercised directly: succeeds-first-try, fails-then-succeeds, exhausts-attempts-and-propagates-rc, and the multi-line last-command-wins rule that matches the inlineset +esemantics it replaces.add-swap.shexercised end-to-end in a privileged container against a real ext4 loop device (fallocate → mkswap → swapon, detach,--waitpropagation, idempotent re-run), plus disk-selection rejection paths on a Linux host.failure-diagnosticsexecuted on macOS (BSD branch) and in a bare Linux container with no engine present.Known gaps
reusable-misc-tests-1.ymlpreviously used 3 attempts where its peers used 2; harmonising to 3 preserves it, but whetherremote-cachegenuinely needs more than the rest is untested either way.reusable-secrets-integrations.yml:59passesEARTHLY_TOKENtostage2-setup, which declares no such input (GHA drops it silently). Present onmain; adding the input would quiet the lint without establishing whether the token was ever needed.🤖 Generated with Claude Code