Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(git-node): use a single git push command #870

Merged
merged 2 commits into from
Nov 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 24 additions & 43 deletions lib/promote_release.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,9 @@ export default class ReleasePromotion extends Session {

// Set up for next release.
cli.startSpinner('Setting up for next release');
await this.setupForNextRelease();
const workingOnNewReleaseCommit = await this.setupForNextRelease();
cli.stopSpinner('Successfully set up for next release');

// Merge vX.Y.Z-proposal into vX.x.
await this.mergeProposalBranch();

// Cherry pick release commit to master.
const shouldCherryPick = await cli.prompt(
'Cherry-pick release commit to the default branch?', { defaultAnswer: true });
Expand Down Expand Up @@ -186,8 +183,8 @@ export default class ReleasePromotion extends Session {
}
}

// Push to the remote default branch and release tag.
await this.pushTagAndDefaultBranchToRemote();
// Push to the remote the release tag, and default, release, and staging branch.
await this.pushToRemote(workingOnNewReleaseCommit);

// Promote and sign the release builds.
await this.promoteAndSignRelease();
Expand Down Expand Up @@ -385,56 +382,36 @@ export default class ReleasePromotion extends Session {

// Create 'Working On' commit.
await forceRunAsync('git', ['add', filePath], { ignoreFailure: false });
return forceRunAsync('git', [
await forceRunAsync('git', [
'commit',
...this.gpgSign,
'-m',
`Working on ${workingOnVersion}`,
'-m',
`PR-URL: https://github.com/nodejs/node/pull/${prid}`
], { ignoreFailure: false });
const workingOnNewReleaseCommit = await forceRunAsync('git', ['rev-parse', 'HEAD'],
{ ignoreFailure: false, captureStdout: true });
return workingOnNewReleaseCommit.trim();
}

async mergeProposalBranch() {
const { cli, dryRun, stagingBranch, versionComponents } = this;
async pushToRemote(workingOnNewReleaseCommit) {
const { cli, dryRun, version, versionComponents, stagingBranch } = this;
const releaseBranch = `v${versionComponents.major}.x`;

let prompt = 'Merge proposal branch into staging branch?';
if (dryRun) {
cli.info(dryRunMessage);
cli.info('Run the following commands to merge the staging branch:');
cli.info(`git push ${this.upstream} HEAD:refs/heads/${releaseBranch
} HEAD:refs/heads/${stagingBranch}`);
prompt = 'Ready to continue?';
}

const shouldMergeProposalBranch = await cli.prompt(prompt, { defaultAnswer: true });
if (!shouldMergeProposalBranch) {
cli.warn('Aborting release promotion');
throw new Error('Aborted');
} else if (dryRun) {
return;
}

// TODO: find a solution for key passphrase from the terminal
cli.startSpinner('Merging proposal branch');
await forceRunAsync('git', ['push', this.upstream, `HEAD:refs/heads/${releaseBranch}`,
`HEAD:refs/heads/${stagingBranch}`],
{ ignoreFailure: false });
cli.stopSpinner('Merged proposal branch');
}

async pushTagAndDefaultBranchToRemote() {
const { cli, dryRun, version } = this;
const tagVersion = `v${version}`;

this.defaultBranch ??= await this.getDefaultBranch();

let prompt = `Push release tag and ${this.defaultBranch} to ${this.upstream}?`;
let prompt = `Push release tag and commits to ${this.upstream}?`;
if (dryRun) {
cli.info(dryRunMessage);
cli.info('Run the following commands to push to remote:');
cli.info(`git push ${this.upstream} ${this.defaultBranch} ${tagVersion}`);
cli.info('Run the following command to push to remote:');
cli.info(`git push ${this.upstream} ${
this.defaultBranch} ${
tagVersion} ${
workingOnNewReleaseCommit}:refs/heads/${releaseBranch} ${
workingOnNewReleaseCommit}:refs/heads/${stagingBranch}`);
cli.warn('Once pushed, you must not delete the local tag');
prompt = 'Ready to continue?';
}

Expand All @@ -447,9 +424,13 @@ export default class ReleasePromotion extends Session {
}

cli.startSpinner('Pushing to remote');
await forceRunAsync('git', ['push', this.upstream, this.defaultBranch, tagVersion],
{ ignoreFailure: false });
cli.stopSpinner(`Pushed ${tagVersion} and ${this.defaultBranch} to remote`);
await forceRunAsync('git', ['push', this.upstream, this.defaultBranch, tagVersion,
`${workingOnNewReleaseCommit}:refs/heads/${releaseBranch}`,
`${workingOnNewReleaseCommit}:refs/heads/${stagingBranch}`],
{ ignoreFailure: false });
cli.stopSpinner(`Pushed ${tagVersion}, ${this.defaultBranch}, ${
releaseBranch}, and ${stagingBranch} to remote`);
cli.warn('Now that it has been pushed, you must not delete the local tag');
}

async promoteAndSignRelease() {
Expand Down
Loading