@node-core/utils 5.0.2 → 5.2.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/components/git/security.js +18 -0
- package/components/git/v8.js +2 -0
- package/lib/ci/run_ci.js +1 -1
- package/lib/github/templates/security-pre-release.md +4 -0
- package/lib/pr_checker.js +26 -0
- package/lib/pr_data.js +10 -0
- package/lib/prepare_security.js +1 -2
- package/lib/queries/PRLabeledEvents.gql +19 -0
- package/lib/request.js +3 -2
- package/lib/security-release/security-release.js +33 -16
- package/lib/update-v8/majorUpdate.js +9 -4
- package/lib/update-v8/minorUpdate.js +5 -3
- package/lib/update-v8/updateV8Clone.js +2 -0
- package/lib/update_security_release.js +39 -1
- package/lib/voting_session.js +13 -3
- package/package.json +15 -15
@@ -12,6 +12,10 @@ const securityOptions = {
|
|
12
12
|
describe: 'Start security release process',
|
13
13
|
type: 'boolean'
|
14
14
|
},
|
15
|
+
sync: {
|
16
|
+
describe: 'Synchronize an ongoing security release with HackerOne',
|
17
|
+
type: 'boolean'
|
18
|
+
},
|
15
19
|
'update-date': {
|
16
20
|
describe: 'Updates the target date of the security release',
|
17
21
|
type: 'string'
|
@@ -46,6 +50,10 @@ export function builder(yargs) {
|
|
46
50
|
.example(
|
47
51
|
'git node security --start',
|
48
52
|
'Prepare a security release of Node.js')
|
53
|
+
.example(
|
54
|
+
'git node security --sync',
|
55
|
+
'Synchronize an ongoing security release with HackerOne'
|
56
|
+
)
|
49
57
|
.example(
|
50
58
|
'git node security --update-date=YYYY/MM/DD',
|
51
59
|
'Updates the target date of the security release'
|
@@ -76,6 +84,9 @@ export function handler(argv) {
|
|
76
84
|
if (argv.start) {
|
77
85
|
return startSecurityRelease(argv);
|
78
86
|
}
|
87
|
+
if (argv.sync) {
|
88
|
+
return syncSecurityRelease(argv);
|
89
|
+
}
|
79
90
|
if (argv['update-date']) {
|
80
91
|
return updateReleaseDate(argv);
|
81
92
|
}
|
@@ -142,6 +153,13 @@ async function startSecurityRelease(argv) {
|
|
142
153
|
return release.start();
|
143
154
|
}
|
144
155
|
|
156
|
+
async function syncSecurityRelease(argv) {
|
157
|
+
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
158
|
+
const cli = new CLI(logStream);
|
159
|
+
const release = new UpdateSecurityRelease(cli);
|
160
|
+
return release.sync();
|
161
|
+
}
|
162
|
+
|
145
163
|
async function notifyPreRelease() {
|
146
164
|
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
|
147
165
|
const cli = new CLI(logStream);
|
package/components/git/v8.js
CHANGED
@@ -81,6 +81,7 @@ export function handler(argv) {
|
|
81
81
|
options.execGitNode = function execGitNode(cmd, args, input) {
|
82
82
|
args.unshift(cmd);
|
83
83
|
return forceRunAsync('git', args, {
|
84
|
+
ignoreFailure: false,
|
84
85
|
input,
|
85
86
|
spawnArgs: {
|
86
87
|
cwd: options.nodeDir,
|
@@ -91,6 +92,7 @@ export function handler(argv) {
|
|
91
92
|
|
92
93
|
options.execGitV8 = function execGitV8(...args) {
|
93
94
|
return forceRunAsync('git', args, {
|
95
|
+
ignoreFailure: false,
|
94
96
|
captureStdout: true,
|
95
97
|
spawnArgs: { cwd: options.v8Dir, stdio: ['ignore', 'pipe', 'ignore'] }
|
96
98
|
});
|
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
|
+
new PRChecker(cli, this.prData, request, {}).checkCommitsAfterReviewOrLabel()
|
31
31
|
);
|
32
32
|
}
|
33
33
|
|
@@ -18,6 +18,10 @@ releases lines on or shortly after, %RELEASE_DATE% in order to address:
|
|
18
18
|
|
19
19
|
%IMPACT%
|
20
20
|
|
21
|
+
It's important to note that End-of-Life versions are always affected when a security release occurs.
|
22
|
+
To ensure your system's security, please use an up-to-date version as outlined in our
|
23
|
+
[Release Schedule](https://github.com/nodejs/release#release-schedule).
|
24
|
+
|
21
25
|
## Release timing
|
22
26
|
|
23
27
|
Releases will be available on, or shortly after, %RELEASE_DATE%.
|
package/lib/pr_checker.js
CHANGED
@@ -523,6 +523,32 @@ export default class PRChecker {
|
|
523
523
|
return true;
|
524
524
|
}
|
525
525
|
|
526
|
+
async checkCommitsAfterReviewOrLabel() {
|
527
|
+
if (this.checkCommitsAfterReview()) return true;
|
528
|
+
|
529
|
+
await Promise.all([this.data.getLabeledEvents(), this.data.getCollaborators()]);
|
530
|
+
|
531
|
+
const {
|
532
|
+
cli, data, pr
|
533
|
+
} = this;
|
534
|
+
|
535
|
+
const { updatedAt } = pr.timelineItems;
|
536
|
+
const requestCiLabels = data.labeledEvents.findLast(
|
537
|
+
({ createdAt, label: { name } }) => name === 'request-ci' && createdAt > updatedAt
|
538
|
+
);
|
539
|
+
if (requestCiLabels == null) return false;
|
540
|
+
|
541
|
+
const { actor: { login } } = requestCiLabels;
|
542
|
+
const collaborators = Array.from(data.collaborators.values(),
|
543
|
+
(c) => c.login.toLowerCase());
|
544
|
+
if (collaborators.includes(login.toLowerCase())) {
|
545
|
+
cli.info('request-ci label was added by a Collaborator after the last push event.');
|
546
|
+
return true;
|
547
|
+
}
|
548
|
+
|
549
|
+
return false;
|
550
|
+
}
|
551
|
+
|
526
552
|
checkCommitsAfterReview() {
|
527
553
|
const {
|
528
554
|
commits, reviews, cli, argv
|
package/lib/pr_data.js
CHANGED
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
} from './user_status.js';
|
6
6
|
|
7
7
|
// lib/queries/*.gql file names
|
8
|
+
const LABELED_EVENTS_QUERY = 'PRLabeledEvents';
|
8
9
|
const PR_QUERY = 'PR';
|
9
10
|
const REVIEWS_QUERY = 'Reviews';
|
10
11
|
const COMMENTS_QUERY = 'PRComments';
|
@@ -33,6 +34,7 @@ export default class PRData {
|
|
33
34
|
this.comments = [];
|
34
35
|
this.commits = [];
|
35
36
|
this.reviewers = [];
|
37
|
+
this.labeledEvents = [];
|
36
38
|
}
|
37
39
|
|
38
40
|
getThread() {
|
@@ -90,6 +92,14 @@ export default class PRData {
|
|
90
92
|
]);
|
91
93
|
}
|
92
94
|
|
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
|
+
|
93
103
|
async getComments() {
|
94
104
|
const { prid, owner, repo, cli, request, prStr } = this;
|
95
105
|
const vars = { prid, owner, repo };
|
package/lib/prepare_security.js
CHANGED
@@ -248,8 +248,7 @@ export default class PrepareSecurityRelease {
|
|
248
248
|
});
|
249
249
|
|
250
250
|
try {
|
251
|
-
const
|
252
|
-
const res = await this.req.getPullRequest(prUrl);
|
251
|
+
const res = await this.req.getPullRequest(dep);
|
253
252
|
const { html_url, title } = res;
|
254
253
|
deps.push({
|
255
254
|
name,
|
@@ -0,0 +1,19 @@
|
|
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
|
+
}
|
package/lib/request.js
CHANGED
@@ -77,7 +77,8 @@ export default class Request {
|
|
77
77
|
return this.json(url, options);
|
78
78
|
}
|
79
79
|
|
80
|
-
async getPullRequest(
|
80
|
+
async getPullRequest(fullUrl) {
|
81
|
+
const prUrl = fullUrl.replace('https://github.com/', 'https://api.github.com/repos/').replace('pull', 'pulls');
|
81
82
|
const options = {
|
82
83
|
method: 'GET',
|
83
84
|
headers: {
|
@@ -86,7 +87,7 @@ export default class Request {
|
|
86
87
|
Accept: 'application/vnd.github+json'
|
87
88
|
}
|
88
89
|
};
|
89
|
-
return this.json(
|
90
|
+
return this.json(prUrl, options);
|
90
91
|
}
|
91
92
|
|
92
93
|
async createPullRequest(title, body, { owner, repo, head, base }) {
|
@@ -87,8 +87,8 @@ export async function getSupportedVersions() {
|
|
87
87
|
return supportedVersions;
|
88
88
|
}
|
89
89
|
|
90
|
-
export
|
91
|
-
const { data } =
|
90
|
+
export function getSummary(report) {
|
91
|
+
const { data } = report;
|
92
92
|
const summaryList = data?.relationships?.summaries?.data;
|
93
93
|
if (!summaryList?.length) return;
|
94
94
|
const summaries = summaryList.filter((summary) => summary?.attributes?.category === 'team');
|
@@ -139,17 +139,25 @@ export async function createIssue(title, content, repository, { cli, req }) {
|
|
139
139
|
}
|
140
140
|
}
|
141
141
|
|
142
|
-
export
|
142
|
+
export function getReportSeverity(report) {
|
143
143
|
const {
|
144
|
-
|
145
|
-
relationships: { severity, weakness, reporter }
|
144
|
+
relationships: { severity, weakness }
|
146
145
|
} = report;
|
147
|
-
const link = `https://hackerone.com/reports/${id}`;
|
148
146
|
const reportSeverity = {
|
149
147
|
rating: severity?.data?.attributes?.rating || '',
|
150
148
|
cvss_vector_string: severity?.data?.attributes?.cvss_vector_string || '',
|
151
149
|
weakness_id: weakness?.data?.id || ''
|
152
150
|
};
|
151
|
+
return reportSeverity;
|
152
|
+
}
|
153
|
+
|
154
|
+
export async function pickReport(report, { cli, req }) {
|
155
|
+
const {
|
156
|
+
id, attributes: { title, cve_ids },
|
157
|
+
relationships: { reporter, custom_field_values }
|
158
|
+
} = report;
|
159
|
+
const link = `https://hackerone.com/reports/${id}`;
|
160
|
+
const reportSeverity = getReportSeverity(report);
|
153
161
|
|
154
162
|
cli.separator();
|
155
163
|
cli.info(`Report: ${link} - ${title} (${reportSeverity?.rating})`);
|
@@ -165,19 +173,27 @@ export async function pickReport(report, { cli, req }) {
|
|
165
173
|
defaultAnswer: await getSupportedVersions()
|
166
174
|
});
|
167
175
|
|
168
|
-
let
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
});
|
173
|
-
|
174
|
-
if (!patchAuthors) {
|
175
|
-
patchAuthors = [];
|
176
|
+
let prURL = '';
|
177
|
+
let patchAuthors = [];
|
178
|
+
if (custom_field_values.data.length) {
|
179
|
+
prURL = custom_field_values.data[0].attributes.value;
|
180
|
+
const { user } = await req.getPullRequest(prURL);
|
181
|
+
patchAuthors = [user.login];
|
176
182
|
} else {
|
177
|
-
patchAuthors =
|
183
|
+
patchAuthors = await cli.prompt(
|
184
|
+
'Add github username of the authors of the patch (split by comma if multiple)', {
|
185
|
+
questionType: 'input',
|
186
|
+
defaultAnswer: ''
|
187
|
+
});
|
188
|
+
|
189
|
+
if (!patchAuthors) {
|
190
|
+
patchAuthors = [];
|
191
|
+
} else {
|
192
|
+
patchAuthors = patchAuthors.split(',').map((p) => p.trim());
|
193
|
+
}
|
178
194
|
}
|
179
195
|
|
180
|
-
const summaryContent =
|
196
|
+
const summaryContent = getSummary(report);
|
181
197
|
|
182
198
|
return {
|
183
199
|
id,
|
@@ -186,6 +202,7 @@ export async function pickReport(report, { cli, req }) {
|
|
186
202
|
severity: reportSeverity,
|
187
203
|
summary: summaryContent ?? '',
|
188
204
|
patchAuthors,
|
205
|
+
prURL,
|
189
206
|
affectedVersions: versions.split(',').map((v) => v.replace('v', '').trim()),
|
190
207
|
link,
|
191
208
|
reporter: reporter.data.attributes.username
|
@@ -14,7 +14,7 @@ import {
|
|
14
14
|
} from './util.js';
|
15
15
|
import applyNodeChanges from './applyNodeChanges.js';
|
16
16
|
import { chromiumGit, v8Deps } from './constants.js';
|
17
|
-
import {
|
17
|
+
import { forceRunAsync } from '../run.js';
|
18
18
|
|
19
19
|
export default function majorUpdate() {
|
20
20
|
return {
|
@@ -83,7 +83,8 @@ function cloneLocalV8() {
|
|
83
83
|
return {
|
84
84
|
title: 'Clone branch to deps/v8',
|
85
85
|
task: (ctx) =>
|
86
|
-
|
86
|
+
forceRunAsync('git', ['clone', '-b', ctx.branch, ctx.v8Dir, 'deps/v8'], {
|
87
|
+
ignoreFailure: false,
|
87
88
|
spawnArgs: { cwd: ctx.nodeDir, stdio: 'ignore' }
|
88
89
|
})
|
89
90
|
};
|
@@ -101,7 +102,8 @@ function addDepsV8() {
|
|
101
102
|
title: 'Track all files in deps/v8',
|
102
103
|
// Add all V8 files with --force before updating DEPS. We have to do this
|
103
104
|
// because some files are checked in by V8 despite .gitignore rules.
|
104
|
-
task: (ctx) =>
|
105
|
+
task: (ctx) => forceRunAsync('git', ['add', '--force', 'deps/v8'], {
|
106
|
+
ignoreFailure: false,
|
105
107
|
spawnArgs: { cwd: ctx.nodeDir, stdio: 'ignore' }
|
106
108
|
})
|
107
109
|
};
|
@@ -164,6 +166,9 @@ async function fetchFromGit(cwd, repo, commit) {
|
|
164
166
|
await removeDirectory(path.join(cwd, '.git'));
|
165
167
|
|
166
168
|
function exec(...options) {
|
167
|
-
return
|
169
|
+
return forceRunAsync('git', options, {
|
170
|
+
ignoreFailure: false,
|
171
|
+
spawnArgs: { cwd, stdio: 'ignore' }
|
172
|
+
});
|
168
173
|
}
|
169
174
|
}
|
@@ -6,7 +6,7 @@ import { Listr } from 'listr2';
|
|
6
6
|
|
7
7
|
import { getCurrentV8Version } from './common.js';
|
8
8
|
import { isVersionString } from './util.js';
|
9
|
-
import {
|
9
|
+
import { forceRunAsync } from '../run.js';
|
10
10
|
|
11
11
|
export default function minorUpdate() {
|
12
12
|
return {
|
@@ -27,7 +27,8 @@ function getLatestV8Version() {
|
|
27
27
|
task: async(ctx) => {
|
28
28
|
const version = ctx.currentVersion;
|
29
29
|
const currentV8Tag = `${version.major}.${version.minor}.${version.build}`;
|
30
|
-
const result = await
|
30
|
+
const result = await forceRunAsync('git', ['tag', '-l', `${currentV8Tag}.*`], {
|
31
|
+
ignoreFailure: false,
|
31
32
|
captureStdout: true,
|
32
33
|
spawnArgs: {
|
33
34
|
cwd: ctx.v8Dir,
|
@@ -68,7 +69,8 @@ async function applyPatch(ctx, latestStr) {
|
|
68
69
|
{ cwd: ctx.v8Dir, stdio: ['ignore', 'pipe', 'ignore'] }
|
69
70
|
);
|
70
71
|
try {
|
71
|
-
await
|
72
|
+
await forceRunAsync('git', ['apply', '--directory', 'deps/v8'], {
|
73
|
+
ignoreFailure: false,
|
72
74
|
spawnArgs: {
|
73
75
|
cwd: ctx.nodeDir,
|
74
76
|
stdio: [diff.stdout, 'ignore', 'ignore']
|
@@ -20,6 +20,7 @@ function fetchOrigin() {
|
|
20
20
|
task: async(ctx, task) => {
|
21
21
|
try {
|
22
22
|
await forceRunAsync('git', ['fetch', 'origin'], {
|
23
|
+
ignoreFailure: false,
|
23
24
|
spawnArgs: { cwd: ctx.v8Dir, stdio: 'ignore' }
|
24
25
|
});
|
25
26
|
} catch (e) {
|
@@ -40,6 +41,7 @@ function createClone() {
|
|
40
41
|
task: async(ctx) => {
|
41
42
|
await fs.mkdir(ctx.baseDir, { recursive: true });
|
42
43
|
await forceRunAsync('git', ['clone', v8Git, ctx.v8Dir], {
|
44
|
+
ignoreFailure: false,
|
43
45
|
spawnArgs: { stdio: 'ignore' }
|
44
46
|
});
|
45
47
|
},
|
@@ -2,9 +2,12 @@ import {
|
|
2
2
|
NEXT_SECURITY_RELEASE_FOLDER,
|
3
3
|
NEXT_SECURITY_RELEASE_REPOSITORY,
|
4
4
|
checkoutOnSecurityReleaseBranch,
|
5
|
+
checkRemote,
|
5
6
|
commitAndPushVulnerabilitiesJSON,
|
6
7
|
validateDate,
|
7
|
-
pickReport
|
8
|
+
pickReport,
|
9
|
+
getReportSeverity,
|
10
|
+
getSummary
|
8
11
|
} from './security-release/security-release.js';
|
9
12
|
import fs from 'node:fs';
|
10
13
|
import path from 'node:path';
|
@@ -18,6 +21,41 @@ export default class UpdateSecurityRelease {
|
|
18
21
|
this.cli = cli;
|
19
22
|
}
|
20
23
|
|
24
|
+
async sync() {
|
25
|
+
checkRemote(this.cli, this.repository);
|
26
|
+
|
27
|
+
const vulnerabilitiesJSONPath = this.getVulnerabilitiesJSONPath();
|
28
|
+
const content = this.readVulnerabilitiesJSON(vulnerabilitiesJSONPath);
|
29
|
+
const credentials = await auth({
|
30
|
+
github: true,
|
31
|
+
h1: true
|
32
|
+
});
|
33
|
+
const req = new Request(credentials);
|
34
|
+
for (let i = 0; i < content.reports.length; ++i) {
|
35
|
+
let report = content.reports[i];
|
36
|
+
const { data } = await req.getReport(report.id);
|
37
|
+
const reportSeverity = getReportSeverity(data);
|
38
|
+
const summaryContent = getSummary(data);
|
39
|
+
const link = `https://hackerone.com/reports/${report.id}`;
|
40
|
+
let prURL = report.prURL;
|
41
|
+
if (data.relationships.custom_field_values.data.length) {
|
42
|
+
prURL = data.relationships.custom_field_values.data[0].attributes.value;
|
43
|
+
}
|
44
|
+
|
45
|
+
report = {
|
46
|
+
...report,
|
47
|
+
title: data.attributes.title,
|
48
|
+
cveIds: data.attributes.cve_ids,
|
49
|
+
severity: reportSeverity,
|
50
|
+
summary: summaryContent ?? report.summary,
|
51
|
+
link,
|
52
|
+
prURL
|
53
|
+
};
|
54
|
+
}
|
55
|
+
fs.writeFileSync(vulnerabilitiesJSONPath, JSON.stringify(content, null, 2));
|
56
|
+
this.cli.ok('Synced vulnerabilities.json with HackerOne');
|
57
|
+
}
|
58
|
+
|
21
59
|
async updateReleaseDate(releaseDate) {
|
22
60
|
const { cli } = this;
|
23
61
|
|
package/lib/voting_session.js
CHANGED
@@ -114,7 +114,7 @@ export default class VotingSession extends Session {
|
|
114
114
|
const body = 'I would like to close this vote, and for this effect, I\'m revealing my ' +
|
115
115
|
`key part:\n\n${'```'}\n${keyPart}\n${'```'}\n`;
|
116
116
|
if (this.postComment) {
|
117
|
-
const { html_url } = await this.req.json(`https://api.github.com/repos/${this.owner}/${this.repo}/issues/${this.prid}/comments`, {
|
117
|
+
const { message, html_url } = await this.req.json(`https://api.github.com/repos/${this.owner}/${this.repo}/issues/${this.prid}/comments`, {
|
118
118
|
agent: this.req.proxyAgent,
|
119
119
|
method: 'POST',
|
120
120
|
headers: {
|
@@ -124,13 +124,23 @@ export default class VotingSession extends Session {
|
|
124
124
|
},
|
125
125
|
body: JSON.stringify({ body })
|
126
126
|
});
|
127
|
-
|
128
|
-
|
127
|
+
if (html_url) {
|
128
|
+
this.cli.log(`Comment posted at: ${html_url}`);
|
129
|
+
return;
|
130
|
+
} else {
|
131
|
+
this.cli.warn(message);
|
132
|
+
this.cli.error('Failed to post comment');
|
133
|
+
}
|
134
|
+
}
|
135
|
+
if (isGhAvailable()) {
|
129
136
|
this.cli.log('\nRun the following command to post the comment:\n');
|
130
137
|
this.cli.log(
|
131
138
|
`gh pr comment ${this.prid} --repo ${this.owner}/${this.repo} ` +
|
132
139
|
`--body-file - <<'EOF'\n${body}\nEOF`
|
133
140
|
);
|
141
|
+
} else {
|
142
|
+
this.cli.log('\nPost the following comment on the PR thread:\n');
|
143
|
+
this.cli.log(body);
|
134
144
|
}
|
135
145
|
}
|
136
146
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@node-core/utils",
|
3
|
-
"version": "5.0
|
3
|
+
"version": "5.2.0",
|
4
4
|
"description": "Utilities for Node.js core collaborators",
|
5
5
|
"type": "module",
|
6
6
|
"engines": {
|
@@ -34,36 +34,36 @@
|
|
34
34
|
],
|
35
35
|
"license": "MIT",
|
36
36
|
"dependencies": {
|
37
|
-
"@listr2/prompt-adapter-enquirer": "^2.0.
|
38
|
-
"@node-core/caritat": "^1.3.
|
37
|
+
"@listr2/prompt-adapter-enquirer": "^2.0.8",
|
38
|
+
"@node-core/caritat": "^1.3.1",
|
39
39
|
"@pkgjs/nv": "^0.2.2",
|
40
|
-
"branch-diff": "^3.0.
|
40
|
+
"branch-diff": "^3.0.4",
|
41
41
|
"chalk": "^5.3.0",
|
42
|
-
"changelog-maker": "^4.
|
42
|
+
"changelog-maker": "^4.1.1",
|
43
43
|
"cheerio": "^1.0.0-rc.12",
|
44
44
|
"clipboardy": "^4.0.0",
|
45
45
|
"core-validate-commit": "^4.0.0",
|
46
|
-
"figures": "^6.0
|
47
|
-
"ghauth": "^6.0.
|
48
|
-
"inquirer": "^9.2.
|
46
|
+
"figures": "^6.1.0",
|
47
|
+
"ghauth": "^6.0.4",
|
48
|
+
"inquirer": "^9.2.22",
|
49
49
|
"js-yaml": "^4.1.0",
|
50
|
-
"listr2": "^8.
|
50
|
+
"listr2": "^8.2.1",
|
51
51
|
"lodash": "^4.17.21",
|
52
52
|
"log-symbols": "^6.0.0",
|
53
53
|
"ora": "^8.0.1",
|
54
54
|
"replace-in-file": "^7.1.0",
|
55
|
-
"undici": "^6.
|
55
|
+
"undici": "^6.18.0",
|
56
56
|
"which": "^4.0.0",
|
57
57
|
"yargs": "^17.7.2"
|
58
58
|
},
|
59
59
|
"devDependencies": {
|
60
|
-
"@reporters/github": "^1.
|
61
|
-
"c8": "^9.
|
62
|
-
"eslint": "^8.
|
60
|
+
"@reporters/github": "^1.7.0",
|
61
|
+
"c8": "^9.1.0",
|
62
|
+
"eslint": "^8.57.0",
|
63
63
|
"eslint-config-standard": "^17.1.0",
|
64
64
|
"eslint-plugin-import": "^2.29.1",
|
65
|
-
"eslint-plugin-n": "^16.6.
|
65
|
+
"eslint-plugin-n": "^16.6.2",
|
66
66
|
"eslint-plugin-promise": "^6.1.1",
|
67
|
-
"sinon": "^
|
67
|
+
"sinon": "^18.0.0"
|
68
68
|
}
|
69
69
|
}
|