@node-core/utils 5.10.0 → 5.12.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/bin/git-node.js +2 -0
- package/bin/ncu-ci.js +3 -3
- package/components/git/metadata.js +1 -0
- package/components/git/release.js +3 -2
- package/lib/ci/build-types/health_build.js +4 -4
- package/lib/ci/build-types/test_build.js +2 -0
- package/lib/ci/ci_failure_parser.js +0 -1
- package/lib/ci/run_ci.js +2 -1
- package/lib/cli.js +1 -0
- package/lib/collaborators.js +0 -2
- package/lib/pr_checker.js +19 -53
- package/lib/pr_data.js +0 -10
- package/lib/prepare_release.js +12 -10
- package/lib/prepare_security.js +18 -14
- package/lib/promote_release.js +26 -15
- package/lib/queries/PR.gql +0 -3
- package/lib/release/utils.js +0 -2
- package/lib/request.js +9 -5
- package/lib/run.js +14 -3
- package/lib/security-release/security-release.js +1 -1
- package/lib/team_info.js +0 -1
- package/lib/update-v8/constants.js +6 -0
- package/lib/update-v8/majorUpdate.js +0 -2
- package/lib/voting_session.js +2 -1
- package/package.json +10 -7
- package/lib/queries/PRLabeledEvents.gql +0 -19
package/bin/git-node.js
CHANGED
package/bin/ncu-ci.js
CHANGED
@@ -115,9 +115,9 @@ const args = yargs(hideBin(process.argv))
|
|
115
115
|
type: 'number'
|
116
116
|
})
|
117
117
|
.positional('certify-safe', {
|
118
|
-
describe: '
|
119
|
-
'
|
120
|
-
type: '
|
118
|
+
describe: 'SHA of the commit that is expected to be at the tip of the PR head. ' +
|
119
|
+
'If not provided, the command will use the SHA of the last approved commit.',
|
120
|
+
type: 'string'
|
121
121
|
})
|
122
122
|
.option('owner', {
|
123
123
|
default: '',
|
@@ -112,9 +112,10 @@ function release(state, argv) {
|
|
112
112
|
}
|
113
113
|
|
114
114
|
async function main(state, argv, cli, dir) {
|
115
|
-
const prID = /^(?:https:\/\/github\.com\/nodejs
|
115
|
+
const prID = /^(?:https:\/\/github\.com\/nodejs(-private)?\/node\1\/pull\/)?(\d+)$/.exec(argv.prid);
|
116
116
|
if (prID) {
|
117
|
-
|
117
|
+
if (prID[1]) argv.security = true;
|
118
|
+
argv.prid = Number(prID[2]);
|
118
119
|
}
|
119
120
|
if (state === PREPARE) {
|
120
121
|
const release = new ReleasePreparation(argv, cli, dir);
|
@@ -20,10 +20,10 @@ class Health {
|
|
20
20
|
formatAsMarkdown() {
|
21
21
|
const { success, pending, aborted, failed, unstable, count } = this;
|
22
22
|
const rate = `${(success / (count - pending - aborted) * 100).toFixed(2)}%`;
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
let result =
|
24
|
+
'| UTC Time | RUNNING | SUCCESS | UNSTABLE | ABORTED | FAILURE | Green Rate |\n';
|
25
|
+
result +=
|
26
|
+
'| ---------------- | ------- | ------- | -------- | ------- | ------- | ---------- |\n';
|
27
27
|
const time = new Date().toISOString().slice(0, 16).replace('T', ' ');
|
28
28
|
result += `| ${time} | ${pad(pending, 7)} | ${pad(success, 8)}|`;
|
29
29
|
result += ` ${pad(unstable, 8)} | ${pad(aborted, 7)} | ${pad(failed, 7)} |`;
|
@@ -204,7 +204,6 @@ const FAILURE_FILTERS = [{
|
|
204
204
|
context: { index: 0, contextBefore: 0, contextAfter: 0 }
|
205
205
|
}, {
|
206
206
|
pattern:
|
207
|
-
// eslint-disable-next-line max-len
|
208
207
|
/error: Your local changes to the following files[\s\S]+Failed to merge in the changes./g,
|
209
208
|
context: { index: 0, contextBefore: 0, contextAfter: 0 }
|
210
209
|
}, {
|
package/lib/ci/run_ci.js
CHANGED
@@ -27,7 +27,7 @@ export class RunPRJob {
|
|
27
27
|
this.certifySafe =
|
28
28
|
certifySafe ||
|
29
29
|
Promise.all([this.prData.getReviews(), this.prData.getPR()]).then(() =>
|
30
|
-
new PRChecker(cli, this.prData, request, {}).
|
30
|
+
(this.certifySafe = new PRChecker(cli, this.prData, request, {}).getApprovedTipOfHead())
|
31
31
|
);
|
32
32
|
}
|
33
33
|
|
@@ -45,6 +45,7 @@ export class RunPRJob {
|
|
45
45
|
payload.append('json', JSON.stringify({
|
46
46
|
parameter: [
|
47
47
|
{ name: 'CERTIFY_SAFE', value: 'on' },
|
48
|
+
{ name: 'COMMIT_SHA_CHECK', value: this.certifySafe },
|
48
49
|
{ name: 'TARGET_GITHUB_ORG', value: this.owner },
|
49
50
|
{ name: 'TARGET_REPO_NAME', value: this.repo },
|
50
51
|
{ name: 'PR_ID', value: this.prid },
|
package/lib/cli.js
CHANGED
package/lib/collaborators.js
CHANGED
@@ -105,7 +105,6 @@ function parseCollaborators(readme, cli) {
|
|
105
105
|
|
106
106
|
// We also assume that TSC & TSC Emeriti are also listed as collaborators
|
107
107
|
CONTACT_RE.lastIndex = tscIndex;
|
108
|
-
// eslint-disable-next-line no-cond-assign
|
109
108
|
while ((m = CONTACT_RE.exec(readme)) && CONTACT_RE.lastIndex < tscrIndex) {
|
110
109
|
const login = m[1].toLowerCase();
|
111
110
|
const user = new Collaborator(m[1], m[2], m[3], TSC);
|
@@ -113,7 +112,6 @@ function parseCollaborators(readme, cli) {
|
|
113
112
|
}
|
114
113
|
|
115
114
|
CONTACT_RE.lastIndex = clIndex;
|
116
|
-
// eslint-disable-next-line no-cond-assign
|
117
115
|
while ((m = CONTACT_RE.exec(readme)) &&
|
118
116
|
CONTACT_RE.lastIndex < cleIndex) {
|
119
117
|
const login = m[1].toLowerCase();
|
package/lib/pr_checker.js
CHANGED
@@ -524,38 +524,17 @@ export default class PRChecker {
|
|
524
524
|
return true;
|
525
525
|
}
|
526
526
|
|
527
|
-
|
528
|
-
if (this.checkCommitsAfterReview()) return true;
|
529
|
-
|
530
|
-
await Promise.all([this.data.getLabeledEvents(), this.data.getCollaborators()]);
|
531
|
-
|
532
|
-
const {
|
533
|
-
cli, data, pr
|
534
|
-
} = this;
|
535
|
-
|
536
|
-
const { updatedAt } = pr.timelineItems;
|
537
|
-
const requestCiLabels = data.labeledEvents.findLast(
|
538
|
-
({ createdAt, label: { name } }) => name === 'request-ci' && createdAt > updatedAt
|
539
|
-
);
|
540
|
-
if (requestCiLabels == null) return false;
|
541
|
-
|
542
|
-
const { actor: { login } } = requestCiLabels;
|
543
|
-
const collaborators = Array.from(data.collaborators.values(),
|
544
|
-
(c) => c.login.toLowerCase());
|
545
|
-
if (collaborators.includes(login.toLowerCase())) {
|
546
|
-
cli.info('request-ci label was added by a Collaborator after the last push event.');
|
547
|
-
return true;
|
548
|
-
}
|
549
|
-
|
550
|
-
return false;
|
551
|
-
}
|
552
|
-
|
553
|
-
checkCommitsAfterReview() {
|
527
|
+
getApprovedTipOfHead() {
|
554
528
|
const {
|
555
529
|
commits, reviews, cli, argv
|
556
530
|
} = this;
|
557
531
|
const { maxCommits } = argv;
|
558
532
|
|
533
|
+
if (commits.length === 0) {
|
534
|
+
cli.warn('No commits found');
|
535
|
+
return false;
|
536
|
+
}
|
537
|
+
|
559
538
|
const reviewIndex = reviews.findLastIndex(
|
560
539
|
review => review.authorCanPushToRepository && review.state === 'APPROVED'
|
561
540
|
);
|
@@ -565,45 +544,32 @@ export default class PRChecker {
|
|
565
544
|
return false;
|
566
545
|
}
|
567
546
|
|
568
|
-
const
|
569
|
-
|
570
|
-
const afterCommits = [];
|
571
|
-
commits.forEach((commit) => {
|
572
|
-
commit = commit.commit;
|
573
|
-
if (commit.committedDate > reviewDate) {
|
574
|
-
afterCommits.push(commit);
|
575
|
-
}
|
576
|
-
});
|
577
|
-
|
578
|
-
const totalCommits = afterCommits.length;
|
579
|
-
if (totalCommits === 0 && this.pr.timelineItems.updatedAt > reviewDate) {
|
580
|
-
// Some commits were pushed, but all the commits have a commit date prior
|
581
|
-
// to the last review. It means that either that a long time elapsed
|
582
|
-
// between the commit and the push, or that the clock on the dev machine
|
583
|
-
// is wrong, or the commit date was forged.
|
584
|
-
cli.warn('Something was pushed to the Pull Request branch since the last approving review.');
|
585
|
-
return false;
|
586
|
-
}
|
547
|
+
const reviewedCommitIndex = commits
|
548
|
+
.findLastIndex(({ commit }) => commit.oid === reviews[reviewIndex].commit.oid);
|
587
549
|
|
588
|
-
if (
|
550
|
+
if (reviewedCommitIndex !== commits.length - 1) {
|
589
551
|
cli.warn('Commits were pushed since the last approving review:');
|
590
|
-
|
591
|
-
|
592
|
-
.forEach(commit => {
|
552
|
+
commits.slice(Math.max(reviewedCommitIndex + 1, commits.length - maxCommits))
|
553
|
+
.forEach(({ commit }) => {
|
593
554
|
cli.warn(`- ${commit.messageHeadline}`);
|
594
555
|
});
|
595
556
|
|
557
|
+
const totalCommits = commits.length - reviewedCommitIndex - 1;
|
596
558
|
if (totalCommits > maxCommits) {
|
597
559
|
const infoMsg = '...(use `' +
|
598
|
-
|
599
|
-
|
560
|
+
`--max-commits ${totalCommits}` +
|
561
|
+
'` to see the full list of commits)';
|
600
562
|
cli.warn(infoMsg);
|
601
563
|
}
|
602
564
|
|
603
565
|
return false;
|
604
566
|
}
|
605
567
|
|
606
|
-
return
|
568
|
+
return reviews[reviewIndex].commit.oid;
|
569
|
+
}
|
570
|
+
|
571
|
+
checkCommitsAfterReview() {
|
572
|
+
return !!this.getApprovedTipOfHead();
|
607
573
|
}
|
608
574
|
|
609
575
|
checkMergeableState() {
|
package/lib/pr_data.js
CHANGED
@@ -5,7 +5,6 @@ import {
|
|
5
5
|
} from './user_status.js';
|
6
6
|
|
7
7
|
// lib/queries/*.gql file names
|
8
|
-
const LABELED_EVENTS_QUERY = 'PRLabeledEvents';
|
9
8
|
const PR_QUERY = 'PR';
|
10
9
|
const REVIEWS_QUERY = 'Reviews';
|
11
10
|
const COMMENTS_QUERY = 'PRComments';
|
@@ -34,7 +33,6 @@ export default class PRData {
|
|
34
33
|
this.comments = [];
|
35
34
|
this.commits = [];
|
36
35
|
this.reviewers = [];
|
37
|
-
this.labeledEvents = [];
|
38
36
|
}
|
39
37
|
|
40
38
|
getThread() {
|
@@ -92,14 +90,6 @@ export default class PRData {
|
|
92
90
|
]);
|
93
91
|
}
|
94
92
|
|
95
|
-
async getLabeledEvents() {
|
96
|
-
const { prid, owner, repo, cli, request, prStr } = this;
|
97
|
-
const vars = { prid, owner, repo };
|
98
|
-
cli.updateSpinner(`Getting labels from ${prStr}`);
|
99
|
-
this.labeledEvents = (await request.gql(LABELED_EVENTS_QUERY, vars))
|
100
|
-
.repository.pullRequest.timelineItems.nodes;
|
101
|
-
}
|
102
|
-
|
103
93
|
async getComments() {
|
104
94
|
const { prid, owner, repo, cli, request, prStr } = this;
|
105
95
|
const vars = { prid, owner, repo };
|
package/lib/prepare_release.js
CHANGED
@@ -40,7 +40,7 @@ export default class ReleasePreparation extends Session {
|
|
40
40
|
const { cli } = this;
|
41
41
|
|
42
42
|
cli.warn(`PR#${pr.number} - ${pr.title} is not 'MERGEABLE'.
|
43
|
-
|
43
|
+
Status: ${pr.mergeable}`);
|
44
44
|
}
|
45
45
|
|
46
46
|
async getOpenPRs(filterLabels) {
|
@@ -66,7 +66,6 @@ export default class ReleasePreparation extends Session {
|
|
66
66
|
for (const pr of prs) {
|
67
67
|
if (pr.mergeable !== 'MERGEABLE') {
|
68
68
|
this.warnForNonMergeablePR(pr);
|
69
|
-
continue;
|
70
69
|
}
|
71
70
|
const cp = new CherryPick(pr.number, this.dir, cli, {
|
72
71
|
owner: this.owner,
|
@@ -93,9 +92,9 @@ export default class ReleasePreparation extends Session {
|
|
93
92
|
} = this;
|
94
93
|
|
95
94
|
// Create new proposal branch.
|
96
|
-
cli.startSpinner(`
|
95
|
+
cli.startSpinner(`Switching to proposal branch for ${newVersion}`);
|
97
96
|
const proposalBranch = await this.createProposalBranch(releaseBranch);
|
98
|
-
cli.stopSpinner(`
|
97
|
+
cli.stopSpinner(`Switched to proposal branch for ${newVersion}`);
|
99
98
|
|
100
99
|
const success = await this.cherryPickSecurityPRs(filterLabels);
|
101
100
|
if (!success) {
|
@@ -201,9 +200,9 @@ export default class ReleasePreparation extends Session {
|
|
201
200
|
}
|
202
201
|
|
203
202
|
// Create new proposal branch.
|
204
|
-
cli.startSpinner(`
|
203
|
+
cli.startSpinner(`Switching to proposal branch for ${newVersion}`);
|
205
204
|
await this.createProposalBranch();
|
206
|
-
cli.stopSpinner(`
|
205
|
+
cli.stopSpinner(`Switched to proposal branch for ${newVersion}`);
|
207
206
|
|
208
207
|
if (this.isLTSTransition) {
|
209
208
|
// For releases transitioning into LTS, fetch the new code name.
|
@@ -482,11 +481,14 @@ export default class ReleasePreparation extends Session {
|
|
482
481
|
const data = await fs.readFile(majorChangelogPath, 'utf8');
|
483
482
|
const arr = data.split('\n');
|
484
483
|
const allCommits = this.getChangelog();
|
485
|
-
const notableChanges = await this.getBranchDiff({
|
484
|
+
const notableChanges = await this.getBranchDiff({
|
485
|
+
onlyNotableChanges: true,
|
486
|
+
format: isSecurityRelease ? 'messageonly' : 'markdown',
|
487
|
+
});
|
486
488
|
let releaseHeader = `## ${date}, Version ${newVersion}` +
|
487
489
|
` ${releaseInfo}, @${username}\n`;
|
488
490
|
if (isSecurityRelease) {
|
489
|
-
releaseHeader += '\nThis is a security release
|
491
|
+
releaseHeader += '\nThis is a security release.\n';
|
490
492
|
}
|
491
493
|
|
492
494
|
const topHeader =
|
@@ -541,7 +543,7 @@ export default class ReleasePreparation extends Session {
|
|
541
543
|
|
542
544
|
await runAsync('git', [
|
543
545
|
'checkout',
|
544
|
-
'-
|
546
|
+
'-B',
|
545
547
|
proposalBranch,
|
546
548
|
base
|
547
549
|
]);
|
@@ -620,7 +622,7 @@ export default class ReleasePreparation extends Session {
|
|
620
622
|
|
621
623
|
const notableChanges = await this.getBranchDiff({
|
622
624
|
onlyNotableChanges: true,
|
623
|
-
format: 'plaintext'
|
625
|
+
format: isSecurityRelease ? 'messageonly' : 'plaintext'
|
624
626
|
});
|
625
627
|
messageBody.push('Notable changes:\n\n');
|
626
628
|
if (isLTSTransition) {
|
package/lib/prepare_security.js
CHANGED
@@ -52,24 +52,27 @@ export default class PrepareSecurityRelease extends SecurityRelease {
|
|
52
52
|
await this.closeAndRequestDisclosure(vulnerabilityJSON.reports);
|
53
53
|
|
54
54
|
this.cli.info('Closing pull requests');
|
55
|
-
// For now, close the ones with
|
56
|
-
await this.closePRWithLabel(
|
55
|
+
// For now, close the ones with Security Release label
|
56
|
+
await this.closePRWithLabel('Security Release');
|
57
57
|
|
58
|
-
const updateFolder = this.cli.prompt(
|
59
|
-
|
60
|
-
|
58
|
+
const updateFolder = await this.cli.prompt(
|
59
|
+
`Would you like to update the next-security-release folder to ${
|
60
|
+
vulnerabilityJSON.releaseDate}?`,
|
61
61
|
{ defaultAnswer: true });
|
62
62
|
if (updateFolder) {
|
63
|
-
|
63
|
+
this.updateReleaseFolder(
|
64
|
+
vulnerabilityJSON.releaseDate.replaceAll('/', '-')
|
65
|
+
);
|
66
|
+
const securityReleaseFolder = path.join(process.cwd(), 'security-release');
|
64
67
|
commitAndPushVulnerabilitiesJSON(
|
65
|
-
|
68
|
+
securityReleaseFolder,
|
66
69
|
'chore: change next-security-release folder',
|
67
70
|
{ cli: this.cli, repository: this.repository }
|
68
71
|
);
|
69
72
|
}
|
70
73
|
this.cli.info(`Merge pull request with:
|
71
74
|
- git checkout main
|
72
|
-
- git merge
|
75
|
+
- git merge ${NEXT_SECURITY_RELEASE_BRANCH} --no-ff -m "chore: add latest security release"
|
73
76
|
- git push origin main`);
|
74
77
|
this.cli.ok('Done!');
|
75
78
|
}
|
@@ -306,16 +309,17 @@ export default class PrepareSecurityRelease extends SecurityRelease {
|
|
306
309
|
labels = [labels];
|
307
310
|
}
|
308
311
|
|
309
|
-
const url = 'https://github.com/nodejs-private/node-private/
|
312
|
+
const url = 'https://github.com/nodejs-private/node-private/pull';
|
310
313
|
this.cli.startSpinner('Closing GitHub Pull Requests...');
|
311
314
|
// At this point, GitHub does not provide filters through their REST API
|
312
|
-
const prs = this.req.getPullRequest(url);
|
315
|
+
const prs = await this.req.getPullRequest(url);
|
313
316
|
for (const pr of prs) {
|
314
|
-
if (pr.labels.some((l) => labels.includes(l))) {
|
315
|
-
this.cli.updateSpinner(`Closing Pull Request: ${pr.
|
316
|
-
await this.req.closePullRequest(pr.
|
317
|
+
if (pr.labels.some((l) => labels.includes(l.name))) {
|
318
|
+
this.cli.updateSpinner(`Closing Pull Request: ${pr.number}`);
|
319
|
+
await this.req.closePullRequest(pr.number,
|
320
|
+
{ owner: 'nodejs-private', repo: 'node-private' });
|
317
321
|
}
|
318
322
|
}
|
319
|
-
this.cli.
|
323
|
+
this.cli.stopSpinner('Closed GitHub Pull Requests.');
|
320
324
|
}
|
321
325
|
}
|
package/lib/promote_release.js
CHANGED
@@ -19,6 +19,10 @@ export default class ReleasePromotion extends Session {
|
|
19
19
|
constructor(argv, req, cli, dir) {
|
20
20
|
super(cli, dir, argv.prid);
|
21
21
|
this.req = req;
|
22
|
+
if (argv.security) {
|
23
|
+
this.config.owner = 'nodejs-private';
|
24
|
+
this.config.repo = 'node-private';
|
25
|
+
}
|
22
26
|
this.dryRun = !argv.run;
|
23
27
|
this.isLTS = false;
|
24
28
|
this.ltsCodename = '';
|
@@ -226,20 +230,28 @@ export default class ReleasePromotion extends Session {
|
|
226
230
|
|
227
231
|
async verifyTagSignature() {
|
228
232
|
const { cli, version } = this;
|
229
|
-
const [
|
233
|
+
const verifyTagPattern = /gpg:[^\n]+\ngpg:\s+using RSA key ([^\n]+)\ngpg:\s+issuer "([^"]+)"\ngpg:\s+Good signature from "([^<]+) <\2>"/;
|
234
|
+
const [verifyTagOutput, haystack] = await Promise.all([forceRunAsync(
|
230
235
|
'git', ['--no-pager',
|
231
|
-
'
|
232
|
-
`
|
233
|
-
|
234
|
-
|
235
|
-
if (
|
236
|
-
|
236
|
+
'verify-tag',
|
237
|
+
`v${version}`
|
238
|
+
], { ignoreFailure: false, captureStderr: true }), fs.readFile('README.md')]);
|
239
|
+
const match = verifyTagPattern.exec(verifyTagOutput);
|
240
|
+
if (match == null) {
|
241
|
+
cli.warn('git was not able to verify the tag:');
|
242
|
+
cli.info(verifyTagOutput);
|
243
|
+
} else {
|
244
|
+
const [, keyID, email, name] = match;
|
245
|
+
const needle = `* **${name}** <<${email}>>\n ${'`'}${keyID}${'`'}`;
|
246
|
+
if (haystack.includes(needle)) {
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
cli.warn('Tag was signed with an undocumented identity/key pair!');
|
250
|
+
cli.info('Expected to find the following entry in the README:');
|
251
|
+
cli.info(needle);
|
252
|
+
cli.info('If you are using a subkey, it might be OK.');
|
237
253
|
}
|
238
|
-
cli.
|
239
|
-
cli.info('Expected to find the following entry in the README:');
|
240
|
-
cli.info(needle);
|
241
|
-
cli.info('If you are using a subkey, it might be OK.');
|
242
|
-
cli.info(`Otherwise consider removing the tag (git tag -d v${version
|
254
|
+
cli.info(`If that doesn't sound right, consider removing the tag (git tag -d v${version
|
243
255
|
}), check your local config, and start the process over.`);
|
244
256
|
if (!await cli.prompt('Do you want to proceed anyway?', { defaultAnswer: false })) {
|
245
257
|
throw new Error('Aborted');
|
@@ -383,7 +395,6 @@ export default class ReleasePromotion extends Session {
|
|
383
395
|
{ cause: err }
|
384
396
|
);
|
385
397
|
}
|
386
|
-
await forceRunAsync('git', ['tag', '--verify', `v${version}`], { ignoreFailure: false });
|
387
398
|
this.cli.info('Using the existing tag');
|
388
399
|
}
|
389
400
|
}
|
@@ -391,7 +402,7 @@ export default class ReleasePromotion extends Session {
|
|
391
402
|
// Set up the branch so that nightly builds are produced with the next
|
392
403
|
// version number and a pre-release tag.
|
393
404
|
async setupForNextRelease() {
|
394
|
-
const { versionComponents, prid } = this;
|
405
|
+
const { versionComponents, prid, owner, repo } = this;
|
395
406
|
|
396
407
|
// Update node_version.h for next patch release.
|
397
408
|
const filePath = path.resolve('src', 'node_version.h');
|
@@ -422,7 +433,7 @@ export default class ReleasePromotion extends Session {
|
|
422
433
|
'-m',
|
423
434
|
`Working on ${workingOnVersion}`,
|
424
435
|
'-m',
|
425
|
-
`PR-URL: https://github.com/
|
436
|
+
`PR-URL: https://github.com/${owner}/${repo}/pull/${prid}`
|
426
437
|
], { ignoreFailure: false });
|
427
438
|
const workingOnNewReleaseCommit = await forceRunAsync('git', ['rev-parse', 'HEAD'],
|
428
439
|
{ ignoreFailure: false, captureStdout: true });
|
package/lib/queries/PR.gql
CHANGED
package/lib/release/utils.js
CHANGED
@@ -21,12 +21,10 @@ export function getStartLTSBlurb({ date, ltsCodename, versionComponents }) {
|
|
21
21
|
const eol = eolDate.toLocaleString('en-US', dateFormat);
|
22
22
|
const { major } = versionComponents;
|
23
23
|
return [
|
24
|
-
/* eslint-disable max-len */
|
25
24
|
`This release marks the transition of Node.js ${major}.x into Long Term Support (LTS)`,
|
26
25
|
`with the codename '${ltsCodename}'. The ${major}.x release line now moves into "Active LTS"`,
|
27
26
|
`and will remain so until ${mainStart}. After that time, it will move into`,
|
28
27
|
`"Maintenance" until end of life in ${eol}.`
|
29
|
-
/* eslint-enable */
|
30
28
|
].join('\n');
|
31
29
|
}
|
32
30
|
|
package/lib/request.js
CHANGED
@@ -109,14 +109,15 @@ export default class Request {
|
|
109
109
|
return this.json(url, options);
|
110
110
|
}
|
111
111
|
|
112
|
-
async closePullRequest({ owner, repo }) {
|
113
|
-
const url = `https://api.github.com/repos/${owner}/${repo}/pulls`;
|
112
|
+
async closePullRequest(id, { owner, repo }) {
|
113
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${id}`;
|
114
114
|
const options = {
|
115
115
|
method: 'POST',
|
116
116
|
headers: {
|
117
117
|
Authorization: `Basic ${this.credentials.github}`,
|
118
118
|
'User-Agent': 'node-core-utils',
|
119
|
-
Accept: 'application/vnd.github+json'
|
119
|
+
Accept: 'application/vnd.github+json',
|
120
|
+
'Content-Type': 'application/json'
|
120
121
|
},
|
121
122
|
body: JSON.stringify({
|
122
123
|
state: 'closed'
|
@@ -230,7 +231,8 @@ export default class Request {
|
|
230
231
|
headers: {
|
231
232
|
Authorization: `Basic ${this.credentials.h1}`,
|
232
233
|
'User-Agent': 'node-core-utils',
|
233
|
-
Accept: 'application/json'
|
234
|
+
Accept: 'application/json',
|
235
|
+
'Content-Type': 'application/json'
|
234
236
|
},
|
235
237
|
body: JSON.stringify({
|
236
238
|
data: {
|
@@ -252,11 +254,13 @@ export default class Request {
|
|
252
254
|
headers: {
|
253
255
|
Authorization: `Basic ${this.credentials.h1}`,
|
254
256
|
'User-Agent': 'node-core-utils',
|
255
|
-
Accept: 'application/json'
|
257
|
+
Accept: 'application/json',
|
258
|
+
'Content-Type': 'application/json'
|
256
259
|
},
|
257
260
|
body: JSON.stringify({
|
258
261
|
data: {
|
259
262
|
attributes: {
|
263
|
+
message: 'Requesting disclosure',
|
260
264
|
// default to limited version
|
261
265
|
substate: 'no-content'
|
262
266
|
}
|
package/lib/run.js
CHANGED
@@ -12,14 +12,19 @@ function runAsyncBase(cmd, args, {
|
|
12
12
|
ignoreFailure = true,
|
13
13
|
spawnArgs,
|
14
14
|
input,
|
15
|
+
captureStderr = false,
|
15
16
|
captureStdout = false
|
16
17
|
} = {}) {
|
17
18
|
if (cmd instanceof URL) {
|
18
19
|
cmd = fileURLToPath(cmd);
|
19
20
|
}
|
20
21
|
let stdio = 'inherit';
|
21
|
-
if (captureStdout || input != null) {
|
22
|
-
stdio = [
|
22
|
+
if (captureStderr || captureStdout || input != null) {
|
23
|
+
stdio = [
|
24
|
+
input == null ? 'inherit' : 'pipe',
|
25
|
+
captureStdout ? 'pipe' : 'inherit',
|
26
|
+
captureStderr ? 'pipe' : 'inherit'
|
27
|
+
];
|
23
28
|
}
|
24
29
|
return new Promise((resolve, reject) => {
|
25
30
|
const opt = Object.assign({
|
@@ -30,6 +35,12 @@ function runAsyncBase(cmd, args, {
|
|
30
35
|
debuglog('[Spawn]', `${cmd} ${(args || []).join(' ')}`, opt);
|
31
36
|
}
|
32
37
|
const child = spawn(cmd, args, opt);
|
38
|
+
let stderr;
|
39
|
+
if (!captureStdout && captureStderr) {
|
40
|
+
stderr = '';
|
41
|
+
child.stderr.setEncoding('utf8');
|
42
|
+
child.stderr.on('data', (chunk) => { stderr += chunk; });
|
43
|
+
}
|
33
44
|
let stdout;
|
34
45
|
if (captureStdout) {
|
35
46
|
stdout = '';
|
@@ -51,7 +62,7 @@ function runAsyncBase(cmd, args, {
|
|
51
62
|
stdout = stdout.split(/\r?\n/g);
|
52
63
|
if (stdout[stdout.length - 1] === '') stdout.pop();
|
53
64
|
}
|
54
|
-
return resolve(stdout);
|
65
|
+
return resolve(stdout ?? stderr);
|
55
66
|
});
|
56
67
|
if (input != null) child.stdin.end(input);
|
57
68
|
});
|
@@ -236,7 +236,7 @@ export class SecurityRelease {
|
|
236
236
|
updateReleaseFolder(releaseDate) {
|
237
237
|
const folder = path.join(process.cwd(),
|
238
238
|
NEXT_SECURITY_RELEASE_FOLDER);
|
239
|
-
const newFolder = path.join(process.cwd(), releaseDate);
|
239
|
+
const newFolder = path.join(process.cwd(), 'security-release', releaseDate);
|
240
240
|
fs.renameSync(folder, newFolder);
|
241
241
|
return newFolder;
|
242
242
|
}
|
package/lib/team_info.js
CHANGED
@@ -119,7 +119,6 @@ function updateV8Deps() {
|
|
119
119
|
path: v8Dep.repo
|
120
120
|
})), newV8Version);
|
121
121
|
if (deps.length === 0) return;
|
122
|
-
/* eslint-disable no-await-in-loop */
|
123
122
|
for (const dep of deps) {
|
124
123
|
if (dep.gitignore) {
|
125
124
|
if (typeof dep.gitignore === 'string') {
|
@@ -132,7 +131,6 @@ function updateV8Deps() {
|
|
132
131
|
const thePath = path.join(ctx.nodeDir, 'deps/v8', dep.path);
|
133
132
|
await fetchFromGit(thePath, repo, commit);
|
134
133
|
}
|
135
|
-
/* eslint-enable */
|
136
134
|
}
|
137
135
|
};
|
138
136
|
}
|
package/lib/voting_session.js
CHANGED
@@ -10,6 +10,7 @@ import {
|
|
10
10
|
getEditor, isGhAvailable
|
11
11
|
} from './utils.js';
|
12
12
|
|
13
|
+
// eslint-disable-next-line import/no-unresolved
|
13
14
|
import voteUsingGit from '@node-core/caritat/voteUsingGit';
|
14
15
|
import * as yaml from 'js-yaml';
|
15
16
|
|
@@ -97,7 +98,7 @@ export default class VotingSession extends Session {
|
|
97
98
|
cp.stdin.end(share);
|
98
99
|
const [code] = await Promise.race([
|
99
100
|
once(cp, 'exit'),
|
100
|
-
once(cp, 'error').then((er) =>
|
101
|
+
once(cp, 'error').then((er) => { throw er; })
|
101
102
|
]);
|
102
103
|
if (code !== 0) throw new Error('failed', { cause: code });
|
103
104
|
return Buffer.concat(await stdout);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@node-core/utils",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.12.0",
|
4
4
|
"description": "Utilities for Node.js core collaborators",
|
5
5
|
"type": "module",
|
6
6
|
"engines": {
|
@@ -40,7 +40,7 @@
|
|
40
40
|
"@pkgjs/nv": "^0.2.2",
|
41
41
|
"branch-diff": "^3.1.1",
|
42
42
|
"chalk": "^5.4.1",
|
43
|
-
"changelog-maker": "^4.3.
|
43
|
+
"changelog-maker": "^4.3.2",
|
44
44
|
"cheerio": "^1.0.0",
|
45
45
|
"clipboardy": "^4.0.0",
|
46
46
|
"core-validate-commit": "^4.1.0",
|
@@ -53,18 +53,21 @@
|
|
53
53
|
"log-symbols": "^7.0.0",
|
54
54
|
"ora": "^8.1.1",
|
55
55
|
"replace-in-file": "^8.3.0",
|
56
|
-
"
|
56
|
+
"semver": "^7.6.3",
|
57
|
+
"undici": "^7.3.0",
|
57
58
|
"which": "^5.0.0",
|
58
59
|
"yargs": "^17.7.2"
|
59
60
|
},
|
60
61
|
"devDependencies": {
|
62
|
+
"@eslint/js": "^9.19.0",
|
61
63
|
"@reporters/github": "^1.7.2",
|
62
64
|
"c8": "^10.1.3",
|
63
|
-
"eslint": "^
|
64
|
-
"eslint-config-standard": "^17.1.0",
|
65
|
+
"eslint": "^9.19.0",
|
65
66
|
"eslint-plugin-import": "^2.31.0",
|
66
|
-
"eslint-plugin-n": "^
|
67
|
-
"eslint-plugin-promise": "^
|
67
|
+
"eslint-plugin-n": "^17.15.1",
|
68
|
+
"eslint-plugin-promise": "^7.2.1",
|
69
|
+
"globals": "^15.14.0",
|
70
|
+
"neostandard": "^0.12.0",
|
68
71
|
"sinon": "^19.0.2"
|
69
72
|
}
|
70
73
|
}
|
@@ -1,19 +0,0 @@
|
|
1
|
-
query PRLabeledEvents($prid: Int!, $owner: String!, $repo: String!, $after: String) {
|
2
|
-
repository(owner: $owner, name: $repo) {
|
3
|
-
pullRequest(number: $prid) {
|
4
|
-
timelineItems(itemTypes: LABELED_EVENT, after: $after, last: 100) {
|
5
|
-
nodes {
|
6
|
-
... on LabeledEvent {
|
7
|
-
actor {
|
8
|
-
login
|
9
|
-
}
|
10
|
-
label {
|
11
|
-
name
|
12
|
-
}
|
13
|
-
createdAt
|
14
|
-
}
|
15
|
-
}
|
16
|
-
}
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|