@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
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import logSymbols from 'log-symbols';
|
|
4
|
+
|
|
5
|
+
import { minor, major, backport } from '../../lib/update-v8/index.js';
|
|
6
|
+
import { defaultBaseDir } from '../../lib/update-v8/constants.js';
|
|
7
|
+
import { checkCwd } from '../../lib/update-v8/common.js';
|
|
8
|
+
import { forceRunAsync } from '../../lib/run.js';
|
|
9
|
+
|
|
10
|
+
export const command = 'v8 [major|minor|backport]';
|
|
11
|
+
export const describe = 'Update or patch the V8 engine';
|
|
12
|
+
|
|
13
|
+
export function builder(yargs) {
|
|
14
|
+
yargs
|
|
15
|
+
.command({
|
|
16
|
+
command: 'major',
|
|
17
|
+
desc: 'Do a major upgrade. Replaces the whole deps/v8 directory',
|
|
18
|
+
handler,
|
|
19
|
+
builder: (yargs) => {
|
|
20
|
+
yargs.option('branch', {
|
|
21
|
+
describe: 'Branch of the V8 repository to use for the upgrade',
|
|
22
|
+
default: 'lkgr'
|
|
23
|
+
});
|
|
24
|
+
yargs.option('version-bump', {
|
|
25
|
+
describe: 'Bump the NODE_MODULE_VERSION constant',
|
|
26
|
+
default: true
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
.command({
|
|
31
|
+
command: 'minor',
|
|
32
|
+
desc: 'Do a minor patch of the current V8 version',
|
|
33
|
+
handler
|
|
34
|
+
})
|
|
35
|
+
.command({
|
|
36
|
+
command: 'backport <sha..>',
|
|
37
|
+
desc: 'Backport one or more commits from the V8 repository',
|
|
38
|
+
handler,
|
|
39
|
+
builder: (yargs) => {
|
|
40
|
+
yargs
|
|
41
|
+
.option('bump', {
|
|
42
|
+
describe: 'Bump V8 embedder version number or patch version',
|
|
43
|
+
default: true
|
|
44
|
+
})
|
|
45
|
+
.option('squash', {
|
|
46
|
+
describe:
|
|
47
|
+
'If multiple commits are backported, squash them into one',
|
|
48
|
+
default: false
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
.demandCommand(1, 'Please provide a valid command')
|
|
53
|
+
.option('node-dir', {
|
|
54
|
+
describe: 'Directory of a Node.js clone',
|
|
55
|
+
default: process.cwd()
|
|
56
|
+
})
|
|
57
|
+
.option('base-dir', {
|
|
58
|
+
describe: 'Directory where V8 should be cloned',
|
|
59
|
+
default: defaultBaseDir
|
|
60
|
+
})
|
|
61
|
+
.option('v8-dir', {
|
|
62
|
+
describe: 'Directory of an existing V8 clone'
|
|
63
|
+
})
|
|
64
|
+
.option('verbose', {
|
|
65
|
+
describe: 'Enable verbose output',
|
|
66
|
+
boolean: true,
|
|
67
|
+
default: false
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function handler(argv) {
|
|
72
|
+
const options = Object.assign({}, argv);
|
|
73
|
+
options.nodeDir = path.resolve(options.nodeDir);
|
|
74
|
+
options.baseDir = path.resolve(options.baseDir);
|
|
75
|
+
if (!options.v8Dir) {
|
|
76
|
+
options.v8Dir = path.join(options.baseDir, 'v8');
|
|
77
|
+
} else {
|
|
78
|
+
options.v8Dir = path.resolve(options.v8Dir);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
options.execGitNode = function execGitNode(cmd, args, input) {
|
|
82
|
+
args.unshift(cmd);
|
|
83
|
+
return forceRunAsync('git', args, {
|
|
84
|
+
input,
|
|
85
|
+
spawnArgs: {
|
|
86
|
+
cwd: options.nodeDir,
|
|
87
|
+
stdio: input ? ['pipe', 'ignore', 'ignore'] : 'ignore'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
options.execGitV8 = function execGitV8(...args) {
|
|
93
|
+
return forceRunAsync('git', args, {
|
|
94
|
+
captureStdout: true,
|
|
95
|
+
spawnArgs: { cwd: options.v8Dir, stdio: ['ignore', 'pipe', 'ignore'] }
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
Promise.resolve()
|
|
100
|
+
.then(async() => {
|
|
101
|
+
await checkCwd(options);
|
|
102
|
+
// First element of argv is 'v8'
|
|
103
|
+
const kind = argv._[1];
|
|
104
|
+
options[kind] = true;
|
|
105
|
+
switch (kind) {
|
|
106
|
+
case 'minor':
|
|
107
|
+
return minor(options);
|
|
108
|
+
case 'major':
|
|
109
|
+
return major(options);
|
|
110
|
+
case 'backport':
|
|
111
|
+
return backport(options);
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
.catch((err) => {
|
|
115
|
+
console.error(
|
|
116
|
+
logSymbols.error,
|
|
117
|
+
options.verbose ? err.stack : err.message
|
|
118
|
+
);
|
|
119
|
+
process.exitCode = 1;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import auth from '../../lib/auth.js';
|
|
2
|
+
import { parsePRFromURL } from '../../lib/links.js';
|
|
3
|
+
import CLI from '../../lib/cli.js';
|
|
4
|
+
import Request from '../../lib/request.js';
|
|
5
|
+
import { runPromise } from '../../lib/run.js';
|
|
6
|
+
import VotingSession from '../../lib/voting_session.js';
|
|
7
|
+
|
|
8
|
+
export const command = 'vote [prid|options]';
|
|
9
|
+
export const describe =
|
|
10
|
+
'Cast a vote, or decrypt a key part to close a vote';
|
|
11
|
+
|
|
12
|
+
const voteOptions = {
|
|
13
|
+
abstain: {
|
|
14
|
+
type: 'boolean',
|
|
15
|
+
default: false,
|
|
16
|
+
describe: 'Abstain from the vote.'
|
|
17
|
+
},
|
|
18
|
+
'decrypt-key-part': {
|
|
19
|
+
describe: 'Publish a key part as a comment to the vote PR.',
|
|
20
|
+
default: false,
|
|
21
|
+
type: 'boolean'
|
|
22
|
+
},
|
|
23
|
+
'gpg-sign': {
|
|
24
|
+
describe: 'GPG-sign commits, will be passed to the git process',
|
|
25
|
+
alias: 'S'
|
|
26
|
+
},
|
|
27
|
+
'post-comment': {
|
|
28
|
+
describe: 'Post the comment on GitHub on the behalf of the user',
|
|
29
|
+
default: false,
|
|
30
|
+
type: 'boolean'
|
|
31
|
+
},
|
|
32
|
+
protocol: {
|
|
33
|
+
describe: 'The protocol to use to clone the vote repository and push the eventual vote commit',
|
|
34
|
+
type: 'string'
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
let yargsInstance;
|
|
39
|
+
|
|
40
|
+
export function builder(yargs) {
|
|
41
|
+
yargsInstance = yargs;
|
|
42
|
+
return yargs
|
|
43
|
+
.options(voteOptions)
|
|
44
|
+
.positional('prid', {
|
|
45
|
+
describe: 'URL of the vote Pull Request'
|
|
46
|
+
})
|
|
47
|
+
.example('git node vote https://github.com/nodejs/TSC/pull/12344',
|
|
48
|
+
'Start an interactive session to cast ballot for https://github.com/nodejs/TSC/pull/12344.')
|
|
49
|
+
.example('git node vote https://github.com/nodejs/TSC/pull/12344 --abstain',
|
|
50
|
+
'Cast an empty ballot for https://github.com/nodejs/TSC/pull/12344.')
|
|
51
|
+
.example('git node vote https://github.com/nodejs/TSC/pull/12344 --decrypt-key-part',
|
|
52
|
+
'Uses gpg to decrypt a key part to close the vote happening on https://github.com/nodejs/TSC/pull/12344.');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function handler(argv) {
|
|
56
|
+
if (argv.prid) {
|
|
57
|
+
const parsed = parsePRFromURL(argv.prid);
|
|
58
|
+
if (parsed) {
|
|
59
|
+
Object.assign(argv, parsed);
|
|
60
|
+
return vote(argv);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
yargsInstance.showHelp();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function vote(argv) {
|
|
67
|
+
const cli = new CLI(process.stderr);
|
|
68
|
+
const dir = process.cwd();
|
|
69
|
+
|
|
70
|
+
return runPromise(main(argv, cli, dir)).catch((err) => {
|
|
71
|
+
if (cli.spinner.enabled) {
|
|
72
|
+
cli.spinner.fail();
|
|
73
|
+
}
|
|
74
|
+
throw err;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function main(argv, cli, dir) {
|
|
79
|
+
const credentials = await auth({ github: true });
|
|
80
|
+
const req = new Request(credentials);
|
|
81
|
+
const session = new VotingSession(cli, req, dir, argv);
|
|
82
|
+
|
|
83
|
+
return session.start();
|
|
84
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import Request from '../../lib/request.js';
|
|
5
|
+
import CLI from '../../lib/cli.js';
|
|
6
|
+
import auth from '../../lib/auth.js';
|
|
7
|
+
import {
|
|
8
|
+
WPTUpdater,
|
|
9
|
+
ResourcesUpdater,
|
|
10
|
+
InterfacesUpdater
|
|
11
|
+
} from '../../lib/wpt/index.js';
|
|
12
|
+
import { runPromise } from '../../lib/run.js';
|
|
13
|
+
|
|
14
|
+
export const command = 'wpt <name>';
|
|
15
|
+
export const describe = 'Updates WPT suite';
|
|
16
|
+
|
|
17
|
+
export function builder(yargs) {
|
|
18
|
+
return yargs
|
|
19
|
+
.positional('name', {
|
|
20
|
+
describe: 'Subset of the WPT to update',
|
|
21
|
+
type: 'string'
|
|
22
|
+
})
|
|
23
|
+
.options({
|
|
24
|
+
commit: {
|
|
25
|
+
describe: 'A specific commit the subset should be updated to',
|
|
26
|
+
type: 'string',
|
|
27
|
+
default: undefined
|
|
28
|
+
},
|
|
29
|
+
nodedir: {
|
|
30
|
+
describe: 'Path to the node.js project directory',
|
|
31
|
+
type: 'string',
|
|
32
|
+
default: '.'
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function main(argv) {
|
|
38
|
+
const { name, nodedir, commit } = argv;
|
|
39
|
+
const cli = new CLI();
|
|
40
|
+
const credentials = await auth({
|
|
41
|
+
github: true
|
|
42
|
+
});
|
|
43
|
+
const request = new Request(credentials);
|
|
44
|
+
|
|
45
|
+
const updaters = [];
|
|
46
|
+
|
|
47
|
+
const statusFolder = path.join(nodedir, 'test', 'wpt', 'status');
|
|
48
|
+
let supported = [
|
|
49
|
+
'dom',
|
|
50
|
+
'html'
|
|
51
|
+
];
|
|
52
|
+
if (fs.existsSync(statusFolder)) {
|
|
53
|
+
const jsons = fs.readdirSync(statusFolder);
|
|
54
|
+
supported = supported.concat(
|
|
55
|
+
jsons.map(item => item.replace('.json', '')));
|
|
56
|
+
} else {
|
|
57
|
+
cli.warn(`Please create the status JSON files in ${statusFolder}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (name === 'all' || name === 'resources') {
|
|
61
|
+
updaters.push(new ResourcesUpdater(cli, request, nodedir, commit));
|
|
62
|
+
}
|
|
63
|
+
if (name === 'all' || name === 'interfaces') {
|
|
64
|
+
updaters.push(new InterfacesUpdater(cli, request, nodedir,
|
|
65
|
+
commit, supported));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (name === 'all') {
|
|
69
|
+
for (const item of supported) {
|
|
70
|
+
updaters.push(new WPTUpdater(item, cli, request, nodedir, commit));
|
|
71
|
+
}
|
|
72
|
+
} else if (name !== 'resources' && name !== 'interfaces') {
|
|
73
|
+
if (!supported.includes(name)) {
|
|
74
|
+
cli.warn(`Please create ${name}.json in ${statusFolder}`);
|
|
75
|
+
}
|
|
76
|
+
updaters.push(new WPTUpdater(name, cli, request, nodedir, commit));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const updater of updaters) {
|
|
80
|
+
await updater.update();
|
|
81
|
+
}
|
|
82
|
+
updaters[0].updateLicense();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function handler(argv) {
|
|
86
|
+
runPromise(main(argv));
|
|
87
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import Request from '../lib/request.js';
|
|
4
|
+
import auth from '../lib/auth.js';
|
|
5
|
+
import PRData from '../lib/pr_data.js';
|
|
6
|
+
import PRSummary from '../lib/pr_summary.js';
|
|
7
|
+
import PRChecker from '../lib/pr_checker.js';
|
|
8
|
+
import MetadataGenerator from '../lib/metadata_gen.js';
|
|
9
|
+
|
|
10
|
+
export async function getMetadata(argv, skipRefs, cli) {
|
|
11
|
+
const credentials = await auth({
|
|
12
|
+
github: true,
|
|
13
|
+
jenkins: true
|
|
14
|
+
});
|
|
15
|
+
const request = new Request(credentials);
|
|
16
|
+
|
|
17
|
+
const data = new PRData(argv, cli, request);
|
|
18
|
+
await data.getAll();
|
|
19
|
+
|
|
20
|
+
const summary = new PRSummary(argv, cli, data);
|
|
21
|
+
cli.separator('PR info');
|
|
22
|
+
summary.display();
|
|
23
|
+
|
|
24
|
+
const metadata = new MetadataGenerator({ skipRefs, ...data }).getMetadata();
|
|
25
|
+
if (!process.stdout.isTTY) {
|
|
26
|
+
process.stdout.write(metadata);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (argv.file) {
|
|
30
|
+
cli.separator();
|
|
31
|
+
cli.startSpinner(`Writing metadata to ${argv.file}..`);
|
|
32
|
+
fs.writeFileSync(argv.file, metadata);
|
|
33
|
+
cli.stopSpinner(`Done writing metadata to ${argv.file}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
cli.separator('Generated metadata');
|
|
37
|
+
cli.write(metadata);
|
|
38
|
+
cli.separator();
|
|
39
|
+
|
|
40
|
+
const checker = new PRChecker(cli, data, request, argv);
|
|
41
|
+
const status = await checker.checkAll(argv.checkComments, argv.checkCI);
|
|
42
|
+
return {
|
|
43
|
+
status,
|
|
44
|
+
request,
|
|
45
|
+
data,
|
|
46
|
+
metadata,
|
|
47
|
+
checker
|
|
48
|
+
};
|
|
49
|
+
};
|
package/lib/auth.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { ClientRequest } from 'node:http';
|
|
3
|
+
|
|
4
|
+
import ghauth from 'ghauth';
|
|
5
|
+
|
|
6
|
+
import { getMergedConfig, getNcurcPath } from './config.js';
|
|
7
|
+
|
|
8
|
+
export default lazy(auth);
|
|
9
|
+
|
|
10
|
+
function errorExit(message) {
|
|
11
|
+
process.stderr.write(`${message}\n`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function check(username, token) {
|
|
16
|
+
if (typeof username !== 'string') {
|
|
17
|
+
errorExit(`username must be a string, received ${typeof username}`);
|
|
18
|
+
}
|
|
19
|
+
if (!/^[a-zA-Z0-9-]+$/.test(username)) {
|
|
20
|
+
errorExit(
|
|
21
|
+
'username may only contain alphanumeric characters or hyphens, ' +
|
|
22
|
+
`received ${username}`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
if (typeof token !== 'string') {
|
|
26
|
+
errorExit(`token must be a string, received ${typeof token}`);
|
|
27
|
+
}
|
|
28
|
+
if (!/^[A-Za-z0-9_]+$/.test(token)) {
|
|
29
|
+
errorExit(`token is misformatted: ${token}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function lazy(fn) {
|
|
34
|
+
let cachedValue;
|
|
35
|
+
return function(...args) {
|
|
36
|
+
if (cachedValue !== undefined) {
|
|
37
|
+
return cachedValue;
|
|
38
|
+
}
|
|
39
|
+
cachedValue = fn(...args);
|
|
40
|
+
return cachedValue;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function tryCreateGitHubToken(githubAuth) {
|
|
45
|
+
let credentials;
|
|
46
|
+
try {
|
|
47
|
+
credentials = await githubAuth({
|
|
48
|
+
noSave: true,
|
|
49
|
+
scopes: ['user:email', 'read:org'],
|
|
50
|
+
note: 'node-core-utils CLI tools',
|
|
51
|
+
noDeviceFlow: true
|
|
52
|
+
});
|
|
53
|
+
} catch (e) {
|
|
54
|
+
errorExit(`Could not get token: ${e.message}`);
|
|
55
|
+
}
|
|
56
|
+
return credentials;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function encode(name, token) {
|
|
60
|
+
return Buffer.from(`${name}:${token}`).toString('base64');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// TODO: support jenkins only...or not necessary?
|
|
64
|
+
// TODO: make this a class with dependency (CLI) injectable for testing
|
|
65
|
+
async function auth(
|
|
66
|
+
options = { github: true },
|
|
67
|
+
githubAuth = ghauth) {
|
|
68
|
+
const result = {};
|
|
69
|
+
if (options.github) {
|
|
70
|
+
let username;
|
|
71
|
+
let token;
|
|
72
|
+
try {
|
|
73
|
+
({ username, token } = getMergedConfig());
|
|
74
|
+
} catch (e) {
|
|
75
|
+
// Ignore error and prompt
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!username || !token) {
|
|
79
|
+
process.stdout.write(
|
|
80
|
+
'If this is your first time running this command, ' +
|
|
81
|
+
'follow the instructions to create an access token' +
|
|
82
|
+
'. If you prefer to create it yourself on Github, ' +
|
|
83
|
+
'see https://github.com/nodejs/node-core-utils/blob/main/README.md.\n');
|
|
84
|
+
const credentials = await tryCreateGitHubToken(githubAuth);
|
|
85
|
+
username = credentials.user;
|
|
86
|
+
token = credentials.token;
|
|
87
|
+
const json = JSON.stringify({ username, token }, null, 2);
|
|
88
|
+
fs.writeFileSync(getNcurcPath(), json, {
|
|
89
|
+
mode: 0o600 /* owner read/write */
|
|
90
|
+
});
|
|
91
|
+
// Try again reading the file
|
|
92
|
+
({ username, token } = getMergedConfig());
|
|
93
|
+
}
|
|
94
|
+
check(username, token);
|
|
95
|
+
result.github = encode(username, token);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (options.jenkins) {
|
|
99
|
+
const { username, jenkins_token } = getMergedConfig();
|
|
100
|
+
if (!username || !jenkins_token) {
|
|
101
|
+
errorExit(
|
|
102
|
+
'Get your Jenkins API token in https://ci.nodejs.org/me/configure ' +
|
|
103
|
+
'and run the following command to add it to your ncu config: ' +
|
|
104
|
+
'ncu-config --global set jenkins_token TOKEN'
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
check(username, jenkins_token);
|
|
108
|
+
result.jenkins = encode(username, jenkins_token);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (options.h1) {
|
|
112
|
+
const { h1_username, h1_token } = getMergedConfig();
|
|
113
|
+
if (!h1_username || !h1_token) {
|
|
114
|
+
errorExit(
|
|
115
|
+
'Get your HackerOne API token in ' +
|
|
116
|
+
'https://docs.hackerone.com/organizations/api-tokens.html ' +
|
|
117
|
+
'and run the following command to add it to your ncu config: ' +
|
|
118
|
+
'ncu-config --global set h1_token TOKEN or ' +
|
|
119
|
+
'ncu-config --global set h1_username USERNAME'
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
result.h1 = encode(h1_username, h1_token);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// This is an ugly hack to get around a bug in hyperquest & ghauth
|
|
128
|
+
// which are not currently maintained
|
|
129
|
+
const originalSetTimeout = ClientRequest.prototype.setTimeout;
|
|
130
|
+
ClientRequest.prototype.setTimeout = function(msecs, ...args) {
|
|
131
|
+
msecs = Math.min(msecs, Math.pow(2, 31) - 1);
|
|
132
|
+
return originalSetTimeout.call(this, msecs, ...args);
|
|
133
|
+
};
|