mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-17 14:31:38 +00:00
fix(release): reuse SHA-pinned root evidence
This commit is contained in:
@@ -218,22 +218,33 @@ for ((index = 0; index < run_count; index += 1)); do
|
||||
and (.root.targetSha | type == "string" and test("^[0-9a-f]{40}$"))
|
||||
and (.root.artifact.digest | type == "string" and test("^sha256:[0-9a-f]{64}$"))
|
||||
and all($record.current, $record.root;
|
||||
.producerOnTrustedMainLineage == true
|
||||
and .workflowFullRef == "refs/heads/main"
|
||||
. as $parent
|
||||
| .producerOnTrustedMainLineage == true
|
||||
and .workflowRefType == "branch"
|
||||
and .workflowPath == ".github/workflows/full-release-validation.yml"
|
||||
and .workflowFullRef == ("refs/heads/" + .workflowRef)
|
||||
and .workflowQualifiedPath ==
|
||||
".github/workflows/full-release-validation.yml@refs/heads/main"
|
||||
(".github/workflows/full-release-validation.yml@" + .workflowFullRef)
|
||||
and (
|
||||
.workflowRunPath == ".github/workflows/full-release-validation.yml"
|
||||
or .workflowRunPath ==
|
||||
".github/workflows/full-release-validation.yml@refs/heads/main"
|
||||
or .workflowRunPath == .workflowQualifiedPath
|
||||
)
|
||||
and (
|
||||
(.manifestVersion == 3 and .workflowRefProof == "manifest-v3-branch")
|
||||
(
|
||||
.workflowRef == "main"
|
||||
and (
|
||||
(.manifestVersion == 3 and .workflowRefProof == "manifest-v3-branch")
|
||||
or (
|
||||
.manifestVersion == 2
|
||||
and .workflowRefProof == "legacy-v2-main-ancestry"
|
||||
)
|
||||
)
|
||||
)
|
||||
or (
|
||||
.manifestVersion == 2
|
||||
and .workflowRefProof == "legacy-v2-main-ancestry"
|
||||
.manifestVersion == 3
|
||||
and .workflowRefProof == "manifest-v3-sha-pinned-main-ancestry"
|
||||
and (.workflowRef | test("^release-ci/[0-9a-f]{12}-[1-9][0-9]*$"))
|
||||
and (.workflowRef | startswith("release-ci/\($parent.workflowSha[0:12])-"))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -178,17 +178,24 @@ function normalizedEvidence(options: {
|
||||
targetSha: string;
|
||||
validationInputs?: Record<string, string> | null;
|
||||
verifierSha?: string | null;
|
||||
workflowRef?: string;
|
||||
}): NormalizedEvidence {
|
||||
const runId = options.runId ?? "111";
|
||||
const producerSha = options.producerSha ?? PRODUCER_SHA;
|
||||
const releaseProfile = options.releaseProfile ?? "full";
|
||||
const soak = options.soak ?? true;
|
||||
const workflowRef = options.workflowRef ?? "main";
|
||||
const workflowFullRef = `refs/heads/${workflowRef}`;
|
||||
const shaPinned = workflowRef.startsWith("release-ci/");
|
||||
const validationInputs =
|
||||
options.validationInputs === undefined ? DEFAULT_INPUTS : options.validationInputs;
|
||||
const manifest = {
|
||||
version: 2,
|
||||
version: shaPinned ? 3 : 2,
|
||||
workflowName: "Full Release Validation",
|
||||
workflowRef: "main",
|
||||
workflowRef,
|
||||
workflowSha: producerSha,
|
||||
workflowFullRef,
|
||||
workflowRefType: "branch",
|
||||
runId,
|
||||
runAttempt: "2",
|
||||
targetRef: "release/2026.7.1",
|
||||
@@ -224,20 +231,24 @@ function normalizedEvidence(options: {
|
||||
},
|
||||
conclusion: "success",
|
||||
manifest,
|
||||
manifestVersion: 2,
|
||||
manifestVersion: shaPinned ? 3 : 2,
|
||||
runAttempt: 2,
|
||||
runId,
|
||||
status: "completed",
|
||||
targetSha: options.targetSha,
|
||||
url: `https://example.test/runs/${runId}`,
|
||||
producerOnTrustedMainLineage: true,
|
||||
workflowFullRef: "refs/heads/main",
|
||||
workflowFullRef,
|
||||
workflowPath: ".github/workflows/full-release-validation.yml",
|
||||
workflowQualifiedPath: ".github/workflows/full-release-validation.yml@refs/heads/main",
|
||||
workflowRef: "main",
|
||||
workflowRefProof: "legacy-v2-main-ancestry",
|
||||
workflowQualifiedPath: `.github/workflows/full-release-validation.yml@${workflowFullRef}`,
|
||||
workflowRef,
|
||||
workflowRefProof: shaPinned
|
||||
? "manifest-v3-sha-pinned-main-ancestry"
|
||||
: "legacy-v2-main-ancestry",
|
||||
workflowRefType: "branch",
|
||||
workflowRunPath: ".github/workflows/full-release-validation.yml",
|
||||
workflowRunPath: shaPinned
|
||||
? `.github/workflows/full-release-validation.yml@${workflowFullRef}`
|
||||
: ".github/workflows/full-release-validation.yml",
|
||||
workflowSha: producerSha,
|
||||
};
|
||||
const roles = [
|
||||
@@ -268,7 +279,7 @@ function normalizedEvidence(options: {
|
||||
dispatchNonce: `full-release-validation-${runId}-${sourceParentAttempt}${suffix}`,
|
||||
displayTitle: `${name} full-release-validation-${runId}-${sourceParentAttempt}${suffix}`,
|
||||
event: "workflow_dispatch",
|
||||
headBranch: "main",
|
||||
headBranch: workflowRef,
|
||||
parentJobId: `job-${role}`,
|
||||
path: `.github/workflows/${workflow}`,
|
||||
role,
|
||||
@@ -471,6 +482,34 @@ function parseOutput(output: string): Record<string, string> {
|
||||
}
|
||||
|
||||
describe("scripts/github/find-reusable-release-validation.sh", () => {
|
||||
it("reuses strict direct-root evidence produced by a canonical SHA-pinned run", () => {
|
||||
const { origin, priorSha } = createRepo();
|
||||
const clone = cloneHead(origin);
|
||||
const producerSha = "d".repeat(40);
|
||||
const producerRef = `release-ci/${producerSha.slice(0, 12)}-122`;
|
||||
const record = normalizedEvidence({
|
||||
producerSha,
|
||||
targetSha: priorSha,
|
||||
workflowRef: producerRef,
|
||||
});
|
||||
const { binDir, fixtures, validatorPath } = setUpFixtures([{ record, runId: "111" }]);
|
||||
|
||||
const result = runResolver({
|
||||
binDir,
|
||||
fixtures,
|
||||
repoDir: clone,
|
||||
targetSha: priorSha,
|
||||
validatorPath,
|
||||
workflowRef: `release-ci/${VERIFIER_SHA.slice(0, 12)}-123`,
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(parseOutput(result.stdout)).toMatchObject({
|
||||
evidence_run_id: "111",
|
||||
reuse: "true",
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects noncanonical release refs and workflow SHAs outside trusted main", () => {
|
||||
const { origin, priorSha } = createRepo();
|
||||
const clone = cloneHead(origin);
|
||||
|
||||
Reference in New Issue
Block a user