mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 07:21:36 +00:00
fix(release): prevent stale beta validation evidence (#103798)
* fix(release): ignore nested squash revert markers * fix(release): preserve squash revert targets * docs(release): state installer doctor contract * fix(release): recognize conventional squash reverts
This commit is contained in:
committed by
GitHub
parent
fc2afc83da
commit
e43f225c81
@@ -317,13 +317,27 @@ function closingReferencesIn(text) {
|
||||
return references;
|
||||
}
|
||||
|
||||
function standardRevertedHash(message) {
|
||||
return message
|
||||
export function standardRevertedHash(message) {
|
||||
const paragraphs = message
|
||||
.trim()
|
||||
.split(/\n\s*\n/)
|
||||
.map((paragraph) => paragraph.trim())
|
||||
.map((paragraph) => paragraph.match(/^This reverts commit ([0-9a-f]{7,40})\.$/i)?.[1])
|
||||
.find(Boolean);
|
||||
.map((paragraph) => paragraph.trim());
|
||||
const messageIsRevert = /^(?:[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s*)?revert\b/i.test(
|
||||
paragraphs[0] ?? "",
|
||||
);
|
||||
for (const [index, paragraph] of paragraphs.entries()) {
|
||||
const revertedHash = paragraph.match(/^This reverts commit ([0-9a-f]{7,40})\.$/i)?.[1];
|
||||
if (!revertedHash) {
|
||||
continue;
|
||||
}
|
||||
// GitHub squash messages can embed a reverted intermediate commit. Its
|
||||
// marker follows the corresponding bullet and does not revert the squash.
|
||||
if (!messageIsRevert && /^\*\s+Revert\b/i.test(paragraphs[index - 1] ?? "")) {
|
||||
continue;
|
||||
}
|
||||
return revertedHash;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function handlesIn(text) {
|
||||
|
||||
@@ -482,6 +482,8 @@ if (typeof updateStep.command !== "string" || !updateStep.command.includes(expec
|
||||
throw new Error(`global update step missing expected tgz URL: ${JSON.stringify(updateStep)}`);
|
||||
}
|
||||
const doctorStep = steps.find((step) => step?.name === "openclaw doctor");
|
||||
// Every baseline that passes verify_installed_cli implements this contract;
|
||||
// the sole earlier npm artifact has no CLI and cannot reach this parser.
|
||||
if (!doctorStep) {
|
||||
throw new Error("missing openclaw doctor step in update JSON");
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
cumulativeShippedPullRequests,
|
||||
highlightCountError,
|
||||
releaseNoteReferences,
|
||||
standardRevertedHash,
|
||||
subtractShippedPullRequests,
|
||||
withoutExcludedContributionRecords,
|
||||
} from "../../.agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs";
|
||||
@@ -32,6 +33,54 @@ function git(cwd: string, args: string[]): string {
|
||||
}
|
||||
|
||||
describe("release-note verification", () => {
|
||||
it("ignores nested revert markers in squash-merge bodies", () => {
|
||||
const nestedRevert = [
|
||||
"feat(android): render display math (#101435)",
|
||||
"",
|
||||
"* feat(android): render display math",
|
||||
"",
|
||||
' * Revert "docs(changelog): note display math"',
|
||||
"",
|
||||
`This reverts commit ${"a".repeat(40)}.`,
|
||||
].join("\n");
|
||||
const topLevelRevert = [
|
||||
'Revert "fix(qa): keep smoke profile on one channel (#101173)" (#101184)',
|
||||
"",
|
||||
`This reverts commit ${"b".repeat(40)}.`,
|
||||
].join("\n");
|
||||
const squashRevert = [
|
||||
"Revert chat session picker inline search (#85527)",
|
||||
"",
|
||||
'* Revert "fix(ui): keep chat session search inline (#85490)"',
|
||||
"",
|
||||
`This reverts commit ${"c".repeat(40)}.`,
|
||||
"",
|
||||
"* fix(ui): clear applied chat picker search on empty input",
|
||||
].join("\n");
|
||||
const conventionalSquashRevert = [
|
||||
"chore: revert dependency guard backfill machinery (#87867)",
|
||||
"",
|
||||
'* Revert "ci: isolate dependency guard backfill label (#87882)"',
|
||||
"",
|
||||
`This reverts commit ${"d".repeat(40)}.`,
|
||||
"",
|
||||
"* ci: preserve clawsweeper bot label filter",
|
||||
].join("\n");
|
||||
const explainedTopLevelRevert = [
|
||||
"revert: restore a provider default",
|
||||
"",
|
||||
"The replacement broke non-native endpoints.",
|
||||
"",
|
||||
`This reverts commit ${"e".repeat(40)}.`,
|
||||
].join("\n");
|
||||
|
||||
expect(standardRevertedHash(nestedRevert)).toBeUndefined();
|
||||
expect(standardRevertedHash(topLevelRevert)).toBe("b".repeat(40));
|
||||
expect(standardRevertedHash(squashRevert)).toBe("c".repeat(40));
|
||||
expect(standardRevertedHash(conventionalSquashRevert)).toBe("d".repeat(40));
|
||||
expect(standardRevertedHash(explainedTopLevelRevert)).toBe("e".repeat(40));
|
||||
});
|
||||
|
||||
it("counts only top-level Highlights bullets and enforces the 5-8 policy input", () => {
|
||||
const highlights = [
|
||||
"### Highlights",
|
||||
|
||||
Reference in New Issue
Block a user