79f9a2dd62
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.
6.3 KiB
6.3 KiB
Changelog
All notable changes to parity-lib are documented here. This project follows semantic versioning; the version is a conceptual tag (no git tag is created).
Unreleased
- Feature:
verify-digestfor nix2container (cluster #195).mkNix2ContainerPublishnow also returns averify-digestapp that builds each locally-buildable arch image and prints its OCI manifest digest with NO registry contact (itcopyTos a throwaway localoci:dir and reads the digest skopeo derives). This formalizes the manifest digest as the parity contract: the OCI layers are builtreproducible = falseON PURPOSE (the fix for the "Digest did not match" caused by non-reproducible layer deps + nix2container's lazy tar regeneration), so byte-identical-tar parity is NOT promised — but the content-addressed manifest digest the registry stores the image under IS stable. Identical local vs CI digest ⇒ identical registry artifact. We do NOT flipreproducibletotrue(the inputs are not reproducible); the LOW-RISK digest-as-contract path was chosen instead. Generalized from the claude-plugin-registry prototype (55f2d0b) so every nix2container consumer gets it for free. pipeline-doctoris now GATE-READY (cluster #191/#193). It already exited non-zero on any failing required check; added a--strictmode that ALSO fails on anyWARN, so a.woodpecker.yamlstep or a server pre-receive hook can callpipeline-doctor --strict <repo>and rely on the exit code. Added a documentedci/local.shescape-hatch (cluster #196): a repo that must keep a hand-written Dockerfile/BuildKit pipeline may opt out of the archetype / parity-lib asserts (downgraded to warnings) if it ships aci/local.shlocal==CI entrypoint. Fixed a false-negative: the token / dev-tag / dry-run /meta.descriptioncontracts are GUARANTEED by parity-lib for a consumer (they live in the generated apps, not the consumer'sflake.nixtext), so a repo that consumes parity-lib now PASSES those by delegation instead of being penalized for not re-implementing them inline. Self-check stays green and a known-good consumer (numpy-s390x) now passes 9/9.- Audit: stage + push-staged uniform across all 8 builders (cluster #194).
Verified every archetype builder exposes a
stage-<arch>(build-parity, no registry contact, writes./.parity-stage) AND apush-staged(replay the staged artifact):mkPyPiWheelPublish,mkPyPiWheelPublishMulti,mkS390xNpmPublish,mkS390xNpmPublishMulti,mkGenericBinaryPublish,mkGoBinaryPublish(alias),mkNix2ContainerPublishandmkHelmPublish(stage-chart). All were already complete — no gaps to fill; the build-parity / publish-parity split is uniform. - Feature:
mkS390xNpmPublishMulti(cluster #192). A multi-version npm builder mirroring the PyPI multi one: publishes a fixed list of{ version; file; distTag? }per tag, each staged into its own dir andnpm published with its dist-tag (idempotent — "already exists" == success).filemay be a.nodeaddon OR a plain binary, andpackageJson(with a$VERSIONthe stage heredoc expands) declares the shape (mainvsbin), so it covers both nextjs-swc (16.1.6@latest+ 15.2.0@next15) and sentry-cli (a binary published as an npm package at two versions). Sharedparity_npm_publish_dirhelper added toci/parity-lib.sh. - Feature:
mkPyPiWheelPublishMulti(cluster #197). A multi-version PyPI builder that publishes a fixed list of{ version; wheel; }per tag instead of just the default — the pre-parity behaviour several*-s390xrepos rely on. Each wheel's real version is read from its filename (PEP 427), so stage/publish/push-staged need no side-channel map and a re-run is idempotent (409-skip per version). Sharedparity_pypi_post/parity_wheel_versionhelpers added toci/parity-lib.sh. First consumer:numpy-s390x(5 versions). - Fix (safety): dev-tag guard was ineffective. Every publish app body runs
VERSION="$(parity_derive_version <default>)"beforeparity_devtag_guard, so by the time the guard checked$VERSIONit was always non-empty (the derived default) and an accidental local--publishwith no explicit version and nov*tag still pushed (cluster #194 finding). The guard now reads a source-time snapshotPARITY_VERSION_EXPLICITcaptured before any clobber, so it correctly blocks unless the caller set$VERSIONor$CI_COMMIT_TAGmatches^v[0-9]. pipeline-doctor(cluster #191 security sweep): added a scoped per-file check asserting noset -xin token-bearingci/*.shscripts going forward — a script that references a registry token (REGISTRY_TOKEN/CI_REGISTRY_TOKEN/ anAuthorization: tokenheader) must not enable xtrace, which would echo the token to the build log. Token-free helpers (e.g. version parsers) are not flagged.
v0.1.0
Initial release (cluster #192/#193/#194, emmett#44).
lib.mkParityBuilders pkgsplus per-builder wrappers exposing the six archetype publish-app builders:mkPyPiWheelPublish— single-arch Gitea PyPI wheel.mkS390xNpmPublish— single-arch Gitea npm native addon.mkGenericBinaryPublish— single-arch Gitea generic-registry binary.mkGoBinaryPublish— alias ofmkGenericBinaryPublish(explicit archetype).mkNix2ContainerPublish— multi-arch OCI image withpublish-indexand:latestdigest copy.mkHelmPublish— Helm chart to an OCI registry.
- Each builder returns flake apps following the corrected parity standard:
stage-<arch>(build-parity, no registry),publish-<arch>(dry-run by default),publish-index(build-free, fail-closed multi-arch assembly via regctl),publish(all local arches + index +:latestlast), andpush-staged(replay./.parity-stage). - Shared shell library
ci/parity-lib.sh(token resolution with$REGISTRY_TOKEN+passfallback and never printed, dev-tag guard, version derivation, the dry-run gate, registry preflight, stage-dir helpers). packages.pipeline-doctor/apps.pipeline-doctor(cluster #193): static parity-contract checker that prints local-equivalent commands.flake.lockfully pinned; nixpkgs follows the sharedfleet-pinsnixpkgs-ci.