Skip to content

feat(git-node): add release promotion step #835

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

Merged
merged 50 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9ee6605
git-node: add release promotion step
codebytere Apr 9, 2020
15c4cb0
Move newVersion to named arg
codebytere Apr 9, 2020
0ec3327
Split out promotion verification steps
codebytere Apr 9, 2020
a1c3ef1
Fix verification spinners
codebytere Apr 14, 2020
61dbeb7
Verify ncurc is set up
codebytere Apr 14, 2020
ea29f87
Properly trim getCommitSha result
codebytere Apr 14, 2020
c0db1ce
Address some feedback
codebytere May 4, 2020
7d23d70
Ensure synced with upstream/master
codebytere May 4, 2020
692c6b7
fix: run release script asynchronously
codebytere May 4, 2020
c1ab158
Run secureTagRelease() asynchronously
codebytere May 20, 2020
ddfe6ef
Run cherry-pick asynchronously
codebytere May 26, 2020
3377b44
Remove unneccessary quotes
codebytere May 26, 2020
88b99f3
Merge branch 'main' of https://github.com./nodejs/node-core-utils
aduh95 Jul 22, 2024
a08566d
nits
aduh95 Jul 22, 2024
0229ccf
esm
aduh95 Jul 22, 2024
ba23781
some refactor + more checks
aduh95 Jul 22, 2024
8ef8c41
fixup! Merge branch 'main' of https://github.com./nodejs/node-core-utils
aduh95 Jul 22, 2024
8d02a41
throw on error to get non-zero exit code
aduh95 Jul 22, 2024
15c0335
lint
aduh95 Jul 22, 2024
ce72380
validate CHANGELOG heading
aduh95 Jul 22, 2024
519388c
add support for PR URL
aduh95 Jul 22, 2024
a1b1974
check if local HEAD is in sync with release proposal
aduh95 Jul 22, 2024
6db9959
Use existing `tryResetBranch` instead of custom git command
aduh95 Jul 22, 2024
3cc80b1
auto fix node_version conflicts
aduh95 Jul 22, 2024
04b4d4d
add `--dryRun` mode to simplify testing
aduh95 Jul 22, 2024
70294cf
fix conflicts making the process crash
aduh95 Jul 22, 2024
549ac8e
fix bug when checking modified files
aduh95 Jul 22, 2024
4bd64c9
do not hard code default branch name
aduh95 Jul 22, 2024
1104f09
fix type
aduh95 Jul 22, 2024
5b91899
add `--gpgSign`/`-S` option
aduh95 Jul 22, 2024
575196d
fixup! add `--gpgSign`/`-S` option
aduh95 Jul 22, 2024
7ed9d06
better handling of releaser not on the team
aduh95 Jul 22, 2024
66fdab5
add `gh release create` note
aduh95 Jul 22, 2024
79d3789
Fix `undefined` in spinner text
aduh95 Jul 22, 2024
d65fd6a
fixup! add `gh release create` note
aduh95 Jul 22, 2024
7c1dfbe
make `--dryRun` more useful
aduh95 Jul 23, 2024
d9d97cb
fix "release date does not match the system date for today" incorrect…
aduh95 Aug 6, 2024
8aa8c08
run `cherry-pick --continue`
aduh95 Aug 6, 2024
c1aa8cb
use one `git push` command instead of two
aduh95 Aug 14, 2024
4e45c8b
Add a more verbose `--dry-run` message
aduh95 Aug 14, 2024
3cccce3
fix typo
aduh95 Aug 14, 2024
5ccb474
`--dry-run` -> `--run`
aduh95 Aug 14, 2024
0196904
Fix `gh release create` command suggestion
aduh95 Aug 22, 2024
423aba8
Merge branch 'main' into git-node-release-promote
aduh95 Aug 28, 2024
a9512d0
fetch default branch name from GitHub API
aduh95 Oct 11, 2024
37ffe70
add spinner when fetching the proposal
aduh95 Oct 11, 2024
c3fb51e
fixup! fetch default branch name from GitHub API
aduh95 Oct 11, 2024
55e4a79
allow reusing existing tag as long as it points to the correct commit
aduh95 Oct 11, 2024
e78b1c7
Merge branch 'main' into git-node-release-promote
aduh95 Nov 6, 2024
94e38df
fix alphabetical order
aduh95 Nov 6, 2024
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
80 changes: 65 additions & 15 deletions components/git/release.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import auth from '../../lib/auth.js';
import CLI from '../../lib/cli.js';
import ReleasePreparation from '../../lib/prepare_release.js';
import ReleasePromotion from '../../lib/promote_release.js';
import TeamInfo from '../../lib/team_info.js';
import Request from '../../lib/request.js';
import { runPromise } from '../../lib/run.js';

