How images stay current
Rebuilding an image and upgrading its application are different operations, so they run on separate loops. Neither waits on the other, and neither needs a human.
1 · Six-hour rebuilds
build.yml rebuilds the complete catalog every six hours. It keeps the currently pinned application version but consumes current Wolfi packages and toolchains — so an upstream glibc or OpenSSL fix reaches every image without anyone changing a line of code.
For a source-built image the pipeline is:
verified source archive
→ native x86_64 and ARM64 Melange packages
→ production and dev Apko images
→ smoke test and production-image Grype scan
→ multi-architecture publish
→ Cosign signature, SPDX SBOM, and SLSA provenance
→ verification and catalog artifacts Pull requests build and test but never publish. Only trusted non-PR runs push to GHCR.
2 · Application-version updates
update-versions.yml checks source-built applications daily against a declarative registry (versions.yaml). It updates the version, verifies the upstream artifact checksum, resets the epoch, opens a pull request, and enables auto-merge once required checks pass.
Major-version pins stop unattended breaking upgrades. When a new major appears the workflow can open an issue for explicit review rather than bumping across it.
For package-based images:
- Rolling Wolfi packages (
nginx-mainline,apache2,sqlite,bun) advance through the six-hour rebuild. - Versioned families (Python, Go, Node.js, .NET, Java, PostgreSQL) get patch releases through rebuilds, while update-wolfi-packages.yml opens PRs when the package family itself must change.
3 · Transitive dependency patches
patch-go-deps.yml scans published Go binaries every six hours and proposes targeted module updates for fixable vulnerabilities. It preserves existing security pins, harmonizes related module families, and for dependency-sensitive applications probes each candidate fix against a real compile, keeping only those that still build.
patch-deps.yml does the same for Rails gems, Qdrant Rust crates, Keycloak Maven dependencies, and bundled Java archives in OpenSearch and Keycloak.
Generated changes land as automated pull requests — the normal image build is the integration gate before auto-merge. Cassandra, Solr, and Pulsar bundled-JAR findings are report-only until their tightly coupled dependency families get an explicit compatibility review.
4 · Guardrails
Automation that fails silently is worse than none, so each of these turns an invisible problem into a failed build.
| Check | Runs | Enforces |
|---|---|---|
| Auto-update coverage | Every build | All 96 images have exactly one live update mechanism — an image cannot be silently frozen. |
| Catalog validation | Every build | The published catalog and the build matrix can never drift apart. |
| Workflow lint | Workflow changes | Actionlint and ShellCheck, so a shell error cannot reach a scheduled run on main. |
| Branch auto-update | Push to main, every 30 min | Keeps auto-merge pull requests from stalling under strict branch protection. |
| Retention | Weekly | Prunes untagged and expired dated versions. Deletion is dry-run unless explicitly enabled. |