From ec6c6cbf23d90738e4e73a17c245d24ac331de7d Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 19 Nov 2024 18:21:59 +0000 Subject: [PATCH] fix(git-node): do not assume release commit will conflict (#871) --- lib/promote_release.js | 55 +++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/lib/promote_release.js b/lib/promote_release.js index e3f919a3..e8aeaa25 100644 --- a/lib/promote_release.js +++ b/lib/promote_release.js @@ -144,23 +144,34 @@ export default class ReleasePromotion extends Session { cli.warn(`Aborting release promotion for version ${version}`); throw new Error('Aborted'); } - await this.cherryPickToDefaultBranch(); - - // Update `node_version.h` - await forceRunAsync('git', ['checkout', 'HEAD', '--', 'src/node_version.h'], - { ignoreFailure: false }); + const appliedCleanly = await this.cherryPickToDefaultBranch(); + + // Ensure `node_version.h`'s `NODE_VERSION_IS_RELEASE` bit is not updated + await forceRunAsync('git', ['checkout', + appliedCleanly + ? 'HEAD^' // In the absence of conflict, the top of the remote branch is the commit before. + : 'HEAD', // In case of conflict, HEAD is still the top of the remove branch. + '--', 'src/node_version.h'], + { ignoreFailure: false }); - // There will be remaining cherry-pick conflicts the Releaser will - // need to resolve, so confirm they've been resolved before - // proceeding with next steps. - cli.separator(); - cli.info('Resolve the conflicts and commit the result'); - cli.separator(); - const didResolveConflicts = await cli.prompt( - 'Finished resolving cherry-pick conflicts?', { defaultAnswer: true }); - if (!didResolveConflicts) { - cli.warn(`Aborting release promotion for version ${version}`); - throw new Error('Aborted'); + if (appliedCleanly) { + // There were no conflicts, we have to amend the commit to revert the + // `node_version.h` changes. + await forceRunAsync('git', ['commit', ...this.gpgSign, '--amend', '--no-edit', '-n'], + { ignoreFailure: false }); + } else { + // There will be remaining cherry-pick conflicts the Releaser will + // need to resolve, so confirm they've been resolved before + // proceeding with next steps. + cli.separator(); + cli.info('Resolve the conflicts and commit the result'); + cli.separator(); + const didResolveConflicts = await cli.prompt( + 'Finished resolving cherry-pick conflicts?', { defaultAnswer: true }); + if (!didResolveConflicts) { + cli.warn(`Aborting release promotion for version ${version}`); + throw new Error('Aborted'); + } } if (existsSync('.git/CHERRY_PICK_HEAD')) { @@ -469,8 +480,14 @@ export default class ReleasePromotion extends Session { await this.tryResetBranch(); - // There will be conflicts, we do not want to treat this as a failure. - await forceRunAsync('git', ['cherry-pick', ...this.gpgSign, releaseCommitSha], - { ignoreFailure: true }); + // There might be conflicts, we do not want to treat this as a hard failure, + // but we want to retain that information. + try { + await forceRunAsync('git', ['cherry-pick', ...this.gpgSign, releaseCommitSha], + { ignoreFailure: false }); + return true; + } catch { + return false; + } } }