From 7624186db2a746d33a1ea6f18b602d88605f341b Mon Sep 17 00:00:00 2001 From: Tarun Vashishtha Date: Fri, 10 Apr 2026 20:38:50 +0000 Subject: [PATCH 1/3] packagekit: link Red Hat issue references in changelogs --- pkg/packagekit/mock-updates.js | 9 +++++++ pkg/packagekit/updates.jsx | 46 +++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/pkg/packagekit/mock-updates.js b/pkg/packagekit/mock-updates.js index 1937b21c99bc..c5800813c9f2 100644 --- a/pkg/packagekit/mock-updates.js +++ b/pkg/packagekit/mock-updates.js @@ -108,4 +108,13 @@ export function injectMockUpdates(updates) { severity: 6, description: "This is FUBAR", }; + + updates["tracker-links;1-1"] = { + name: "tracker-links", + version: "1-1", + bug_urls: [], + cve_urls: [], + severity: 4, + description: "Fixes rhbz#12345 and jira#67890 in one update.", + }; } diff --git a/pkg/packagekit/updates.jsx b/pkg/packagekit/updates.jsx index 898ff7c1fd89..5c554e96b57d 100644 --- a/pkg/packagekit/updates.jsx +++ b/pkg/packagekit/updates.jsx @@ -133,6 +133,49 @@ function cleanupChangelogLine(text) { return text.trim(); } +function isRedHatBasedDistribution() { + const os_release = cockpit.info?.os_release; + if (!os_release) + return false; + + const ids = [os_release.ID, ...(os_release.ID_LIKE || "").split(" ")].filter(Boolean); + return ids.some(id => ["rhel", "fedora", "centos"].includes(id)); +} + +function renderChangelogWithIssueLinks(text) { + if (!text || !isRedHatBasedDistribution()) + return text; + + const issuePattern = /(rhbz|jira)#(\d+)/g; + const result = []; + let lastIndex = 0; + let match; + + while ((match = issuePattern.exec(text)) !== null) { + if (match.index > lastIndex) + result.push(text.slice(lastIndex, match.index)); + + const [, tracker, issueId] = match; + const href = tracker === "rhbz" + ? `https://bugzilla.redhat.com/show_bug.cgi?id=${issueId}` + : `https://issues.redhat.com/browse/${issueId}`; + result.push( + + {match[0]} + + ); + lastIndex = issuePattern.lastIndex; + } + + if (lastIndex === 0) + return text; + + if (lastIndex < text.length) + result.push(text.slice(lastIndex)); + + return result; +} + // Replace cockpit-wsinstance-https@[long_id] with a shorter string function shortenCockpitWsInstance(list) { return list.map(item => item.startsWith('cockpit-wsinstance-https') ? 'cockpit-wsinstance-https@.' : item); @@ -323,7 +366,8 @@ function updateItem(remarkable, info, pkgNames, key) { descriptionFirstLine = ; description =
; } else { - description =
{info.description}
; + descriptionFirstLine = renderChangelogWithIssueLinks(descriptionFirstLine); + description =
{renderChangelogWithIssueLinks(info.description)}
; } const expandedContent = ( From 85fb439115e7924287706d1a06f9f12c7d6e0304 Mon Sep 17 00:00:00 2001 From: Freya Gustavsson Date: Tue, 14 Apr 2026 16:11:20 +0200 Subject: [PATCH 2/3] packagekit: Update mock to new package syntax At some point we change to an object with keys to a list with all the objects in it and looking at ID instead. To make it work during manual testing we need to update the syntax from object to array. Signed-off-by: Freya Gustavsson --- pkg/packagekit/mock-updates.js | 50 ++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/pkg/packagekit/mock-updates.js b/pkg/packagekit/mock-updates.js index c5800813c9f2..98cc0be6f584 100644 --- a/pkg/packagekit/mock-updates.js +++ b/pkg/packagekit/mock-updates.js @@ -13,7 +13,8 @@ export function injectMockUpdates(updates) { // some security updates - updates["security-crit;2.3-4"] = { + updates.push({ + id: "security-crit;2.3-4", name: "security-crit", version: "2.3-4", bug_urls: [], @@ -22,8 +23,9 @@ export function injectMockUpdates(updates) { "https://access.redhat.example.com/errata/RHSA-2000:0001", "https://access.redhat.example.com/errata/RHSA-2000:0002"], severity: 8, description: "This will wreck your data center!", - }; - updates["security-low;1-2+sec1"] = { + }); + updates.push({ + id: "security-low;1-2+sec1", name: "security-low", version: "1-2+sec1", bug_urls: [], @@ -32,8 +34,9 @@ export function injectMockUpdates(updates) { "https://access.redhat.com/security/updates/classification/#low", "low"], severity: 8, description: "Mostly Harmless", - }; - updates["security-imp;5-2"] = { + }); + updates.push({ + id: "security-imp;5-2", name: "security-imp", version: "5-2", bug_urls: [], @@ -41,29 +44,32 @@ export function injectMockUpdates(updates) { "https://access.redhat.com/security/updates/classification/#important", "important"], severity: 8, description: "This update will make you sleep more peacefully.", - }; - updates["security-mod;12.3-4"] = { + }); + updates.push({ + id: "security-mod;12.3-4", name: "security-mod", version: "12.3-4", bug_urls: [], vendor_urls: ["https://access.redhat.com/security/updates/classification/#moderate", "moderate"], severity: 8, description: "This update will make you sleep more peacefully.", - }; + }); // no vendor URLs, default severity - updates["security-default;42"] = { + updates.push({ + id: "security-default;42", name: "security-default", version: "42", cve_urls: ["https://cve.example.com?name=CVE-2014-54321"], vendor_urls: [], severity: 8, description: "Yet another weakness fixed.", - }; + }); // source with many binaries for (let i = 1; i < 50; ++i) { const name = `manypkgs${i}`; - updates[name + ";1-1"] = { + updates.push({ + id: name + ";1-1", name, version: "1-1", bug_urls: [], @@ -71,11 +77,12 @@ export function injectMockUpdates(updates) { severity: 4, description: "Make [everything](http://everything.example.com) *better*\n\n * more packages\n * more `bugs`\n * more fun!", markdown: true, - }; + }); } // long changelog - updates["verbose;1-1"] = { + updates.push({ + id: "verbose;1-1", name: "verbose", version: "1-1", bug_urls: [], @@ -83,9 +90,10 @@ export function injectMockUpdates(updates) { severity: 6, description: ("Some longish explanation of some boring technical change. " + "This is total technobabble gibberish for layman users.\n\n").repeat(30) - }; + }); - updates["verbose-md;1-1"] = { + updates.push({ + id: "verbose-md;1-1", name: "verbose-md", version: "1-1", bug_urls: [], @@ -94,27 +102,29 @@ export function injectMockUpdates(updates) { description: ("Some longish explanation of some *boring* technical change. " + "This is total technobabble gibberish for layman users.\n\n").repeat(30), markdown: true, - }; + }); // many bug fixes const bugs = []; for (let i = 10000; i < 10025; ++i) bugs.push("http://bugzilla.example.com/" + i); - updates["buggy;1-1"] = { + updates.push({ + id: "buggy;1-1", name: "buggy", version: "1-1", bug_urls: bugs, cve_urls: [], severity: 6, description: "This is FUBAR", - }; + }); - updates["tracker-links;1-1"] = { + updates.push({ + id: "tracker-links;1-1", name: "tracker-links", version: "1-1", bug_urls: [], cve_urls: [], severity: 4, description: "Fixes rhbz#12345 and jira#67890 in one update.", - }; + }); } From 9f5745483b00760afd85c5a35e748dfb28cea9d8 Mon Sep 17 00:00:00 2001 From: Tarun Vashishtha Date: Sun, 26 Apr 2026 19:10:03 +0000 Subject: [PATCH 3/3] packagekit: refine changelog issue links --- pkg/packagekit/mock-updates.js | 2 +- pkg/packagekit/updates.jsx | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/pkg/packagekit/mock-updates.js b/pkg/packagekit/mock-updates.js index 98cc0be6f584..fbdf1d680c7a 100644 --- a/pkg/packagekit/mock-updates.js +++ b/pkg/packagekit/mock-updates.js @@ -125,6 +125,6 @@ export function injectMockUpdates(updates) { bug_urls: [], cve_urls: [], severity: 4, - description: "Fixes rhbz#12345 and jira#67890 in one update.", + description: "Fixes rhbz#12345 and RHEL-67890 in one update.", }); } diff --git a/pkg/packagekit/updates.jsx b/pkg/packagekit/updates.jsx index 5c554e96b57d..086fe59016b3 100644 --- a/pkg/packagekit/updates.jsx +++ b/pkg/packagekit/updates.jsx @@ -143,24 +143,37 @@ function isRedHatBasedDistribution() { } function renderChangelogWithIssueLinks(text) { - if (!text || !isRedHatBasedDistribution()) + if (!text) return text; - const issuePattern = /(rhbz|jira)#(\d+)/g; + const issuePattern = /\brhbz#(\d+)(?!\w)|\bRHEL-(\d+)(?![-\w])/g; const result = []; let lastIndex = 0; let match; + const redHatBased = isRedHatBasedDistribution(); while ((match = issuePattern.exec(text)) !== null) { if (match.index > lastIndex) result.push(text.slice(lastIndex, match.index)); - const [, tracker, issueId] = match; - const href = tracker === "rhbz" - ? `https://bugzilla.redhat.com/show_bug.cgi?id=${issueId}` - : `https://issues.redhat.com/browse/${issueId}`; + const [, bugzillaId, rhelId] = match; + let href = null; + let key = null; + + if (bugzillaId) { + href = `https://bugzilla.redhat.com/show_bug.cgi?id=${bugzillaId}`; + key = `rhbz-${bugzillaId}-${match.index}`; + } else if (rhelId && redHatBased) { + href = `https://redhat.atlassian.net/browse/RHEL-${rhelId}`; + key = `RHEL-${rhelId}-${match.index}`; + } else { + result.push(match[0]); + lastIndex = issuePattern.lastIndex; + continue; + } + result.push( - + {match[0]} );