From 6d2c9c97bd36a850ac7641912833bdc14e7e79c8 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 1 Apr 2026 15:30:30 +0200 Subject: [PATCH 1/4] fix(git-node): fix handling of existing trailers --- lib/landing_session.js | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/lib/landing_session.js b/lib/landing_session.js index 424e5c97..6fb902c2 100644 --- a/lib/landing_session.js +++ b/lib/landing_session.js @@ -316,7 +316,7 @@ export default class LandingSession extends Session { const BACKPORT_RE = /^BACKPORT-PR-URL\s*:\s*(\S+)$/i; const PR_RE = /^PR-URL\s*:\s*(\S+)$/i; const REVIEW_RE = /^Reviewed-By\s*:\s*(\S+)$/i; - const CVE_RE = /^CVE-ID\s*:\s*(\S+)$/i; + const CVE_RE = /^CVE-ID\s*:\s*(\S+)$/im; this.startAmending(); @@ -328,41 +328,31 @@ export default class LandingSession extends Session { // git has very specific rules about what is a trailer and what is not. // Instead of trying to implement those ourselves, let git parse the // original commit message and see if it outputs any trailers. - const originalHasTrailers = runSync('git', [ + const originalTrailers = runSync('git', [ 'interpret-trailers', '--parse', '--no-divider' ], { input: `${original}\n` - }).trim().length !== 0; + }); + const containCVETrailer = CVE_RE.test(originalTrailers); const metadata = this.metadata.trim().split('\n'); - // Filtering out metadata that we will add ourselves: - const isFiltered = line => + // Only keep existing trailers that we won't add ourselves + const shouldKeepTrailer = line => + !!line && (!PR_RE.test(line) || this.backport) && !BACKPORT_RE.test(line) && !REVIEW_RE.test(line); - const amended = original.split('\n').filter(isFiltered); - - // If the original commit message already contains trailers (such as - // "Co-authored-by"), we simply add our own metadata after those. Otherwise, - // we have to add an empty line so that git recognizes our own metadata as - // trailers in the amended commit message. - if (!originalHasTrailers) { - amended.push(''); - } + const amended = original.slice(0, -originalTrailers.length).trim().split('\n'); + + amended.push('', ...originalTrailers.split('\n').filter(shouldKeepTrailer)); - let containCVETrailer = false; for (const line of metadata) { - if (line.length !== 0 && original.includes(line) && !isFiltered(line)) { - containCVETrailer ||= CVE_RE.test(line); - if (originalHasTrailers) { - cli.warn(`Found ${line}, skipping..`); - continue; - } else { - cli.error('Git found no trailers in the original commit message, ' + + if (originalTrailers.includes(line)) { + cli.error('Git found no trailers in the original commit message, ' + `but '${line}' is present and should be a trailer.`); - process.exit(1); // make it work with git rebase -x - } + process.exit(1); // make it work with git rebase -x } + if (BACKPORT_RE.test(line)) { const prIndex = (amended.findIndex(datum => PR_RE.test(datum)) + 1) || From 592e4cec55664369bd6b1a0233d7e5bf2640ccb3 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Fri, 3 Apr 2026 23:45:21 +0200 Subject: [PATCH 2/4] fixup! fix(git-node): fix handling of existing trailers --- lib/landing_session.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/landing_session.js b/lib/landing_session.js index 6fb902c2..c93d3e6c 100644 --- a/lib/landing_session.js +++ b/lib/landing_session.js @@ -336,21 +336,20 @@ export default class LandingSession extends Session { const containCVETrailer = CVE_RE.test(originalTrailers); const metadata = this.metadata.trim().split('\n'); + const amended = original.slice(0, -originalTrailers.length).trim().split('\n'); + // Only keep existing trailers that we won't add ourselves - const shouldKeepTrailer = line => + const keptTrailers = originalTrailers.split('\n').filter(line => !!line && (!PR_RE.test(line) || this.backport) && !BACKPORT_RE.test(line) && - !REVIEW_RE.test(line); - const amended = original.slice(0, -originalTrailers.length).trim().split('\n'); - - amended.push('', ...originalTrailers.split('\n').filter(shouldKeepTrailer)); + !REVIEW_RE.test(line)); + amended.push('', ...keptTrailers); for (const line of metadata) { - if (originalTrailers.includes(line)) { - cli.error('Git found no trailers in the original commit message, ' + - `but '${line}' is present and should be a trailer.`); - process.exit(1); // make it work with git rebase -x + if (keptTrailers.includes(line)) { + cli.warn(`Found ${line}, skipping..`); + continue; } if (BACKPORT_RE.test(line)) { From 8447bae21a17872f40a323e6b7909148adbbf840 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 4 Apr 2026 00:32:38 +0200 Subject: [PATCH 3/4] fixup! fix(git-node): fix handling of existing trailers --- lib/session.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/session.js b/lib/session.js index 088d168b..0f130108 100644 --- a/lib/session.js +++ b/lib/session.js @@ -127,6 +127,7 @@ export default class Session { writeJson(this.sessionPath, { state: STARTED, prid: this.prid, + backport: this.backport, // Filter out getters, those are likely encrypted data we don't need on the session. config: Object.entries(Object.getOwnPropertyDescriptors(this.config)) .reduce((pv, [key, desc]) => { @@ -271,6 +272,7 @@ export default class Session { const sess = this.session; if (sess.prid) { this.prid = sess.prid; + this.backport = sess.backport; this.config = sess.config; } return this; From 96e2e92fdaf0800a9cbc189a412a5926fc6809b2 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 4 Apr 2026 11:04:57 +0200 Subject: [PATCH 4/4] squash! lint --- lib/landing_session.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/landing_session.js b/lib/landing_session.js index c93d3e6c..8e1cfa44 100644 --- a/lib/landing_session.js +++ b/lib/landing_session.js @@ -337,7 +337,7 @@ export default class LandingSession extends Session { const metadata = this.metadata.trim().split('\n'); const amended = original.slice(0, -originalTrailers.length).trim().split('\n'); - + // Only keep existing trailers that we won't add ourselves const keptTrailers = originalTrailers.split('\n').filter(line => !!line &&