ci: wait for concurrent candidate publication
Nuvisphere/Platform-CI: Immutable QuickStack OCI deployment / Build once and deploy exact digest (push) Successful in 23s

This commit is contained in:
2026-08-24 09:40:35 +02:00
parent b6a550e9a3
commit 8f8110fb67
4 changed files with 89 additions and 6 deletions
@@ -6,6 +6,7 @@ import {
deployExactImage,
expandTokens,
mergeEnvironment,
pullCandidateArtifact,
resolveSecretEnvironment,
orderApplications,
resolveDeploymentBranch,
@@ -99,6 +100,46 @@ test("production pull requests validate tested candidates without rebuilding", (
);
});
test("production pull requests wait for a concurrently published candidate", async () => {
const registry = "gitea.nuvisphere.de";
const artifact = {
name: "webapp",
image: "innomieter/webapp",
requiredFiles: [],
};
const sourceSha = "1234567890abcdef1234567890abcdef12345678";
const digest = `sha256:${"a".repeat(64)}`;
const sleeps = [];
let pullCalls = 0;
const runCommand = (_command, args) => {
if (args[0] === "pull") {
pullCalls += 1;
if (pullCalls < 3) throw new Error("manifest unknown");
return "";
}
if (args[0] === "image") {
return `${registry}/${artifact.image}@${digest}\n`;
}
throw new Error(`Unexpected Docker command: ${args.join(" ")}`);
};
const result = await pullCandidateArtifact({
artifact,
registry,
sourceSha,
workspace: "/workspace",
dockerEnv: {},
pullAttempts: 3,
pullRetryMs: 25,
runCommand,
sleep: async (ms) => sleeps.push(ms),
});
assert.equal(pullCalls, 3);
assert.deepEqual(sleeps, [25, 25]);
assert.equal(result.exactImage, `${registry}/${artifact.image}@${digest}`);
});
test("validates OCI paths and repository-local build paths", () => {
assert.equal(validateTarget({ name: "Web", image: "Owner/Web", appId: "app-1" }).image, "owner/web");
assert.throws(() => validateTarget({ name: "Web", image: "owner/web", appId: "app-1", context: "../secret" }), /inside/);