From 888bfbb945a28bd5067d53c690a9b78112bb21d0 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sun, 17 Nov 2024 12:42:52 +0100 Subject: [PATCH 1/2] feat(git-v8): preserve original author when backporting --- components/git/v8.js | 18 +++++++++-- lib/update-v8/backport.js | 67 ++++++++++++++++++++++++++++++++++----- lib/update-v8/index.js | 1 + 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/components/git/v8.js b/components/git/v8.js index b0c2879e..716718ab 100644 --- a/components/git/v8.js +++ b/components/git/v8.js @@ -44,10 +44,22 @@ export function builder(yargs) { describe: 'Bump V8 embedder version number or patch version', default: true }) + .option('gpg-sign', { + alias: 'S', + type: 'boolean', + describe: 'GPG-sign commits', + default: false + }) + .option('preserve-original-author', { + type: 'boolean', + describe: 'Preserve original commit author and date', + default: true + }) .option('squash', { type: 'boolean', describe: - 'If multiple commits are backported, squash them into one', + 'If multiple commits are backported, squash them into one. When ' + + '`--squash` is passed, `--preserve-original-author` will be ignored', default: false }); } @@ -88,7 +100,7 @@ export function handler(argv) { input, spawnArgs: { cwd: options.nodeDir, - stdio: input ? ['pipe', 'ignore', 'ignore'] : 'ignore' + stdio: input ? ['pipe', 'inherit', 'inherit'] : 'inherit' } }); }; @@ -97,7 +109,7 @@ export function handler(argv) { return forceRunAsync('git', args, { ignoreFailure: false, captureStdout: true, - spawnArgs: { cwd: options.v8Dir, stdio: ['ignore', 'pipe', 'ignore'] } + spawnArgs: { cwd: options.v8Dir, stdio: ['ignore', 'pipe', 'inherit'] } }); }; diff --git a/lib/update-v8/backport.js b/lib/update-v8/backport.js index e3ff224e..2b640952 100644 --- a/lib/update-v8/backport.js +++ b/lib/update-v8/backport.js @@ -41,6 +41,8 @@ export function doBackport(options) { } } todo.push(commitSquashedBackport()); + } else if (options.preserveOriginalAuthor) { + todo.push(cherryPickV8Commits(options)); } else { todo.push(applyAndCommitPatches()); } @@ -76,18 +78,35 @@ function commitSquashedBackport() { }; }; -function commitPatch(patch) { +const commitTask = (patch, ...extraArgs) => async(ctx) => { + const messageTitle = formatMessageTitle([patch]); + const messageBody = formatMessageBody(patch, false); + await ctx.execGitNode('add', ['deps/v8']); + await ctx.execGitNode('commit', [ + ...ctx.gpgSign, ...extraArgs, + '-m', messageTitle, '-m', messageBody + ]); +}; + +function amendHEAD(patch) { return { - title: 'Commit patch', + title: 'Amend/commit', task: async(ctx) => { - const messageTitle = formatMessageTitle([patch]); - const messageBody = formatMessageBody(patch, false); - await ctx.execGitNode('add', ['deps/v8']); - await ctx.execGitNode('commit', ['-m', messageTitle, '-m', messageBody]); + if (patch.hadConflicts) { + await ctx.execGitNode('am', [...ctx.gpgSign, '--continue']); + } + await commitTask(patch, '--amend')(ctx); } }; } +function commitPatch(patch) { + return { + title: 'Commit patch', + task: commitTask(patch) + }; +} + function formatMessageTitle(patches) { const action = patches.some(patch => patch.hadConflicts) ? 'backport' : 'cherry-pick'; @@ -167,6 +186,15 @@ function applyAndCommitPatches() { }; } +function cherryPickV8Commits() { + return { + title: 'Cherry-pick commit from V8 clone to deps/v8', + task: (ctx, task) => { + return task.newListr(ctx.patches.map(cherryPickV8CommitTask)); + } + }; +} + function applyPatchTask(patch) { return { title: `Commit ${shortSha(patch.sha)}`, @@ -190,10 +218,33 @@ function applyPatchTask(patch) { }; } -async function applyPatch(ctx, task, patch) { +function cherryPickV8CommitTask(patch) { + return { + title: `Commit ${shortSha(patch.sha)}`, + task: (ctx, task) => { + const todo = [ + { + title: 'Cherry-pick', + task: (ctx, task) => applyPatch(ctx, task, patch, 'am') + } + ]; + if (ctx.bump !== false) { + if (ctx.nodeMajorVersion < 9) { + todo.push(incrementV8Version()); + } else { + todo.push(incrementEmbedderVersion()); + } + } + todo.push(amendHEAD(patch)); + return task.newListr(todo); + } + }; +} + +async function applyPatch(ctx, task, patch, method = 'apply') { try { await ctx.execGitNode( - 'apply', + method, ['-p1', '--3way', '--directory=deps/v8'], patch.data /* input */ ); diff --git a/lib/update-v8/index.js b/lib/update-v8/index.js index 4f999e90..1c9afca1 100644 --- a/lib/update-v8/index.js +++ b/lib/update-v8/index.js @@ -26,6 +26,7 @@ export function minor(options) { export async function backport(options) { const shouldStop = await checkOptions(options); if (shouldStop) return; + options.gpgSign = options.gpgSign ? ['-S'] : []; const tasks = new Listr( [updateV8Clone(), doBackport(options)], getOptions(options) From b317b282eebb8e2ba7d391992c40db0029b98b48 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sun, 17 Nov 2024 17:42:25 +0100 Subject: [PATCH 2/2] add user as co-author in case of conflict --- lib/update-v8/backport.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/update-v8/backport.js b/lib/update-v8/backport.js index 2b640952..6df9a6c0 100644 --- a/lib/update-v8/backport.js +++ b/lib/update-v8/backport.js @@ -9,6 +9,7 @@ import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer'; import { shortSha } from '../utils.js'; import { getCurrentV8Version } from './common.js'; +import { forceRunAsync } from '../run.js'; export async function checkOptions(options) { if (options.sha.length > 1 && options.squash) { @@ -78,9 +79,9 @@ function commitSquashedBackport() { }; }; -const commitTask = (patch, ...extraArgs) => async(ctx) => { +const commitTask = (patch, extraArgs, trailers) => async(ctx) => { const messageTitle = formatMessageTitle([patch]); - const messageBody = formatMessageBody(patch, false); + const messageBody = formatMessageBody(patch, false, trailers); await ctx.execGitNode('add', ['deps/v8']); await ctx.execGitNode('commit', [ ...ctx.gpgSign, ...extraArgs, @@ -92,10 +93,22 @@ function amendHEAD(patch) { return { title: 'Amend/commit', task: async(ctx) => { + let coAuthor; if (patch.hadConflicts) { + const getGitConfigEntry = async(configKey) => { + const output = await forceRunAsync('git', ['config', configKey], { + ignoreFailure: false, + captureStdout: true, + spawnArgs: { cwd: ctx.nodeDir } + }); + return output.trim(); + }; await ctx.execGitNode('am', [...ctx.gpgSign, '--continue']); + coAuthor = `\nCo-authored-by: ${ + await getGitConfigEntry('user.name')} <${ + await getGitConfigEntry('user.email')}>`; } - await commitTask(patch, '--amend')(ctx); + await commitTask(patch, ['--amend'], coAuthor)(ctx); } }; } @@ -125,12 +138,12 @@ function formatMessageTitle(patches) { } } -function formatMessageBody(patch, prefixTitle) { +function formatMessageBody(patch, prefixTitle, trailers = '') { const indentedMessage = patch.message.replace(/\n/g, '\n '); const body = 'Original commit message:\n\n' + ` ${indentedMessage}\n\n` + - `Refs: https://github.com/v8/v8/commit/${patch.sha}`; + `Refs: https://github.com/v8/v8/commit/${patch.sha}${trailers}`; if (prefixTitle) { const action = patch.hadConflicts ? 'Backport' : 'Cherry-pick';