mandrel-platform 1.15.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -783,3 +783,55 @@ test("wiring: the check is absent from the PR-gating ci.yml", () => {
|
|
|
783
783
|
"ci.yml must not invoke the freshness check"
|
|
784
784
|
);
|
|
785
785
|
});
|
|
786
|
+
|
|
787
|
+
// ── The release gate (issue #533) ──────────────────────────────────────────
|
|
788
|
+
//
|
|
789
|
+
// The reasoning above is why a PR cannot carry this check — but it left the
|
|
790
|
+
// drift ungated entirely: `pin-drift.yml` reports it weekly and on push to
|
|
791
|
+
// main, both AFTER the merge that caused it, and nothing stopped a release
|
|
792
|
+
// shipping on top. Two did. v1.14.0's asset-download retry fix and v1.15.0's
|
|
793
|
+
// install watchdog both landed in the action directories while every workflow
|
|
794
|
+
// still pinned a sha that predated them, so every consumer that upgraded got
|
|
795
|
+
// an inert release.
|
|
796
|
+
//
|
|
797
|
+
// Release time is the one moment that is both satisfiable (the commit exists
|
|
798
|
+
// on main) and on the boundary that matters (nothing reaches a consumer
|
|
799
|
+
// un-repointed), so that is where the gate lives.
|
|
800
|
+
test("wiring: the release path REFUSES to publish stale first-party pins", () => {
|
|
801
|
+
const wf = readFileSync(join(REPO_ROOT, ".github/workflows/release-please.yml"), "utf8");
|
|
802
|
+
|
|
803
|
+
assert.ok(
|
|
804
|
+
wf.includes(SCRIPT_INVOCATION),
|
|
805
|
+
"release-please.yml invokes the freshness check"
|
|
806
|
+
);
|
|
807
|
+
|
|
808
|
+
const gate = jobBlock(wf, "pin-freshness-gate");
|
|
809
|
+
assert.ok(gate, "the gate runs in its own job");
|
|
810
|
+
assert.ok(gate.includes(SCRIPT_INVOCATION), "that job invokes the checker");
|
|
811
|
+
assert.match(
|
|
812
|
+
gate,
|
|
813
|
+
/fetch-depth: 0/,
|
|
814
|
+
"a shallow checkout cannot resolve the pinned manifests"
|
|
815
|
+
);
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
test("wiring: a FAILED freshness gate actually blocks the publish", () => {
|
|
819
|
+
// The load-bearing half. `npm-publish` is guarded by `!cancelled()`, an
|
|
820
|
+
// always()-family condition: a failed `needs` job does NOT skip it. Without
|
|
821
|
+
// an explicit success assertion the gate would be decorative — present,
|
|
822
|
+
// green-looking, and unable to stop anything.
|
|
823
|
+
const wf = readFileSync(join(REPO_ROOT, ".github/workflows/release-please.yml"), "utf8");
|
|
824
|
+
const publish = jobBlock(wf, "npm-publish");
|
|
825
|
+
|
|
826
|
+
assert.ok(publish, "the npm-publish job exists");
|
|
827
|
+
assert.match(
|
|
828
|
+
publish,
|
|
829
|
+
/needs: \[[^\]]*pin-freshness-gate[^\]]*\]/,
|
|
830
|
+
"npm-publish depends on the gate"
|
|
831
|
+
);
|
|
832
|
+
assert.match(
|
|
833
|
+
publish,
|
|
834
|
+
/needs\.pin-freshness-gate\.result == 'success'/,
|
|
835
|
+
"npm-publish asserts the gate SUCCEEDED, not merely that it ran"
|
|
836
|
+
);
|
|
837
|
+
});
|