mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-25 21:20:00 +00:00
Read declared issue versions from visible release-link text
A version supplied as a Markdown release link currently becomes needs-version-info even though its visible label states the version. Read only that label and ordinary inline formatting; never mine destinations, image text or literal Markdown for a version. Keep current-report checks, silent metadata deltas and Community labels unchanged. Contract-Neutral: Recognise visible inline version values within the existing issue metadata contract; no product runtime, API or label ownership changes. Change-source: pulse-maintainer
This commit is contained in:
@@ -139,8 +139,26 @@ function normalizeVersion(value) {
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
function inlineVersionText(tokens) {
|
||||
return (tokens || []).map((token) => {
|
||||
// A release link's label is evidence; its destination and title are not.
|
||||
// Unwrap only ordinary inline formatting, not images, struck-out values
|
||||
// or HTML. Code spans keep their literal text rather than parsing links
|
||||
// or comments inside them.
|
||||
if (["link", "strong", "em"].includes(token.type)) {
|
||||
return inlineVersionText(token.tokens);
|
||||
}
|
||||
if (["codespan", "escape"].includes(token.type)) return token.text;
|
||||
return token.raw || "";
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function normalizeLegacyVersionValue(value) {
|
||||
const visible = String(value).trim().replace(/^[`*_]+/, "");
|
||||
const raw = String(value).trim();
|
||||
const blocks = lexer(raw, { gfm: true });
|
||||
const text = blocks.length === 1 && blocks[0].type === "paragraph"
|
||||
? inlineVersionText(blocks[0].tokens) : raw;
|
||||
const visible = text.trim().replace(/^[`*_]+/, "");
|
||||
// Failed-install forms explicitly accept an attempted server archive. Its
|
||||
// packaging suffix is not part of the release version. Recognise only the
|
||||
// server archive names; companion binaries and signatures cannot establish
|
||||
|
||||
@@ -1774,3 +1774,60 @@ for (const [filename, version] of [
|
||||
assert.equal(calls.getIssue.length, 2);
|
||||
});
|
||||
}
|
||||
|
||||
test("declared versions use visible release-link text, including nested inline formatting", () => {
|
||||
const { extractPulseVersion } = triage.internals;
|
||||
for (const [value, expected] of [
|
||||
["[v6.5.0](https://github.com/rcourtman/Pulse/releases/tag/v6.4.5)", "6.5.0"],
|
||||
["**[6.5.0](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0)**", "6.5.0"],
|
||||
["_[`v6.5.0`](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0)_", "6.5.0"],
|
||||
["[6\\.5\\.0](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0)", "6.5.0"],
|
||||
["[pulse-v6.6.0-beta.3-linux-amd64.tar.gz](https://github.com/rcourtman/Pulse/releases/tag/v6.6.0-beta.3)", "6.6.0-beta.3"],
|
||||
]) {
|
||||
for (const body of [
|
||||
`### Pulse version\n${value}\n### Agent version\n6.4.5`,
|
||||
`Pulse version: ${value}`,
|
||||
`- **Pulse version**: ${value}`,
|
||||
]) {
|
||||
for (const newline of ["\n", "\r\n"]) {
|
||||
assert.equal(extractPulseVersion("Upgrade from v6.4.5", body.replaceAll("\n", newline)), expected, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("link targets, titles, images and literal Markdown cannot invent a declared version", () => {
|
||||
const { extractPulseVersion } = triage.internals;
|
||||
for (const value of [
|
||||
"[unknown](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0)",
|
||||
'[unknown](https://github.com/rcourtman/Pulse "6.5.0")',
|
||||
"",
|
||||
"~~[6.5.0](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0)~~",
|
||||
"`[6.5.0](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0)`",
|
||||
"<span>6.5.0</span>",
|
||||
"[release](https://github.com/rcourtman/Pulse/releases/tag/v6.5.0) 6.4.5",
|
||||
"[6.5.0](unterminated",
|
||||
]) {
|
||||
assert.equal(extractPulseVersion("Upgrade from v6.4.5",
|
||||
`### Pulse version\n${value}\n### Agent version\n6.5.0`), null, value);
|
||||
}
|
||||
});
|
||||
|
||||
test("the label consumer accepts a linked version without fetching links or contacting the reporter", async () => {
|
||||
for (const [visible, expected] of [["**`v6.5.0`**", "6.5.0"], ["unknown", null]]) {
|
||||
const { github, calls } = createGithub();
|
||||
const issue = { number: 2922, title: "[Bug]: Upgrade from v6.4.5",
|
||||
body: `### Pulse version\n[${visible}](https://github.com/rcourtman/Pulse/releases/tag/v6.6.0-rc.5)\n### Agent version\n6.4.5`,
|
||||
labels: ["bug", "affects-6.4.5", "needs-version-info", "needs-human", "release-blocker",
|
||||
"needs-decomposition", "needs-retest-on-latest"].map(name => ({ name })) };
|
||||
await syncLabels({ github, context: createContext({ issue }), core: createCore() });
|
||||
assert.deepEqual(calls.addLabels.map(call => call.labels), expected ? [["affects-6.5.0"]] : []);
|
||||
assert.deepEqual(calls.removeLabel.map(call => call.name), expected
|
||||
? ["affects-6.4.5", "needs-version-info"] : ["affects-6.4.5"]);
|
||||
assert.deepEqual(calls.createLabel.map(call => call.name), expected ? ["affects-6.5.0"] : ["needs-version-info"]);
|
||||
assert.deepEqual(calls.createComment, []);
|
||||
assert.deepEqual(calls.getLatestRelease, []);
|
||||
assert.deepEqual(calls.paginate, []);
|
||||
assert.equal(calls.getIssue.length, 2);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user