mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-14 15:56:10 +00:00
Codex review + test findings on the pipeline convergence: - candidate changelog provenance now validates the same section the renderer publishes (correction tags may carry their own heading) via a shared correctionVersionForTag helper - guard_existing_public_release accepts a canonical proofless body with intact dependency evidence, matching the renderer's documented proof-omitted-at-limit state; retries re-append the proof - ledgerFor regains main's noteReferences threading so prose-cited PRs keep their contribution-record rows, and the ledger/verify tests pin the merged entry shape (externalReferences) and highlight gate
222 lines
5.8 KiB
TypeScript
222 lines
5.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
contributionRecordFor,
|
|
ledgerChecks,
|
|
ledgerFor,
|
|
renderContributionRecordEntry,
|
|
} from "../../.agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs";
|
|
|
|
describe("renderContributionRecordEntry", () => {
|
|
it("keeps source and linked issue references without repeating PR titles", () => {
|
|
expect(
|
|
renderContributionRecordEntry({
|
|
number: 123,
|
|
title: "Fix local openclaw/openclaw#45 and openclaw/imsg#141",
|
|
linkedIssues: [{ number: 45 }, { number: 67 }],
|
|
thanks: ["alice", "bob"],
|
|
}),
|
|
).toBe("- **PR #123** Related #45, openclaw/imsg#141, #67. Thanks @alice and @bob.");
|
|
});
|
|
|
|
it("deduplicates title references and retains seeded cross-repository references", () => {
|
|
expect(
|
|
renderContributionRecordEntry({
|
|
number: 124,
|
|
title: "Fix #45, #45, and OpenClaw/imsg#141",
|
|
externalReferences: ["openclaw/imsg#141"],
|
|
priorReferences: [67],
|
|
linkedIssues: [{ number: 45 }],
|
|
thanks: [],
|
|
}),
|
|
).toBe("- **PR #124** Related #45, OpenClaw/imsg#141, #67.");
|
|
});
|
|
|
|
it("renders every source PR even without issue references or credits", () => {
|
|
expect(
|
|
renderContributionRecordEntry({
|
|
number: 456,
|
|
title: "Internal cleanup",
|
|
linkedIssues: [],
|
|
thanks: [],
|
|
}),
|
|
).toBe("- **PR #456**");
|
|
});
|
|
|
|
it("retains references and credits when a compact record is seeded again", () => {
|
|
const line = "- **PR #125** Related #45, openclaw/imsg#141. Thanks @alice and @bob.";
|
|
const record = contributionRecordFor({
|
|
source: [
|
|
"## 2026.7.1",
|
|
"",
|
|
"### Complete contribution record",
|
|
"",
|
|
"#### Pull requests",
|
|
"",
|
|
line,
|
|
].join("\n"),
|
|
});
|
|
const seeded = record.pullRequests.get(125);
|
|
|
|
expect(seeded).toEqual({
|
|
externalReferences: ["openclaw/imsg#141"],
|
|
references: [45],
|
|
thanks: ["alice", "bob"],
|
|
});
|
|
expect(
|
|
renderContributionRecordEntry({
|
|
number: 125,
|
|
title: "Title changed after release",
|
|
priorReferences: seeded?.references,
|
|
externalReferences: seeded?.externalReferences,
|
|
linkedIssues: [],
|
|
thanks: seeded?.thanks ?? [],
|
|
}),
|
|
).toBe(line);
|
|
});
|
|
|
|
it("retains seeded credits when the production ledger is rebuilt", () => {
|
|
const priorRecord = contributionRecordFor({
|
|
source: [
|
|
"## 2026.7.1",
|
|
"",
|
|
"### Complete contribution record",
|
|
"",
|
|
"#### Pull requests",
|
|
"",
|
|
"- **PR #125** Thanks @alice and @bob.",
|
|
].join("\n"),
|
|
});
|
|
const nodes = new Map([
|
|
[
|
|
125,
|
|
{
|
|
__typename: "PullRequest",
|
|
author: { __typename: "User", login: "carol" },
|
|
closingIssuesReferences: { nodes: [] },
|
|
mergedAt: "2026-07-08T00:00:00Z",
|
|
title: "fix: keep release credits",
|
|
},
|
|
],
|
|
]);
|
|
|
|
const result = ledgerFor(
|
|
"v2026.6.11",
|
|
"HEAD",
|
|
[125],
|
|
nodes,
|
|
new Map(),
|
|
new Map(),
|
|
{ issuesByPullRequest: new Map() },
|
|
priorRecord,
|
|
new Set([125]),
|
|
new Set(),
|
|
new Set(),
|
|
new Set(),
|
|
new Set(),
|
|
[],
|
|
Date.parse("2026-07-09T00:00:00Z"),
|
|
);
|
|
|
|
expect(result.ledger).toContain("- **PR #125** Thanks @carol and @alice and @bob.");
|
|
});
|
|
|
|
it("retains references from a verbose record when the source title changes", () => {
|
|
const record = contributionRecordFor({
|
|
source: [
|
|
"## 2026.7.1",
|
|
"",
|
|
"### Complete contribution record",
|
|
"",
|
|
"#### Pull requests",
|
|
"",
|
|
"- **PR #126** Fix #46 and openclaw/imsg#142. Related #68. Thanks @alice.",
|
|
].join("\n"),
|
|
});
|
|
const seeded = record.pullRequests.get(126);
|
|
|
|
expect(seeded).toEqual({
|
|
externalReferences: ["openclaw/imsg#142"],
|
|
references: [46, 68],
|
|
thanks: ["alice"],
|
|
});
|
|
});
|
|
|
|
it("requires complete reference tokens rather than matching substrings", () => {
|
|
const source = [
|
|
"## 2026.7.1",
|
|
"",
|
|
"### Highlights",
|
|
"",
|
|
"- Highlight one.",
|
|
"- Highlight two.",
|
|
"- Highlight three.",
|
|
"- Highlight four.",
|
|
"- Highlight five.",
|
|
"",
|
|
"### Changes",
|
|
"",
|
|
"### Fixes",
|
|
"",
|
|
"### Complete contribution record",
|
|
"",
|
|
"#### Pull requests",
|
|
"",
|
|
"- **PR #456** Related openclaw/imsg#141.",
|
|
].join("\n");
|
|
const entry = {
|
|
number: 456,
|
|
title: "Internal cleanup",
|
|
editorialEligible: false,
|
|
priorReferences: [45, 141],
|
|
externalReferences: [],
|
|
linkedIssues: [],
|
|
thanks: [],
|
|
};
|
|
|
|
expect(
|
|
ledgerChecks({ source }, [entry], new Map([[456, { __typename: "PullRequest" }]]), []),
|
|
).toEqual([
|
|
"missing #45 on contribution record for PR #456",
|
|
"missing #141 on contribution record for PR #456",
|
|
]);
|
|
});
|
|
|
|
it("accepts case-only differences in cross-repository references", () => {
|
|
const line = "- **PR #127** Related OpenClaw/imsg#143.";
|
|
const source = [
|
|
"## 2026.7.1",
|
|
"",
|
|
"### Highlights",
|
|
"",
|
|
"- Highlight one.",
|
|
"- Highlight two.",
|
|
"- Highlight three.",
|
|
"- Highlight four.",
|
|
"- Highlight five.",
|
|
"",
|
|
"### Changes",
|
|
"",
|
|
"### Fixes",
|
|
"",
|
|
"### Complete contribution record",
|
|
"",
|
|
"#### Pull requests",
|
|
"",
|
|
line,
|
|
].join("\n");
|
|
const entry = {
|
|
number: 127,
|
|
title: "Internal cleanup",
|
|
editorialEligible: false,
|
|
priorReferences: [],
|
|
externalReferences: ["openclaw/imsg#143"],
|
|
linkedIssues: [],
|
|
thanks: [],
|
|
};
|
|
|
|
expect(
|
|
ledgerChecks({ source }, [entry], new Map([[127, { __typename: "PullRequest" }]]), []),
|
|
).toEqual([]);
|
|
});
|
|
});
|