fix(ci): publish registry blobs in bounded chunks
CI / check (push) Successful in 52s
CI / deploy (push) Successful in 1m6s
CI / publish-container (push) Failing after 1m2s

This commit is contained in:
Simo committed 2026-09-09 20:22:07 +02:00
1 parent 047cd9f3dd
commit 2af244b634
5 files changed
+74 -8

No files matched your search

+1 -1
View File
@@ -62,7 +62,7 @@ it("verifies portability before publishing and uses committed build context", ()
expect(publish).toContain("git archive HEAD");
expect(
publish.indexOf("node scripts/verify-portable-image.mjs"),
).toBeLessThan(publish.indexOf("docker push"));
).toBeLessThan(publish.indexOf("regctl image import"));
expect(publish).toContain("--password-stdin");
expect(publish).not.toContain(":latest");
});
+26 -5
View File
@@ -17,7 +17,7 @@ const bash =
.find((path) => existsSync(path)) ?? "bash")
: "bash";
const sha = "a".repeat(40);
function simulate(scenario: string, namespace = "") {
function simulate(scenario: string, namespace = "", expectedStatus = 0) {
const dir = mkdtempSync(join(tmpdir(), "cms-publish-test-"));
try {
const result = spawnSync(
@@ -42,7 +42,7 @@ function simulate(scenario: string, namespace = "") {
},
);
if (result.error) throw result.error;
expect(result.status, result.stdout + result.stderr).toBe(0);
expect(result.status, result.stdout + result.stderr).toBe(expectedStatus);
return readFileSync(join(dir, "calls"), "utf8");
} finally {
rmSync(dir, { recursive: true, force: true });
@@ -57,7 +57,7 @@ describe("verified application image reuse", () => {
expect(calls).not.toContain("docker build --network=host --build-arg");
expect(
calls.indexOf("verify scripts/verify-portable-image.mjs"),
).toBeLessThan(calls.indexOf("docker push"));
).toBeLessThan(calls.indexOf("regctl image import"));
});
it.each(["missing", "mismatch"])(
"builds committed source when verification marker is %s",
@@ -71,10 +71,31 @@ describe("verified application image reuse", () => {
it("uses the token account namespace instead of the repository owner", () => {
const calls = simulate("verified");
expect(calls).toContain(`docker push registry.invalid/simo/cms:${sha}`);
expect(calls).toContain(
`regctl image import registry.invalid/simo/cms:${sha}`,
);
expect(calls).not.toContain("registry.invalid/owner/cms");
});
it("supports an explicit organization namespace", () => {
const calls = simulate("verified", "My-Org");
expect(calls).toContain(`docker push registry.invalid/my-org/cms:${sha}`);
expect(calls).toContain(
`regctl image import registry.invalid/my-org/cms:${sha}`,
);
});
it("bounds uploads and verifies both published image configs", () => {
const calls = simulate("verified");
expect(calls).toContain("--blob-chunk 8388608 --blob-max 8388608");
expect(calls).not.toContain("docker push");
expect(calls.match(/regctl image import/g)).toHaveLength(2);
expect(calls.match(/regctl manifest get/g)).toHaveLength(2);
});
it.each(["upload-fails", "wrong-config", "bad-checksum"])(
"stops publication on %s",
(scenario) => {
const calls = simulate(scenario, "", 1);
expect(calls).not.toContain(
`regctl image import registry.invalid/simo/cms:${sha} `,
);
},
);
+15
View File
@@ -12,3 +12,18 @@ docker() {
fi
}
export -f git tar node docker
curl() {
local output="${@: -1}"
cat > "$output" <<'MOCK'
#!/usr/bin/env bash
echo "regctl $*" >> "$TEST_DIR/calls"
if [[ "$1 $2" = "image import" && "$SCENARIO" = upload-fails ]]; then exit 1; fi
if [[ "$1 $2" = "manifest get" ]]; then
if [[ "$SCENARIO" = wrong-config ]]; then echo sha256:wrong; else echo sha256:candidate; fi
fi
MOCK
}
sha256sum() { cat >/dev/null; [[ "$SCENARIO" != bad-checksum ]]; }
uname() { echo x86_64; }
export -f curl sha256sum uname