@node-core/utils 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +158 -0
- package/bin/get-metadata.js +11 -0
- package/bin/git-node.js +30 -0
- package/bin/ncu-ci.js +600 -0
- package/bin/ncu-config.js +101 -0
- package/bin/ncu-team.js +76 -0
- package/components/git/backport.js +70 -0
- package/components/git/epilogue.js +18 -0
- package/components/git/land.js +223 -0
- package/components/git/metadata.js +94 -0
- package/components/git/release.js +99 -0
- package/components/git/security.js +35 -0
- package/components/git/status.js +32 -0
- package/components/git/sync.js +24 -0
- package/components/git/v8.js +121 -0
- package/components/git/vote.js +84 -0
- package/components/git/wpt.js +87 -0
- package/components/metadata.js +49 -0
- package/lib/auth.js +133 -0
- package/lib/backport_session.js +302 -0
- package/lib/cache.js +107 -0
- package/lib/cherry_pick.js +304 -0
- package/lib/ci/build-types/benchmark_run.js +72 -0
- package/lib/ci/build-types/citgm_build.js +194 -0
- package/lib/ci/build-types/citgm_comparison_build.js +174 -0
- package/lib/ci/build-types/commit_build.js +112 -0
- package/lib/ci/build-types/daily_build.js +24 -0
- package/lib/ci/build-types/fanned_build.js +87 -0
- package/lib/ci/build-types/health_build.js +63 -0
- package/lib/ci/build-types/job.js +114 -0
- package/lib/ci/build-types/linter_build.js +35 -0
- package/lib/ci/build-types/normal_build.js +89 -0
- package/lib/ci/build-types/pr_build.js +101 -0
- package/lib/ci/build-types/test_build.js +186 -0
- package/lib/ci/build-types/test_run.js +41 -0
- package/lib/ci/ci_failure_parser.js +325 -0
- package/lib/ci/ci_type_parser.js +203 -0
- package/lib/ci/ci_utils.js +106 -0
- package/lib/ci/failure_aggregator.js +152 -0
- package/lib/ci/jenkins_constants.js +28 -0
- package/lib/ci/run_ci.js +120 -0
- package/lib/cli.js +192 -0
- package/lib/collaborators.js +140 -0
- package/lib/config.js +72 -0
- package/lib/figures.js +7 -0
- package/lib/file.js +43 -0
- package/lib/github/templates/next-security-release.md +97 -0
- package/lib/github/tree.js +162 -0
- package/lib/landing_session.js +506 -0
- package/lib/links.js +123 -0
- package/lib/mergeable_state.js +3 -0
- package/lib/metadata_gen.js +61 -0
- package/lib/pr_checker.js +605 -0
- package/lib/pr_data.js +115 -0
- package/lib/pr_summary.js +62 -0
- package/lib/prepare_release.js +772 -0
- package/lib/prepare_security.js +117 -0
- package/lib/proxy.js +21 -0
- package/lib/queries/DefaultBranchRef.gql +8 -0
- package/lib/queries/LastCommit.gql +16 -0
- package/lib/queries/PR.gql +37 -0
- package/lib/queries/PRComments.gql +27 -0
- package/lib/queries/PRCommits.gql +45 -0
- package/lib/queries/PRs.gql +25 -0
- package/lib/queries/Reviews.gql +23 -0
- package/lib/queries/SearchIssue.gql +51 -0
- package/lib/queries/Team.gql +22 -0
- package/lib/queries/TreeEntries.gql +12 -0
- package/lib/queries/VotePRInfo.gql +28 -0
- package/lib/release/utils.js +53 -0
- package/lib/request.js +185 -0
- package/lib/review_state.js +5 -0
- package/lib/reviews.js +178 -0
- package/lib/run.js +106 -0
- package/lib/session.js +415 -0
- package/lib/sync_session.js +15 -0
- package/lib/team_info.js +95 -0
- package/lib/update-v8/applyNodeChanges.js +49 -0
- package/lib/update-v8/backport.js +258 -0
- package/lib/update-v8/commitUpdate.js +26 -0
- package/lib/update-v8/common.js +35 -0
- package/lib/update-v8/constants.js +86 -0
- package/lib/update-v8/index.js +56 -0
- package/lib/update-v8/majorUpdate.js +171 -0
- package/lib/update-v8/minorUpdate.js +105 -0
- package/lib/update-v8/updateMaintainingDependencies.js +34 -0
- package/lib/update-v8/updateV8Clone.js +53 -0
- package/lib/update-v8/updateVersionNumbers.js +122 -0
- package/lib/update-v8/util.js +62 -0
- package/lib/user.js +4 -0
- package/lib/user_status.js +5 -0
- package/lib/utils.js +66 -0
- package/lib/verbosity.js +26 -0
- package/lib/voting_session.js +136 -0
- package/lib/wpt/index.js +243 -0
- package/lib/wpt/templates/README.md +16 -0
- package/package.json +69 -0
package/bin/ncu-team.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import yargs from 'yargs';
|
|
4
|
+
import { hideBin } from 'yargs/helpers';
|
|
5
|
+
|
|
6
|
+
import Request from '../lib/request.js';
|
|
7
|
+
import auth from '../lib/auth.js';
|
|
8
|
+
import { runPromise } from '../lib/run.js';
|
|
9
|
+
import CLI from '../lib/cli.js';
|
|
10
|
+
import TeamInfo from '../lib/team_info.js';
|
|
11
|
+
|
|
12
|
+
import { setVerbosityFromEnv } from '../lib/verbosity.js';
|
|
13
|
+
|
|
14
|
+
setVerbosityFromEnv();
|
|
15
|
+
|
|
16
|
+
yargs(hideBin(process.argv))
|
|
17
|
+
.completion('completion')
|
|
18
|
+
.command({
|
|
19
|
+
command: 'list <team> [org]',
|
|
20
|
+
desc: 'Get the list of members in a team',
|
|
21
|
+
builder: (yargs) => {
|
|
22
|
+
yargs
|
|
23
|
+
.positional('team', {
|
|
24
|
+
describe: 'Name of the team',
|
|
25
|
+
type: 'string'
|
|
26
|
+
})
|
|
27
|
+
.positional('org', {
|
|
28
|
+
describe: 'Name of the organization',
|
|
29
|
+
type: 'string',
|
|
30
|
+
default: 'nodejs'
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
handler
|
|
34
|
+
})
|
|
35
|
+
.command({
|
|
36
|
+
command: 'sync <file>',
|
|
37
|
+
desc:
|
|
38
|
+
'Synchronize the <!-- ncu-team-sync.team($org/$team) --> block in a file',
|
|
39
|
+
builder: (yargs) => {
|
|
40
|
+
yargs
|
|
41
|
+
.positional('file', {
|
|
42
|
+
describe: 'Path to the file to update',
|
|
43
|
+
type: 'string'
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
handler
|
|
47
|
+
})
|
|
48
|
+
.demandCommand(1, 'must provide a valid command')
|
|
49
|
+
.help()
|
|
50
|
+
.parse();
|
|
51
|
+
|
|
52
|
+
function handler(argv) {
|
|
53
|
+
runPromise(main(argv));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function main(argv) {
|
|
57
|
+
const cli = new CLI();
|
|
58
|
+
const credentials = await auth({
|
|
59
|
+
github: true
|
|
60
|
+
});
|
|
61
|
+
const request = new Request(credentials);
|
|
62
|
+
|
|
63
|
+
const [command] = argv._;
|
|
64
|
+
switch (command) {
|
|
65
|
+
case 'list': {
|
|
66
|
+
const info = new TeamInfo(cli, request, argv.org, argv.team);
|
|
67
|
+
await info.listMembers();
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case 'sync':
|
|
71
|
+
await TeamInfo.syncFile(cli, request, argv.file);
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
throw new Error(`Unknown command ${command}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { parsePRFromURL } from '../../lib/links.js';
|
|
2
|
+
import CLI from '../../lib/cli.js';
|
|
3
|
+
import { runPromise } from '../../lib/run.js';
|
|
4
|
+
import BackportSession from '../../lib/backport_session.js';
|
|
5
|
+
|
|
6
|
+
export const command = 'backport <identifier>';
|
|
7
|
+
export const describe = 'Backport a PR to a release staging branch.';
|
|
8
|
+
|
|
9
|
+
const epilogue = `====================== Example =======================
|
|
10
|
+
Demo: https://asciinema.org/a/221244
|
|
11
|
+
Backporting https://github.com/nodejs/node/pull/24816 to v11.x
|
|
12
|
+
|
|
13
|
+
# Sync main with upstream for the commits, if they are not yet there
|
|
14
|
+
$ git checkout main
|
|
15
|
+
$ ncu-config set branch main
|
|
16
|
+
$ git node sync
|
|
17
|
+
|
|
18
|
+
# Backport existing commits from main to v11.x-staging
|
|
19
|
+
$ git checkout v11.x-staging
|
|
20
|
+
$ ncu-config set branch v11.x-staging
|
|
21
|
+
$ git node sync
|
|
22
|
+
$ git node backport 24816 --to 11
|
|
23
|
+
=====================================================
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
let yargsInstance;
|
|
27
|
+
|
|
28
|
+
export function builder(yargs) {
|
|
29
|
+
yargsInstance = yargs;
|
|
30
|
+
return yargs
|
|
31
|
+
.options({
|
|
32
|
+
to: {
|
|
33
|
+
describe: 'release to backport the commits to',
|
|
34
|
+
type: 'number',
|
|
35
|
+
required: true
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
.positional('identifier', {
|
|
39
|
+
type: 'string',
|
|
40
|
+
describe: 'ID or URL of the pull request'
|
|
41
|
+
})
|
|
42
|
+
.epilogue(epilogue)
|
|
43
|
+
.wrap(90);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function main(argv, parsed) {
|
|
47
|
+
const merged = (await import('../../lib/config.js')).getMergedConfig();
|
|
48
|
+
const config = Object.assign({}, argv, parsed, merged);
|
|
49
|
+
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
|
50
|
+
const cli = new CLI(logStream);
|
|
51
|
+
cli.setFigureIndent(0);
|
|
52
|
+
const dir = process.cwd();
|
|
53
|
+
const session = new BackportSession(cli, dir, config.prid, config.to);
|
|
54
|
+
return session.backport();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function handler(argv) {
|
|
58
|
+
let parsed = {};
|
|
59
|
+
const prid = Number.parseInt(argv.identifier);
|
|
60
|
+
if (!Number.isNaN(prid)) {
|
|
61
|
+
parsed.prid = prid;
|
|
62
|
+
} else {
|
|
63
|
+
parsed = parsePRFromURL(argv.identifier);
|
|
64
|
+
if (!parsed) {
|
|
65
|
+
return yargsInstance.showHelp();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return runPromise(main(argv, parsed));
|
|
70
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default `Steps to land a pull request:
|
|
2
|
+
==============================================================================
|
|
3
|
+
$ cd path/to/node/project
|
|
4
|
+
|
|
5
|
+
# If you have not configured it before
|
|
6
|
+
$ ncu-config set upstream <name-of-remote-to-nodejs/node>
|
|
7
|
+
$ ncu-config set branch main # Assuming you are landing commits on main
|
|
8
|
+
|
|
9
|
+
$ git checkout main
|
|
10
|
+
$ git node land --abort # Abort a landing session, just in case
|
|
11
|
+
$ git node land $PRID # Start a new landing session
|
|
12
|
+
$ git node land $URL # Start a new landing session using the PR URL
|
|
13
|
+
|
|
14
|
+
# Follow instructions provided.
|
|
15
|
+
|
|
16
|
+
$ git node land --final # Verify all the commit messages
|
|
17
|
+
==============================================================================
|
|
18
|
+
Watch https://asciinema.org/a/148627 for a complete demo`;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import auth from '../../lib/auth.js';
|
|
2
|
+
import { parsePRFromURL } from '../../lib/links.js';
|
|
3
|
+
import { getMetadata } from '../metadata.js';
|
|
4
|
+
import CLI from '../../lib/cli.js';
|
|
5
|
+
import Request from '../../lib/request.js';
|
|
6
|
+
import { runPromise } from '../../lib/run.js';
|
|
7
|
+
import LandingSession from '../../lib/landing_session.js';
|
|
8
|
+
import epilogue from './epilogue.js';
|
|
9
|
+
|
|
10
|
+
export const command = 'land [prid|options]';
|
|
11
|
+
export const describe =
|
|
12
|
+
'Manage the current landing session or start a new one for a pull request';
|
|
13
|
+
|
|
14
|
+
const landActions = {
|
|
15
|
+
apply: {
|
|
16
|
+
describe: 'Apply a patch with the given PR id',
|
|
17
|
+
type: 'number'
|
|
18
|
+
},
|
|
19
|
+
amend: {
|
|
20
|
+
describe: 'Amend the current commit',
|
|
21
|
+
type: 'boolean'
|
|
22
|
+
},
|
|
23
|
+
continue: {
|
|
24
|
+
alias: 'c',
|
|
25
|
+
describe: 'Continue the landing session',
|
|
26
|
+
type: 'boolean'
|
|
27
|
+
},
|
|
28
|
+
final: {
|
|
29
|
+
describe: 'Verify the landed PR and clean up',
|
|
30
|
+
type: 'boolean'
|
|
31
|
+
},
|
|
32
|
+
abort: {
|
|
33
|
+
describe: 'Abort the current landing session',
|
|
34
|
+
type: 'boolean'
|
|
35
|
+
},
|
|
36
|
+
backport: {
|
|
37
|
+
describe: 'Land a backport PR onto a staging branch',
|
|
38
|
+
default: false,
|
|
39
|
+
type: 'boolean'
|
|
40
|
+
},
|
|
41
|
+
'gpg-sign': {
|
|
42
|
+
describe: 'GPG-sign commits, will be passed to the git process',
|
|
43
|
+
alias: 'S'
|
|
44
|
+
},
|
|
45
|
+
autorebase: {
|
|
46
|
+
describe: 'Automatically rebase branches with multiple commits',
|
|
47
|
+
default: false,
|
|
48
|
+
type: 'boolean'
|
|
49
|
+
},
|
|
50
|
+
fixupAll: {
|
|
51
|
+
describe: 'Automatically fixup all commits to the first one dismissing ' +
|
|
52
|
+
'other commit messages',
|
|
53
|
+
default: false,
|
|
54
|
+
type: 'boolean'
|
|
55
|
+
},
|
|
56
|
+
oneCommitMax: {
|
|
57
|
+
describe: 'When run in conjunction with the --yes and --autorebase ' +
|
|
58
|
+
'options, will abort the session if trying to land more than one commit',
|
|
59
|
+
default: false,
|
|
60
|
+
type: 'boolean'
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const landOptions = {
|
|
65
|
+
yes: {
|
|
66
|
+
type: 'boolean',
|
|
67
|
+
default: false,
|
|
68
|
+
describe: 'Assume "yes" as answer to all prompts and run ' +
|
|
69
|
+
'non-interactively. If an undesirable situation occurs, such as a pull ' +
|
|
70
|
+
'request or commit check fails, then git node land will abort.'
|
|
71
|
+
},
|
|
72
|
+
skipRefs: {
|
|
73
|
+
describe: 'Prevent adding Fixes and Refs information to commit metadata',
|
|
74
|
+
default: false,
|
|
75
|
+
type: 'boolean'
|
|
76
|
+
},
|
|
77
|
+
lint: {
|
|
78
|
+
describe: 'Run linter while landing commits',
|
|
79
|
+
default: false,
|
|
80
|
+
type: 'boolean'
|
|
81
|
+
},
|
|
82
|
+
checkCI: {
|
|
83
|
+
describe: 'Query Jenkins CI results when checking the PR',
|
|
84
|
+
default: true,
|
|
85
|
+
type: 'boolean'
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
let yargsInstance;
|
|
90
|
+
|
|
91
|
+
export function builder(yargs) {
|
|
92
|
+
yargsInstance = yargs;
|
|
93
|
+
return yargs
|
|
94
|
+
.options(Object.assign({}, landOptions, landActions))
|
|
95
|
+
.positional('prid', {
|
|
96
|
+
describe: 'ID or URL of the Pull Request'
|
|
97
|
+
})
|
|
98
|
+
.epilogue(epilogue)
|
|
99
|
+
.example('git node land https://github.com/nodejs/node/pull/12344',
|
|
100
|
+
'Land https://github.com/nodejs/node/pull/12344 in the current directory')
|
|
101
|
+
.example('git node land 12344',
|
|
102
|
+
'Land https://github.com/nodejs/node/pull/12344 in the current directory')
|
|
103
|
+
.example('git node land --abort',
|
|
104
|
+
'Abort the current session')
|
|
105
|
+
.example('git node land --amend',
|
|
106
|
+
'Append metadata to the current commit message')
|
|
107
|
+
.example('git node land --final',
|
|
108
|
+
'Verify the landed PR and clean up')
|
|
109
|
+
.example('git node land --continue',
|
|
110
|
+
'Continue the current landing session');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const START = 'start';
|
|
114
|
+
const APPLY = 'apply';
|
|
115
|
+
const AMEND = 'amend';
|
|
116
|
+
const FINAL = 'final';
|
|
117
|
+
const CONTINUE = 'continue';
|
|
118
|
+
const ABORT = 'abort';
|
|
119
|
+
|
|
120
|
+
export function handler(argv) {
|
|
121
|
+
if (argv.prid) {
|
|
122
|
+
if (Number.isInteger(argv.prid)) {
|
|
123
|
+
return land(START, argv);
|
|
124
|
+
} else {
|
|
125
|
+
const parsed = parsePRFromURL(argv.prid);
|
|
126
|
+
if (parsed) {
|
|
127
|
+
Object.assign(argv, parsed);
|
|
128
|
+
return land(START, argv);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
yargsInstance.showHelp();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const provided = [];
|
|
136
|
+
for (const type of Object.keys(landActions)) {
|
|
137
|
+
if (argv[type]) {
|
|
138
|
+
provided.push(type);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (provided.length === 1) {
|
|
143
|
+
return land(provided[0], argv);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// If the more than one action is provided or no valid action
|
|
147
|
+
// is provided, show help.
|
|
148
|
+
yargsInstance.showHelp();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function land(state, argv) {
|
|
152
|
+
const cli = new CLI(process.stderr);
|
|
153
|
+
if (argv.yes) {
|
|
154
|
+
cli.setAssumeYes();
|
|
155
|
+
}
|
|
156
|
+
const dir = process.cwd();
|
|
157
|
+
|
|
158
|
+
return runPromise(main(state, argv, cli, dir)).catch((err) => {
|
|
159
|
+
if (cli.spinner.enabled) {
|
|
160
|
+
cli.spinner.fail();
|
|
161
|
+
}
|
|
162
|
+
throw err;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function main(state, argv, cli, dir) {
|
|
167
|
+
const credentials = await auth({
|
|
168
|
+
github: true
|
|
169
|
+
});
|
|
170
|
+
const req = new Request(credentials);
|
|
171
|
+
let session = new LandingSession(cli, req, dir);
|
|
172
|
+
|
|
173
|
+
if (state !== AMEND &&
|
|
174
|
+
state !== CONTINUE &&
|
|
175
|
+
await session.warnForWrongBranch()) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (argv.yes) {
|
|
180
|
+
cli.setAssumeYes();
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
session.restore();
|
|
184
|
+
} catch (err) { // JSON error?
|
|
185
|
+
if (state === ABORT) {
|
|
186
|
+
await session.abort();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
cli.warn(
|
|
190
|
+
'Failed to detect previous session. ' +
|
|
191
|
+
'please run `git node land --abort`');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (state === START) {
|
|
196
|
+
if (session.hasStarted()) {
|
|
197
|
+
cli.warn(
|
|
198
|
+
'Previous `git node land` session for ' +
|
|
199
|
+
`${session.pullName} in progress.`);
|
|
200
|
+
cli.log('run `git node land --abort` before starting a new session');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
session = new LandingSession(cli, req, dir, argv);
|
|
204
|
+
const metadata = await getMetadata(session.argv, argv.skipRefs, cli);
|
|
205
|
+
if (argv.backport) {
|
|
206
|
+
const split = metadata.metadata.split('\n')[0];
|
|
207
|
+
if (split === 'PR-URL: ') {
|
|
208
|
+
cli.error('Commit message is missing PR-URL');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return session.start(metadata);
|
|
212
|
+
} else if (state === APPLY) {
|
|
213
|
+
return session.apply();
|
|
214
|
+
} else if (state === AMEND) {
|
|
215
|
+
return session.amend();
|
|
216
|
+
} else if (state === FINAL) {
|
|
217
|
+
return session.final();
|
|
218
|
+
} else if (state === ABORT) {
|
|
219
|
+
return session.abort();
|
|
220
|
+
} else if (state === CONTINUE) {
|
|
221
|
+
return session.continue();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { parsePRFromURL } from '../../lib/links.js';
|
|
2
|
+
import { getMetadata } from '../metadata.js';
|
|
3
|
+
import CLI from '../../lib/cli.js';
|
|
4
|
+
import { getMergedConfig } from '../../lib/config.js';
|
|
5
|
+
import { runPromise, IGNORE } from '../../lib/run.js';
|
|
6
|
+
|
|
7
|
+
export const command = 'metadata <identifier>';
|
|
8
|
+
export const describe =
|
|
9
|
+
'Retrieves metadata for a PR and validates them against nodejs/node PR rules';
|
|
10
|
+
|
|
11
|
+
const config = getMergedConfig();
|
|
12
|
+
|
|
13
|
+
const options = {
|
|
14
|
+
owner: {
|
|
15
|
+
alias: 'o',
|
|
16
|
+
describe: 'GitHub owner of the PR repository',
|
|
17
|
+
default: 'nodejs',
|
|
18
|
+
type: 'string'
|
|
19
|
+
},
|
|
20
|
+
repo: {
|
|
21
|
+
default: 'node',
|
|
22
|
+
alias: 'r',
|
|
23
|
+
describe: 'GitHub repository of the PR',
|
|
24
|
+
type: 'string'
|
|
25
|
+
},
|
|
26
|
+
file: {
|
|
27
|
+
alias: 'f',
|
|
28
|
+
describe: 'File to write the metadata in',
|
|
29
|
+
type: 'string'
|
|
30
|
+
},
|
|
31
|
+
readme: {
|
|
32
|
+
describe: 'Path to file that contains collaborator contacts',
|
|
33
|
+
type: 'string'
|
|
34
|
+
},
|
|
35
|
+
'check-comments': {
|
|
36
|
+
describe: 'Check for \'LGTM\' in comments',
|
|
37
|
+
type: 'boolean'
|
|
38
|
+
},
|
|
39
|
+
'max-commits': {
|
|
40
|
+
describe: 'Number of commits to warn',
|
|
41
|
+
type: 'number',
|
|
42
|
+
default: 3
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
let yargsInstance;
|
|
47
|
+
|
|
48
|
+
export function builder(yargs) {
|
|
49
|
+
yargsInstance = yargs;
|
|
50
|
+
return yargs
|
|
51
|
+
.options(options)
|
|
52
|
+
.positional('identifier', {
|
|
53
|
+
type: 'string',
|
|
54
|
+
describe: 'ID or URL of the pull request'
|
|
55
|
+
})
|
|
56
|
+
.example('git node metadata 12344',
|
|
57
|
+
'Retrieve the metadata of https://github.com/nodejs/node/pull/12344 ' +
|
|
58
|
+
'and validate the PR')
|
|
59
|
+
.example('git node metadata https://github.com/nodejs/node/pull/12344',
|
|
60
|
+
'Retrieve the metadata of https://github.com/nodejs/node/pull/12344 ' +
|
|
61
|
+
'and validate it')
|
|
62
|
+
.example('git node metadata 167 --repo llnode --readme ../node/README.md',
|
|
63
|
+
'Retrieve the metadata of https://github.com/nodejs/llnode/pull/167 ' +
|
|
64
|
+
'and validate it using the README in ../node/README.md')
|
|
65
|
+
.wrap(90);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function handler(argv) {
|
|
69
|
+
let parsed = {};
|
|
70
|
+
const prid = Number.parseInt(argv.identifier);
|
|
71
|
+
if (!Number.isNaN(prid)) {
|
|
72
|
+
parsed.prid = prid;
|
|
73
|
+
} else {
|
|
74
|
+
parsed = parsePRFromURL(argv.identifier);
|
|
75
|
+
if (!parsed) {
|
|
76
|
+
return yargsInstance.showHelp();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!Number.isInteger(argv.maxCommits) || argv.maxCommits < 0) {
|
|
81
|
+
return yargsInstance.showHelp();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
|
85
|
+
const cli = new CLI(logStream);
|
|
86
|
+
|
|
87
|
+
const merged = Object.assign({}, argv, parsed, config);
|
|
88
|
+
return runPromise(getMetadata(merged, false, cli)
|
|
89
|
+
.then(({ status }) => {
|
|
90
|
+
if (status === false) {
|
|
91
|
+
throw new Error(IGNORE);
|
|
92
|
+
}
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import CLI from '../../lib/cli.js';
|
|
2
|
+
import ReleasePreparation from '../../lib/prepare_release.js';
|
|
3
|
+
import { runPromise } from '../../lib/run.js';
|
|
4
|
+
|
|
5
|
+
export const command = 'release [newVersion|options]';
|
|
6
|
+
export const describe = 'Manage an in-progress release or start a new one.';
|
|
7
|
+
|
|
8
|
+
const PREPARE = 'prepare';
|
|
9
|
+
const PROMOTE = 'promote';
|
|
10
|
+
|
|
11
|
+
const releaseOptions = {
|
|
12
|
+
prepare: {
|
|
13
|
+
describe: 'Prepare a new release of Node.js',
|
|
14
|
+
type: 'boolean'
|
|
15
|
+
},
|
|
16
|
+
promote: {
|
|
17
|
+
describe: 'Promote new release of Node.js',
|
|
18
|
+
type: 'boolean'
|
|
19
|
+
},
|
|
20
|
+
security: {
|
|
21
|
+
describe: 'Demarcate the new security release as a security release',
|
|
22
|
+
type: 'boolean'
|
|
23
|
+
},
|
|
24
|
+
filterLabel: {
|
|
25
|
+
describe: 'Labels separated by "," to filter security PRs',
|
|
26
|
+
type: 'string'
|
|
27
|
+
},
|
|
28
|
+
skipBranchDiff: {
|
|
29
|
+
describe: 'Skips the initial branch-diff check when preparing releases',
|
|
30
|
+
type: 'boolean'
|
|
31
|
+
},
|
|
32
|
+
startLTS: {
|
|
33
|
+
describe: 'Mark the release as the transition from Current to LTS',
|
|
34
|
+
type: 'boolean'
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
let yargsInstance;
|
|
39
|
+
|
|
40
|
+
export function builder(yargs) {
|
|
41
|
+
yargsInstance = yargs;
|
|
42
|
+
return yargs
|
|
43
|
+
.options(releaseOptions).positional('newVersion', {
|
|
44
|
+
describe: 'Version number of the release to be prepared or promoted'
|
|
45
|
+
})
|
|
46
|
+
.example('git node release --prepare 1.2.3',
|
|
47
|
+
'Prepare a release of Node.js tagged v1.2.3')
|
|
48
|
+
.example('git node --prepare --startLTS',
|
|
49
|
+
'Prepare the first LTS release');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function handler(argv) {
|
|
53
|
+
if (argv.prepare) {
|
|
54
|
+
return release(PREPARE, argv);
|
|
55
|
+
} else if (argv.promote) {
|
|
56
|
+
return release(PROMOTE, argv);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// If more than one action is provided or no valid action
|
|
60
|
+
// is provided, show help.
|
|
61
|
+
yargsInstance.showHelp();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function release(state, argv) {
|
|
65
|
+
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
|
66
|
+
const cli = new CLI(logStream);
|
|
67
|
+
const dir = process.cwd();
|
|
68
|
+
|
|
69
|
+
return runPromise(main(state, argv, cli, dir)).catch((err) => {
|
|
70
|
+
if (cli.spinner.enabled) {
|
|
71
|
+
cli.spinner.fail();
|
|
72
|
+
}
|
|
73
|
+
throw err;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function main(state, argv, cli, dir) {
|
|
78
|
+
if (state === PREPARE) {
|
|
79
|
+
const prep = new ReleasePreparation(argv, cli, dir);
|
|
80
|
+
|
|
81
|
+
if (prep.warnForWrongBranch()) return;
|
|
82
|
+
|
|
83
|
+
// If the new version was automatically calculated, confirm it.
|
|
84
|
+
if (!argv.newVersion) {
|
|
85
|
+
const create = await cli.prompt(
|
|
86
|
+
`Create release with new version ${prep.newVersion}?`,
|
|
87
|
+
{ defaultAnswer: true });
|
|
88
|
+
|
|
89
|
+
if (!create) {
|
|
90
|
+
cli.error('Aborting release preparation process');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return prep.prepare();
|
|
96
|
+
} else if (state === PROMOTE) {
|
|
97
|
+
// TODO(codebytere): implement release promotion.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import CLI from '../../lib/cli.js';
|
|
2
|
+
import SecurityReleaseSteward from '../../lib/prepare_security.js';
|
|
3
|
+
|
|
4
|
+
export const command = 'security [options]';
|
|
5
|
+
export const describe = 'Manage an in-progress security release or start a new one.';
|
|
6
|
+
|
|
7
|
+
const securityOptions = {
|
|
8
|
+
start: {
|
|
9
|
+
describe: 'Start security release process',
|
|
10
|
+
type: 'boolean'
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let yargsInstance;
|
|
15
|
+
|
|
16
|
+
export function builder(yargs) {
|
|
17
|
+
yargsInstance = yargs;
|
|
18
|
+
return yargs.options(securityOptions).example(
|
|
19
|
+
'git node security --start',
|
|
20
|
+
'Prepare a security release of Node.js');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function handler(argv) {
|
|
24
|
+
if (argv.start) {
|
|
25
|
+
return startSecurityRelease(argv);
|
|
26
|
+
}
|
|
27
|
+
yargsInstance.showHelp();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function startSecurityRelease(argv) {
|
|
31
|
+
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
|
32
|
+
const cli = new CLI(logStream);
|
|
33
|
+
const release = new SecurityReleaseSteward(cli);
|
|
34
|
+
return release.start();
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
|
|
4
|
+
import { readJson } from './../../lib/file.js';
|
|
5
|
+
import { getNcuDir } from './../../lib/config.js';
|
|
6
|
+
import CLI from '../../lib/cli.js';
|
|
7
|
+
|
|
8
|
+
const cli = new CLI();
|
|
9
|
+
|
|
10
|
+
export const command = 'status';
|
|
11
|
+
export const describe =
|
|
12
|
+
'Return status and information about the current git-node land session.';
|
|
13
|
+
|
|
14
|
+
export function handler() {
|
|
15
|
+
const ncuDir = getNcuDir(process.cwd());
|
|
16
|
+
const landPath = path.join(ncuDir, 'land');
|
|
17
|
+
|
|
18
|
+
if (fs.existsSync(landPath)) {
|
|
19
|
+
const { state, prid, config } = readJson(landPath);
|
|
20
|
+
const { username, branch, upstream } = config;
|
|
21
|
+
|
|
22
|
+
cli.ok('Landing session in progress');
|
|
23
|
+
cli.separator();
|
|
24
|
+
cli.table('PR:', `https:/github.com/nodejs/node/pull/${prid}`);
|
|
25
|
+
cli.table('State:', state);
|
|
26
|
+
cli.table('Username:', username);
|
|
27
|
+
cli.table('Upstream:', upstream);
|
|
28
|
+
cli.table('Branch:', branch);
|
|
29
|
+
} else {
|
|
30
|
+
cli.warn('No landing session in progress');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import CLI from '../../lib/cli.js';
|
|
2
|
+
import { runPromise } from '../../lib/run.js';
|
|
3
|
+
import SyncSession from '../../lib/sync_session.js';
|
|
4
|
+
|
|
5
|
+
export const command = 'sync';
|
|
6
|
+
export const describe = 'Sync the branch specified by ncu-config.';
|
|
7
|
+
|
|
8
|
+
export function builder(yargs) {
|
|
9
|
+
return yargs
|
|
10
|
+
.epilogue('Demo: https://asciinema.org/a/221230')
|
|
11
|
+
.wrap(90);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function main() {
|
|
15
|
+
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
|
16
|
+
const cli = new CLI(logStream);
|
|
17
|
+
const dir = process.cwd();
|
|
18
|
+
const session = new SyncSession(cli, dir);
|
|
19
|
+
await session.sync();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function handler(argv) {
|
|
23
|
+
return runPromise(main());
|
|
24
|
+
}
|