export const command = 'release [newVersion|options]';
export const command = 'release [prid|options]';
export const describe = 'Manage an in-progress release or start a new one.';

const PREPARE = 'prepare';
const PROMOTE = 'promote';
const RELEASERS = 'releasers';

const releaseOptions = {
filterLabel: {
describe: 'Labels separated by "," to filter security PRs',
type: 'string'
},
'gpg-sign': {
describe: 'GPG-sign commits, will be passed to the git process',
alias: 'S'
},
newVersion: {
describe: 'Version number of the release to be prepared',
type: 'string'
},
prepare: {
describe: 'Prepare a new release of Node.js',
type: 'boolean'
Expand All @@ -21,14 +38,16 @@ const releaseOptions = {
describe: 'Default relase date when --prepare is used. It must be YYYY-MM-DD',
type: 'string'
},
run: {
describe: 'Run steps that involve touching more than the local clone, ' +
'including `git push` commands. Might not work if a passphrase ' +
'required to push to the remote clone.',
type: 'boolean'
},
security: {
describe: 'Demarcate the new security release as a security release',
type: 'boolean'
},
filterLabel: {
describe: 'Labels separated by "," to filter security PRs',
type: 'string'
},
skipBranchDiff: {
describe: 'Skips the initial branch-diff check when preparing releases',
type: 'boolean'
Expand All @@ -49,11 +68,16 @@ let yargsInstance;
export function builder(yargs) {
yargsInstance = yargs;
return yargs
.options(releaseOptions).positional('newVersion', {
describe: 'Version number of the release to be prepared or promoted'
.options(releaseOptions).positional('prid', {
describe: 'PR number or URL of the release proposal to be promoted',
type: 'string'
})
.example('git node release --prepare 1.2.3',
'Prepare a release of Node.js tagged v1.2.3')
.example('git node release --prepare --security',
'Prepare a new security release of Node.js with auto-determined version')
.example('git node release --prepare --newVersion=1.2.3',
'Prepare a new release of Node.js tagged v1.2.3')
.example('git node release --promote 12345',
'Promote a prepared release of Node.js with PR #12345')
.example('git node --prepare --startLTS',
'Prepare the first LTS release');
}
Expand Down Expand Up @@ -88,17 +112,21 @@ function release(state, argv) {
}

async function main(state, argv, cli, dir) {
const prID = /^(?:https:\/\/github\.com\/nodejs\/node\/pull\/)?(\d+)$/.exec(argv.prid);
if (prID) {
argv.prid = Number(prID[1]);
}
if (state === PREPARE) {
const prep = new ReleasePreparation(argv, cli, dir);
const release = new ReleasePreparation(argv, cli, dir);

await prep.prepareLocalBranch();
await release.prepareLocalBranch();

if (prep.warnForWrongBranch()) return;
if (release.warnForWrongBranch()) return;

// If the new version was automatically calculated, confirm it.
if (!argv.newVersion) {
const create = await cli.prompt(
`Create release with new version ${prep.newVersion}?`,
`Create release with new version ${release.newVersion}?`,
{ defaultAnswer: true });

if (!create) {
Expand All @@ -107,8 +135,30 @@ async function main(state, argv, cli, dir) {
}
}

return prep.prepare();
return release.prepare();
} else if (state === PROMOTE) {
// TODO(codebytere): implement release promotion.
const credentials = await auth({ github: true });
const request = new Request(credentials);
const release = new ReleasePromotion(argv, request, cli, dir);

cli.startSpinner('Verifying Releaser status');
const info = new TeamInfo(cli, request, 'nodejs', RELEASERS);

const releasers = await info.getMembers();
if (release.username === undefined) {
cli.stopSpinner('Failed to verify Releaser status');
cli.info(
'Username was undefined - do you have your .ncurc set up correctly?');
return;
} else if (releasers.every(r => r.login !== release.username)) {
cli.stopSpinner(`${release.username} is not a Releaser`, 'failed');
if (!argv.dryRun) {
throw new Error('aborted');
}
} else {
cli.stopSpinner(`${release.username} is a Releaser`);
}

return release.promote();
}
}
Loading
Loading