mirror of
https://github.com/cozystack/cozystack.git
synced 2026-10-28 07:37:49 +09:00
hack/promote-packages-artifact.sh pushes the candidate BEFORE rewriting installer values, so the artifact carries the rc tree's platformSourceUrl/platformSourceRef verbatim — and hack/verify-promoted-packages.sh reads exactly those two fields back out of it as the candidate's rc baseline, requiring a trusted repository and an immutable `digest=sha256:<64 hex>` pin. The publisher checked neither. A tag-form ref or an untrusted URL in the rc tree published a candidate and pushed two commits regardless; the refusal arrived later, in the promote PR gate or in finalize, once the staging branch and the draft release already existed. Check both at dispatch time instead, while nothing has been written. A copied regex would drift from the guard it is bringing forward and quietly restore the late failure, so the trusted repository and the digest pattern move into hack/lib/promoted-packages.sh and both halves source it. That makes the library part of what the verifier needs at run time, so promote's base-branch precondition gains it: the list exists because the base's own workflows run after merge, and a base carrying the verifier without its library fails at the same two late points. Tests: both preflights are covered, each asserting the mock registry client was never invoked — "exited non-zero" alone does not say nothing was written. Both fail with the preflight removed. The publisher fixtures now pin the trusted repository the way a real rc tree does, and still send the candidate elsewhere via REGISTRY so the rewrite assertions keep their teeth. Also covers a malformed PROMOTION_ID. It is not attacker-influenced, but it is the run-uniqueness suffix of the candidate tag and retention.yaml deletes a candidate only when every tag on the manifest matches `promotion-v…-run-[0-9]+-[0-9]+`; a value outside that shape publishes an artifact no cleanup pass can ever collect. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
26 lines
1.5 KiB
Bash
26 lines
1.5 KiB
Bash
# shellcheck shell=sh
|
|
# Shared definitions for the stable-candidate packages artifact.
|
|
#
|
|
# Sourced by hack/promote-packages-artifact.sh, which publishes the candidate,
|
|
# and hack/verify-promoted-packages.sh, which proves it. The publisher's whole
|
|
# reason to inspect the pin at all is to make the verifier's refusal land at
|
|
# dispatch time, before a registry write, two commits and a draft release exist
|
|
# — so the two have to be testing the same thing. Copied constants would drift
|
|
# apart silently and turn that dispatch-time refusal back into the late failure
|
|
# it was added to remove; they live here instead.
|
|
#
|
|
# Not a general library: promotion is the only caller, and both halves run from
|
|
# a `hack`-only sparse checkout of a trusted ref, so this file has to stay
|
|
# inside hack/ next to them.
|
|
|
|
# The one OCI repository a packages candidate may ever be published to or read
|
|
# back from. Overridable only so the behavioural suites can point both halves
|
|
# at a fixture registry; production never sets it.
|
|
EXPECTED_PACKAGES_REPOSITORY="${EXPECTED_PACKAGES_REPOSITORY:-oci://ghcr.io/cozystack/cozystack/cozystack-packages}"
|
|
|
|
# An immutable Flux OCI source pin, `digest=sha256:<64 lowercase hex>`. The
|
|
# tag form Flux also accepts is exactly what promotion must neither publish nor
|
|
# accept: a stable installer pinned by tag resolves to whatever that tag points
|
|
# at later, which is how a stable install ends up serving rc content (#3477).
|
|
PACKAGES_DIGEST_REF_PATTERN='^digest=sha256:[0-9a-f]{64}$'
|