feat(parity): gate-ready pipeline-doctor + OCI verify-digest + stage/push-staged audit
pipeline-doctor (#191/#193): add --strict (fail on WARN) so a .woodpecker.yaml step or pre-receive hook can gate on exit code; add documented ci/local.sh escape-hatch (#196); fix false-negative — token/dev-tag/dry-run/meta contracts are guaranteed by parity-lib for a consumer, so consumers PASS by delegation instead of being penalized for not re-implementing them inline. Self-check and numpy-s390x both pass 9/9. mkNix2ContainerPublish (#195): add verify-digest app that builds each local arch image and prints its OCI manifest digest (no registry contact), formalizing the content-addressed manifest digest as the parity contract. reproducible=false is kept deliberately (non-reproducible layer deps); digest-as-contract is the low-risk path. Generalized from claude-plugin-registry 55f2d0b. stage/push-staged audit (#194): verified all 8 builders expose stage-<arch> + push-staged; all already complete, no gaps.
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
# publish all locally-buildable arches + publish-index; ':latest' is a
|
||||
# digest copy of ':TAG' done LAST as the idempotent mutation.
|
||||
# push-staged replay artifacts from ./.parity-stage to the registry.
|
||||
# verify-digest (OCI only, cluster #195) build each local arch image and print
|
||||
# its OCI manifest digest — the content-addressed parity contract
|
||||
# (layers are reproducible = false, so parity is at the digest,
|
||||
# not byte-identical tars). No registry contact.
|
||||
#
|
||||
# Not every archetype yields every app: a single-arch wheel/binary/npm addon
|
||||
# has no multi-arch index, so it exposes stage/publish/push-staged only. The OCI
|
||||
@@ -699,6 +703,42 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
# Compute one arch image's OCI manifest digest with NO registry contact
|
||||
# (cluster #195). copyTo a throwaway local OCI dir and read back the
|
||||
# content-addressed manifest digest skopeo derives — this is the digest the
|
||||
# registry stores the image under. Because the layer is built with
|
||||
# reproducible = false (a DELIBERATE fix for the "Digest did not match"
|
||||
# from non-reproducible layer deps — nix2container's lazy tar regeneration
|
||||
# rehashes differently across hosts), byte-identical-tar parity is NOT
|
||||
# promised; the manifest digest IS the parity contract. Identical local vs
|
||||
# CI digest ⇒ identical image in the registry.
|
||||
digestArch = arch: ''
|
||||
echo "→ ${imageName}:$VERSION-${arch} (local build, no registry contact)"
|
||||
ocidir="$(mktemp -d)"
|
||||
${lib.escapeShellArg "${images.${arch}.copyTo}"}/bin/copy-to "oci:$ocidir:${arch}" >/dev/null
|
||||
digest="$(skopeo manifest-digest "$ocidir/blobs/sha256/$(
|
||||
jq -r '.manifests[0].digest | sub("sha256:";"")' "$ocidir/index.json"
|
||||
)")"
|
||||
rm -rf "$ocidir"
|
||||
echo " ${arch}: $digest"
|
||||
'';
|
||||
|
||||
verifyDigest = pkgs.writeShellApplication {
|
||||
name = "verify-digest";
|
||||
runtimeInputs = baseInputs ++ [
|
||||
pkgs.nix
|
||||
pkgs.skopeo
|
||||
pkgs.jq
|
||||
];
|
||||
text = ''
|
||||
${head}
|
||||
VERSION="$(parity_derive_version ${lib.escapeShellArg version})"
|
||||
echo "OCI manifest digests for ${imageName}:$VERSION (content-addressed parity, cluster #195)"
|
||||
echo " reproducible = false ⇒ parity is asserted at this digest, not byte-identical tars."
|
||||
${lib.concatMapStringsSep "" digestArch localArches}
|
||||
'';
|
||||
};
|
||||
|
||||
mkArchPublish =
|
||||
arch:
|
||||
pkgs.writeShellApplication {
|
||||
@@ -838,6 +878,8 @@ let
|
||||
mkApp publishAll "Publish all local arches + index; :latest = digest copy of :TAG (last mutation).";
|
||||
"push-staged" =
|
||||
mkApp pushStaged "Replay staged ${imageName} arch closures from .parity-stage to the registry.";
|
||||
"verify-digest" =
|
||||
mkApp verifyDigest "Build each local arch image and print its OCI manifest digest (content-addressed parity check, cluster #195; no registry contact).";
|
||||
};
|
||||
|
||||
# =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user