fix(ci): validate artifact package source sha

This commit is contained in:
Vincent Koc
2026-06-21 15:00:31 +02:00
parent eb00d499d1
commit 5693fcda78
2 changed files with 57 additions and 0 deletions
@@ -487,6 +487,18 @@ export async function readArtifactPackageCandidateMetadata(dir) {
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
throw new Error(`artifact package-candidate.json must contain a JSON object`);
}
const packageSourceSha =
typeof parsed.packageSourceSha === "string" ? parsed.packageSourceSha.trim() : "";
if (packageSourceSha && !/^[0-9a-f]{40}$/iu.test(packageSourceSha)) {
throw new Error(
"artifact package-candidate.json packageSourceSha must be a 40-character commit SHA",
);
}
if (typeof parsed.packageSourceSha === "string") {
return packageSourceSha
? { ...parsed, packageSourceSha: packageSourceSha.toLowerCase() }
: { ...parsed, packageSourceSha: "" };
}
return parsed;
}
@@ -1137,6 +1137,51 @@ describe("resolve-openclaw-package-candidate", () => {
});
});
it("normalizes artifact package source SHAs before workflow output", async () => {
const dir = await mkdtemp(path.join(tmpdir(), "openclaw-package-candidate-sha-"));
tempDirs.push(dir);
await writeFile(
path.join(dir, "package-candidate.json"),
JSON.stringify({
packageSourceSha: "66CE632B9B7C5C7FDD3E66C739687D51638AD6E2",
}),
);
await expect(readArtifactPackageCandidateMetadata(dir)).resolves.toEqual({
packageSourceSha: "66ce632b9b7c5c7fdd3e66c739687d51638ad6e2",
});
});
it("normalizes whitespace-only artifact package source SHAs to absent", async () => {
const dir = await mkdtemp(path.join(tmpdir(), "openclaw-package-candidate-empty-sha-"));
tempDirs.push(dir);
await writeFile(
path.join(dir, "package-candidate.json"),
JSON.stringify({
packageSourceSha: " \r\n ",
}),
);
await expect(readArtifactPackageCandidateMetadata(dir)).resolves.toEqual({
packageSourceSha: "",
});
});
it("rejects malformed artifact package source SHAs", async () => {
const dir = await mkdtemp(path.join(tmpdir(), "openclaw-package-candidate-bad-sha-"));
tempDirs.push(dir);
await writeFile(
path.join(dir, "package-candidate.json"),
JSON.stringify({
packageSourceSha: "66ce632b9b7c5c7fdd3e66c739687d51638ad6e2\r\nsource=main",
}),
);
await expect(readArtifactPackageCandidateMetadata(dir)).rejects.toThrow(
"artifact package-candidate.json packageSourceSha must be a 40-character commit SHA",
);
});
it("accepts uppercase package artifact SHA-256 metadata", async () => {
const dir = await mkdtemp(path.join(tmpdir(), "openclaw-package-sha-"));
tempDirs.push(dir);