Conversation
… 500
Six install steps -- five in ci.yml, one in docs.yml -- need GCC 15 from
ppa:ubuntu-toolchain-r/test, and each called `add-apt-repository` exactly once.
Launchpad serves that call from a service that returns HTTP 500 often enough to
matter. On 2026-08-25 it took out roughly a dozen jobs across six pull requests
in one afternoon, every one dying in the dependency-install step before a single
file was compiled:
lazr.restfulclient.errors.ServerError: HTTP Error 500: Internal Server Error
b'GPGKeyTemporarilyNotFoundError'
Such a failure carries no information about the change under test, but in the
checks list it is indistinguishable from one that does, so each costs a reviewer
the time to open the log and rule it out -- and costs whoever is watching a
round of reruns. The outage is not ours to fix; treating a transient 500 as
fatal is.
All six now go through scripts/add_apt_repository_retrying.sh: five attempts,
linear backoff, each retry announced so a slow green is distinguishable from a
healthy one. Checked that `actions/checkout` precedes the install step in every
one of the six jobs, since the script does not exist before it.
It deliberately still fails after the last attempt rather than continuing
without the PPA. Carrying on would let the following apt-get install pull the
distro's older GCC, and the job would build and pass while testing a compiler
the project does not target -- a green tick for the wrong thing, which is worse
than a red one.
The helper has its own self-test, run in CI beside the existing checker
self-tests, because a retry wrapper nobody tests is worth less than no wrapper:
it looks like resilience while possibly retrying nothing, and the only way to
find out is during the outage it exists to survive. The test drives the script
against a stub whose failure pattern it controls and asserts the call count, so
"it retried" is distinguishable from "it happened to succeed".
Both directions checked: cutting ATTEMPTS to 1 fails four of its checks, and
letting a persistent outage exit 0 fails one.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
What is actually wrong with CI
Nothing is failing right now — 1 failure in the last 40 runs, and that one
was a stale pre-rebase run I have since fixed. What went wrong today was not a
defect in the pipeline's logic but its dependence on a third-party service with
no retry.
Six install steps — five in
ci.yml, one indocs.yml— need GCC 15 fromppa:ubuntu-toolchain-r/test, and each calledadd-apt-repositoryexactlyonce. Launchpad serves that call from a service that returns HTTP 500 often
enough to matter. On 2026-08-25 it took out roughly a dozen jobs across six pull
requests in one afternoon:
Every one of them died in the dependency-install step before a single file was
compiled. The affected legs were exactly those that pull from that PPA —
Application ladder,Valgrind memcheck,Linux / gcc-release,Linux / Qt6 WebSockets,Linux / all optional features,Build documentation.gcc-debugsurvived only because its apt cache hit and it never called Launchpad.
The cost is not the red tick. It is that a Launchpad 500 and a real regression
look identical in the checks list, so each one costs a reviewer the time to open
the log and rule it out — and costs whoever is watching a round of reruns. I
spent a fair part of today doing exactly that.
The fix
All six sites now call
scripts/add_apt_repository_retrying.sh: five attempts,linear backoff, each retry announced so a slow green is distinguishable from a
healthy one.
It still fails after the last attempt, deliberately. Continuing without the
PPA would let the following
apt-get installpull the distro's older GCC, andthe job would build and pass while testing a compiler the project does not
target — a green tick for the wrong thing, which is worse than a red one. The
final error names Launchpad and links the status page, so the next person does
not start by suspecting their own change.
I verified
actions/checkoutprecedes the install step in every one of the sixjobs, since the script does not exist before it:
linux-compilerslinux-qtladder-testslinux-all-featuresvalgrindbuild-docsThe helper is tested, and the test can fail
A retry wrapper nobody tests is worth less than no wrapper: it looks like
resilience while possibly retrying nothing, and the only way to find out is
during the outage it exists to survive. So it gets a self-test, run in CI beside
the repo's existing checker self-tests, following the
scripts/test_check_*.shconvention already in the tree.
The test drives the script against a stub whose failure pattern it controls and
asserts the call count, so "it retried" is distinguishable from "it happened
to succeed":
Mutation-tested in both directions:
ATTEMPTScut to 1 (no retry at all)Not done
is how the project gets the compiler it targets. Vendoring or a container
image would remove the dependency entirely, but that is a much larger change
and this one is worth having regardless.
apt.llvm.org. The clang legs fetch from a different host, whichhas not been flaky in the runs I looked at. Adding retries there speculatively
would be guessing; the same helper will fit if it ever is.