pipeline v5.11.0 -- Fedora 44 base migration, retry-reason convergence, blocking secret detection
Consumer-visible base-image swap for two wrapper components, the
retry-reason cleanup finally reaching every template it should have,
the secret gate that actually blocks a leak, and a floating buildah
pin repinned to something Renovate can track. MINOR because `go-tool`
and `worker-ts` consumers now build and run on a materially different
base distro, not because any interface changed.
- **`go-tool` and `worker-ts`: migrated from the upstream Debian-based
images to Fedora 44, with `just` baked in.** Proves the same
Debian->Fedora pattern `latex` and `website` already run, ahead of
`python` and `rust-cli` following next. Consumers pinning these two
components now receive a glibc-based Fedora userland instead of
Debian's -- different package manager, different base libraries,
different toolchain packaging conventions -- and `just` ships in the
image rather than being installed per-job. `go-tool`: Fedora carries
one golang stream per release rather than a per-minor package, so
`GO_VERSION` now gates a build-time assertion instead of selecting a
package, and `GOPATH=/go` is set explicitly since Fedora's golang
package (unlike the upstream golang image) does not export it,
which would otherwise silently break the preserved `/go/bin` PATH
entry. `worker-ts`: a bare `dnf install nodejs` resolves to Fedora
44's default stream (24), not the pinned 22, so the versioned
`nodejsNN`/`nodejsNN-npm` packages are installed explicitly alongside
their weak-dep `-bin` counterparts that own the unversioned
`/usr/bin/node` and `/usr/bin/npm` (`install_weak_deps=False`
otherwise drops them). Verified against the freshly built images
before landing, via temporary `verify:go-tool`/`verify:worker-ts`
jobs that printed toolchain versions in place; both jobs are gone
again once the base was confirmed.
- **Retry-reason correction now reaches every template, including
`secret-verdict`.** GitLab deprecated the generic
`stuck_or_timeout_failure` retry:when value in 19.1 (removal in
20.0); it aliased exactly `stuck_pending_with_matching_runners`,
`stuck_pending_no_matching_runners`, `no_updates_running`, and
`no_updates_canceling`, so replacing it with that set preserves
identical retry coverage. The first pass landed across
`templates/*.yml` and `.gitlab-ci.yml`, but `secret-verdict.yml` was
added on a parallel branch and slipped past it -- its retry block,
and the README's documented default-policy example, both still
carried the deprecated value. GitLab still accepted it (deprecated,
not yet removed), so this was drift rather than a hard failure, but
it meant the one component landing in this same release was already
inconsistent with the fix. Caught and closed during this release's
prep; `ci/lint` confirms the corrected 10-value list produces zero
deprecation warnings everywhere it now appears.
- **`secret-verdict`: secret detection that actually blocks.** Replaces
the upstream `Jobs/Secret-Detection.gitlab-ci.yml` include. That
template's analyzer runs gitleaks with `--exit-code 0`, so it exits 0
even when it finds secrets, and no `allow_failure` setting can turn a
leak into a red pipeline. `secret-verdict` runs the same analyzer
with the same ruleset -- identical scan surface, so migration is a
swap of the `include:`, not a change in what gets flagged -- then
parses `gl-secret-detection-report.json` directly and exits nonzero
on a non-empty `vulnerabilities` array. A missing, empty, or
malformed report fails closed rather than reading as "no findings."
- **`container-image`: stopped floating on
`quay.io/buildah/stable:latest`.** quay.io rebuilds the `vX`/`vX.Y`/
`vX.Y.Z`/`latest` tags in place (proven 2026-08-03: all four
resolved to one digest pushed 31 May), and nothing tracked the pin --
no Renovate customManager covered `templates/*.yml` bodies, and
`pin-audit.py` only scanned `.gitlab-ci.yml`/`Containerfile`/
`*.container`. Repinned to `v1.43.1-immutable@sha256:fc649e18...`, a
real Renovate-trackable version tag quay does not rebuild in place,
matching ADOPTION.md's `<name>:<semver>@sha256:<digest>` convention.
Zero live consumers of this component today, so this was latent
rather than exploited; closed the same gap on both the Renovate side
(new customManager) and the local-gate side (pin-audit.py file match
extended to `templates/*.yml`).
Release-prep: `scripts/sync-image-pins.sh v5.11.0` moved every
`${NOMOGRAPH_REGISTRY}/*:v5.10.0` image pin (8 distinct refs) and every
`component:.../*@v5.10.0` include (15 distinct refs) across
`templates/` to v5.11.0 in the same commit as this tag, so
`image-pin-coherence` and `component-pin-coherence` land green rather
than catching what release-prep forgot -- exactly what those two
tag-only gates exist to enforce.