From ed41610c418dfb35a269e6723c7300f6a12bc4df Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Sat, 5 Sep 2026 20:01:58 +0100 Subject: [PATCH] fix(triage): keep upgrade source versions out of structured reports Issue #1913 reports an incomplete v6 running version but names its old v5 image in the upgrade title. Falling back to that title incorrectly starts old-version retest handling. Treat the structured version field as authoritative and stop at the next heading, requesting exact version information when incomplete. Cover the parser and mocked label/comment flows without changing public issue state. Change-source: pulse-maintainer --- .github/scripts/issue-version-triage.cjs | 14 ++++++++ .github/scripts/issue-version-triage.test.cjs | 32 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/.github/scripts/issue-version-triage.cjs b/.github/scripts/issue-version-triage.cjs index 5ffb84f5e..37e4d3da2 100644 --- a/.github/scripts/issue-version-triage.cjs +++ b/.github/scripts/issue-version-triage.cjs @@ -77,6 +77,20 @@ function normalizeVersion(value) { function extractPulseVersion(title, body) { if (body) { const lines = body.split(/\r?\n/); + const versionHeading = lines.findIndex((line) => + /^#{1,6}[ \t]+Pulse[ \t]+version[ \t]*$/i.test(line) + ); + if (versionHeading !== -1) { + // The explicit running-version field is authoritative, even when it is + // incomplete. A title may name the old image in an upgrade report, and + // neighbouring fields may contain an unrelated agent version. + const value = []; + for (let i = versionHeading + 1; i < lines.length; i += 1) { + if (/^#{1,6}[ \t]+/.test(lines[i])) break; + value.push(lines[i]); + } + return normalizeVersion(stripHTMLComments(value.join("\n"))); + } for (let i = 0; i < lines.length; i += 1) { const line = lines[i] || ""; if (/pulse\s*(\||-)?\s*version/i.test(line)) { diff --git a/.github/scripts/issue-version-triage.test.cjs b/.github/scripts/issue-version-triage.test.cjs index d86b8f094..bf12393f9 100644 --- a/.github/scripts/issue-version-triage.test.cjs +++ b/.github/scripts/issue-version-triage.test.cjs @@ -431,3 +431,35 @@ test("extractPulseVersion reads a capitalised version under its heading", () => "6.0.4" ); }); + +test("structured Pulse version never falls back to an upgrade source or agent version", () => { + const { extractPulseVersion } = triage.internals; + for (const version of ["6.4", "6", "_No response_", ""]) { + assert.equal(extractPulseVersion( + "[Bug]: upgrade from rcourtman/pulse:v5.1.35 to rcourtman/pulse:6 failed", + `### Pulse version\n\n${version}\n\n### Agent version\n5.1.30\n`, + ), null); + } + assert.equal(extractPulseVersion("upgrade from v5.1.35", "### Pulse version\r\n\r\nV6.4.1\r\n\r\n### Agent version\r\n5.1.30"), "6.4.1"); + assert.equal(extractPulseVersion("bug on v6.4.1", "legacy free-form report"), "6.4.1"); + assert.equal(extractPulseVersion("bug on v5.1.35", "### Pulse version"), null); +}); + +test("ambiguous upgrade version requests information without a retest comment", async () => { + const { github, calls } = createGithub({ latestVersion: "6.4.1" }); + const issue = { + number: 1913, + title: "[Bug]: upgrade from rcourtman/pulse:v5.1.35 to rcourtman/pulse:6 failed", + body: "### Pulse version\n\n6.4\n\n### Agent version\nnone\n", + labels: [{ name: "bug" }], + author_association: "NONE", + }; + const args = { github, context: createContext({ issue }), core: createCore() }; + await triage.syncLabels(args); + await triage.postRetestComment(args); + const labels = calls.setLabels.at(-1).labels; + assert.ok(labels.includes("needs-version-info")); + assert.ok(!labels.includes("affects-5.1.35")); + assert.ok(!labels.includes("needs-retest-on-latest")); + assert.equal(calls.createComment.length, 0); +});