# shellcheck shell=sh disable=SC2034 # ============================================================================= # foundation/VERSIONS — determinism pin-file (PLAN-002 §Determinism, baseline D5) # ============================================================================= # # WHAT THIS IS # The single source of truth for every container image and every host tool the # foundation egg depends on. preflight/ and CI both read this file. An upgrade # is a one-line diff here (PLAN-002 §7.1). # # FORMAT # Plain `KEY=value`, one per line. This file is BOTH: # * shell-`source`-able: `set -a; . ./VERSIONS; set +a` # * greppable: `grep '^IMAGE_FORGEJO=' VERSIONS` # No spaces around `=`. Values are unquoted simple tokens. Comments start `#`. # Keys are UPPER_SNAKE_CASE. Do not use shell expansion in values. # # IMAGE PINNING (determinism — D5: "No floating tags") # The DESIRED end state is to pin every image by DIGEST: # IMAGE_=:@sha256:<64-hex-digest> # A tag alone is mutable; the digest is the immutable content address. # # Where a real sha256 digest could NOT be resolved at authoring time (offline / # no registry access), the value carries the stable version TAG plus the literal # placeholder token `PIN_DIGEST` in the digest position: # IMAGE_=:@sha256:PIN_DIGEST # preflight treats `PIN_DIGEST` as "not yet pinned" and emits a WARNING (not a # failure) so the scaffold is usable before digests are resolved. CI for a real # `pulumi up` SHOULD fail-closed on any remaining PIN_DIGEST (gate that later). # # HOW TO PIN A DIGEST (`pin-digests` procedure — run when online, per image) # For each IMAGE_* below, resolve the multi-arch (or linux/amd64) digest and # replace `PIN_DIGEST` with the real hex, e.g.: # # # whole image index digest (recommended — arch-independent): # docker manifest inspect caddy:2.10 \ # --verbose 2>/dev/null | jq -r '.[0].Descriptor.digest // .Descriptor.digest' | head -1 # # # OR, simpler, pull then read the repo digest docker recorded: # docker pull caddy:2.10 # docker inspect --format '{{index .RepoDigests 0}}' caddy:2.10 # # -> caddy@sha256: ; copy the after sha256: # # # OR with skopeo (no pull): # skopeo inspect docker://caddy:2.10 | jq -r '.Digest' # # Then set: IMAGE_CADDY=caddy:2.10@sha256: # Commit the VERSIONS diff (conventional commit, e.g. `chore(versions): pin caddy digest`). # # HOST TOOL VERSIONS are MINIMUMS (>=). preflight compares the installed tool # version against TOOL__MIN using a numeric dotted-version comparison. # ============================================================================= # ----------------------------------------------------------------------------- # CONTAINER IMAGES (CONTRACT_003 §3.2 — every container the egg runs) # Format: IMAGE_=:@sha256: # ----------------------------------------------------------------------------- # Caddy: the egg runs a CUSTOM build with the Cloudflare DNS-01 plugin (standard # caddy:2 lacks it) — recipe + pinned base digests + module version live in # containers/caddy-cloudflare/Dockerfile. This is the pinned FINAL base it derives. IMAGE_CADDY=caddy:2.10@sha256:c3d7ee5d2b11f9dc54f947f68a734c84e9c9666c92c88a7f30b9cba5da182adb IMAGE_FORGEJO=codeberg.org/forgejo/forgejo:11@sha256:d98d860ea64fd36cb0aabf0b46bbe1a37566b498eee4af0a6b246d5a45759d6d IMAGE_POSTGRES=postgres:17@sha256:5c855ad7b85e68e48a62f34662853f38b57c1c1d80f3a927ab58034fd6d31c5e IMAGE_VAULT=hashicorp/vault:1.18@sha256:750bb37c1638fa194ab37053a81618c61bb0491ddec6fccac87c07a8e6cd8166 IMAGE_RUSTFS=rustfs/rustfs:latest@sha256:fa19210ac4697c79d7ccca1ec9b0eb91aebacc6691991ffb14014bb3c67e6cc3 IMAGE_ACT_RUNNER=code.forgejo.org/forgejo/runner:6@sha256:PIN_DIGEST IMAGE_REGISTRY=registry:2@sha256:PIN_DIGEST # Tool image: MinIO client `mc` — used transiently (never a long-running service) # for S3 control-plane ops against RustFS: bucket creation + service accounts # (T04) and backup put/get (T12). RustFS speaks enough of the MinIO admin API. IMAGE_MC=minio/mc:latest@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727 # NOTE on specific images: # IMAGE_RUSTFS uses `latest` because RustFS does not (yet) publish stable # semver tags reliably (PLAN-002 R3 — RustFS is young). MUST be pinned by # digest before any real deploy; the digest is what gives determinism here. # IMAGE_FORGEJO / IMAGE_ACT_RUNNER pull from Forgejo's own registries # (codeberg.org / code.forgejo.org), not Docker Hub. # ----------------------------------------------------------------------------- # HOST TOOLS (PLAN-002 §9.1 "binary installation" / "host validation") # Format: TOOL__MIN= (preflight enforces installed >= MIN) # The matching CLI binary name preflight looks for is in checks/tools.sh. # ----------------------------------------------------------------------------- # --- orchestration toolchain --- TOOL_PULUMI_MIN=3.140.0 TOOL_BUN_MIN=1.1.0 TOOL_NODE_MIN=20.0.0 # --- container + scm --- TOOL_DOCKER_MIN=24.0.0 TOOL_GIT_MIN=2.34.0 # --- crypto / compression / json (backup + secrets handling) --- TOOL_AGE_MIN=1.1.0 TOOL_ZSTD_MIN=1.5.0 TOOL_JQ_MIN=1.6 # --- service CLIs used by bootstrap / backup / DR --- TOOL_VAULT_MIN=1.15.0 TOOL_PSQL_MIN=15.0 TOOL_PG_DUMP_MIN=15.0 # --- ssh client (Pulumi docker-over-SSH provider, git-over-ssh) --- TOOL_OPENSSH_MIN=8.0 # --- S3 / RustFS client (bucket ops, backup put/get). MinIO client `mc`. --- TOOL_MC_MIN=2023.01.01