mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-25 21:20:00 +00:00
Recognise declared Pro server artifacts during issue intake (#3219)
The published native Pro archive and paid registry image currently become missing-version reports, unlike the Community server artifact. Accept those server naming shapes without mining unknown fields, link destinations, signatures or companion binaries. Exercise the actual silent label consumer and preserve Community-owned state and the live-read fence. Contract-Neutral: Silent issue version classification and registered regression controls only; no Pulse runtime, rendered product surface, subsystem contract, dependency, access or public-contact change. --- Fleet candidate `20261024T201018Z-product-intelligence` from the `product-intelligence` lane. Reviewed tip `18d7e0d2d74ba1b5f1325d11584bd5095a48fa2e` on `main`. Lands together with: pulse-pro https://github.com/rcourtman/pulse-pro/pull/529. [How Pulse handles triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
This commit is contained in:
@@ -165,12 +165,12 @@ function normalizeLegacyVersionValue(value) {
|
||||
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
|
||||
// the attempted server executable's version.
|
||||
// Community and Pro server archive names; companion binaries and signatures
|
||||
// cannot establish the attempted server executable's version.
|
||||
const filename = visible.match(/^pulse-[^\s`*_]+/i)?.[0];
|
||||
if (filename && /\.(?:tar\.gz|tgz|zip|exe|sha256|sig|sshsig)(?:\.|$)/i.test(filename)) {
|
||||
const archive = filename.match(
|
||||
/^pulse-v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\.(?:tar\.gz|tgz)$/i
|
||||
/^pulse-(?:pro-)?v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\.(?:tar\.gz|tgz)$/i
|
||||
);
|
||||
return archive ? normalizeVersion(archive[1].replace(
|
||||
/-linux-(?:386|amd64|arm64|armv6|armv7)$/i, ""
|
||||
@@ -178,7 +178,7 @@ function normalizeLegacyVersionValue(value) {
|
||||
}
|
||||
// Keep an explicitly shared server/agent version (as in #1788), without
|
||||
// mining a sentence such as "unknown; agent version 6.5.0" for a number.
|
||||
return /^(?:v?\d+\.\d+\.\d+\b|(?:pulse|server(?:[ \t]*\+[ \t]*pulse-agent)?)[ \t]+v?\d+\.\d+\.\d+\b|(?:[a-z0-9._/-]+\/)?pulse:|pulse[-_])/i.test(visible)
|
||||
return /^(?:v?\d+\.\d+\.\d+\b|(?:pulse|server(?:[ \t]*\+[ \t]*pulse-agent)?)[ \t]+v?\d+\.\d+\.\d+\b|(?:[a-z0-9._/-]+\/)?pulse(?:-pro)?:|pulse[-_])/i.test(visible)
|
||||
? normalizeVersion(visible) : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1821,6 +1821,60 @@ test("non-server artifacts cannot supply an attempted server version", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("Pro server artifacts retain their declared version without borrowing agent evidence", () => {
|
||||
const { extractPulseVersion } = triage.internals;
|
||||
for (const version of ["6.5.0", "6.6.0-beta.3", "6.6.0-rc.6"]) {
|
||||
for (const artifact of [
|
||||
`pulse-pro-v${version}-linux-amd64.tar.gz`,
|
||||
`pulse-pro-v${version}-linux-arm64.tar.gz`,
|
||||
`license.pulserelay.pro/pulse-pro:${version}`,
|
||||
]) {
|
||||
for (const value of [artifact, `**\`${artifact}\`**`, `[${artifact}](https://example.invalid/6.4.5)`]) {
|
||||
for (const field of ["### Pulse version\n", "Pulse version: ", "- **Pulse version**: "]) {
|
||||
for (const newline of ["\n", "\r\n"]) {
|
||||
const body = `${field}${value}\n\n### Agent version\n6.4.5`.replaceAll("\n", newline);
|
||||
assert.equal(extractPulseVersion("Upgrade from v6.4.5", body), version, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const value of [
|
||||
"pulse-pro-agent-v6.6.0-rc.6-linux-amd64.tar.gz",
|
||||
"pulse-pro-v6.6.0-rc.6-linux-amd64.tar.gz.sshsig",
|
||||
"pulse-pro-v6.6.0-rc.6-linux-amd64.tar.gz.sha256",
|
||||
"pulse-pro-v6.6.0-rc.6-linux-amd64.tar.gz.sig",
|
||||
"unknown; downloaded pulse-pro-v6.6.0-rc.6-linux-amd64.tar.gz",
|
||||
"[unknown](https://example.invalid/pulse-pro-v6.6.0-rc.6-linux-amd64.tar.gz)",
|
||||
]) {
|
||||
assert.equal(extractPulseVersion("Upgrade from v6.4.5",
|
||||
`### Pulse version\n${value}\n### Agent version\n6.4.5`), null, value);
|
||||
}
|
||||
});
|
||||
|
||||
for (const value of [
|
||||
"pulse-pro-v6.6.0-rc.6-linux-amd64.tar.gz",
|
||||
"pulse-pro-v6.6.0-rc.6-linux-arm64.tar.gz",
|
||||
"license.pulserelay.pro/pulse-pro:6.6.0-rc.6",
|
||||
]) {
|
||||
test(`Pro server intake updates only silent version metadata: ${value}`, async () => {
|
||||
const { github, calls } = createGithub();
|
||||
const issue = { number: 2923, title: "Failed install", labels: [
|
||||
"bug", "affects-6.4.5", "needs-version-info", "needs-human", "release-blocker",
|
||||
"needs-decomposition", "needs-retest-on-latest",
|
||||
].map(name => ({ name })),
|
||||
body: `### Pulse version\n${value}\n### Agent version\n6.4.5` };
|
||||
await syncLabels({ github, context: createContext({ issue }), core: createCore() });
|
||||
assert.deepEqual(calls.addLabels.map(call => call.labels), [["affects-6.6.0-rc.6"]]);
|
||||
assert.deepEqual(calls.removeLabel.map(call => call.name), ["affects-6.4.5", "needs-version-info"]);
|
||||
assert.deepEqual(calls.createLabel.map(call => call.name), ["affects-6.6.0-rc.6"]);
|
||||
assert.deepEqual(calls.createComment, []);
|
||||
assert.deepEqual(calls.getLatestRelease, []);
|
||||
assert.deepEqual(calls.paginate, []);
|
||||
assert.equal(calls.getIssue.length, 2);
|
||||
});
|
||||
}
|
||||
|
||||
test("archive recognition neither borrows a later filename nor shortens bare prereleases", () => {
|
||||
const { extractPulseVersion } = triage.internals;
|
||||
assert.equal(extractPulseVersion("Upgrade from v6.4.5",
|
||||
|
||||
Reference in New Issue
Block a user