mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-11 05:06:36 +00:00
Fork CI run 41147980556 pgAdmin#0 failed in sys-ctl-hlth-runtime with
"stalwart_webmail: PHP 8.4.26 is below the security floor 8.4.27".
The deploy ran the fork's GHCR mirror of roundcube/roundcubemail:1.7.5-
apache, copied on 10-19 with PHP 8.4.26, while upstream re-pushed the
same tag on 10-27 with PHP 8.4.27. Branch CI runs the sync with
--only-missing, which skipped the tag because it existed ("destination
exists, skipping") without comparing digests, and the full refresh only
runs on the fork's default branch, which still pins 1.7.4.
- utils/docker/registry.py: manifest_digest() reads the
Docker-Content-Digest of a reference with a HEAD request, which does
not count against Docker Hub's pull allowance.
- GHCRProvider.is_stale() reports a mirrored tag as stale only when both
registries answer with a digest and the two differ.
- Under --only-missing an existing tag is re-copied when it is stale; a
failed re-copy is reported on stderr with the image and keeps the
existing copy, so one refresh cannot block every deploy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirror 🪞
Plan and execute the GHCR image mirror pipeline: emit the mirrors.yml mapping that redirects role-declared images to the GHCR mirror, push images upstream-to-GHCR, and clean up stale mirror packages.
The sync also mirrors the images the CI runner pulls itself, outside every role: the tagged image literals of compose.yml and compose/cache.override.yml, and the image keys of default.env listed in RUNNER_ENV_IMAGES (discovery.py). On a GitHub runner, runner_mirror.py layers a generated compose override that points those services at their mirror, and hands the certificate generator the mirrored init image.