@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/lib/figures.js
ADDED
package/lib/file.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export function appendFile(file, content) {
|
|
5
|
+
const parts = path.parse(file);
|
|
6
|
+
if (!fs.existsSync(parts.dir)) {
|
|
7
|
+
fs.mkdirSync(parts.dir, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
// TODO(joyeecheung): what if the file is a dir?
|
|
10
|
+
fs.appendFileSync(file, content, 'utf8');
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function writeFile(file, content) {
|
|
14
|
+
const parts = path.parse(file);
|
|
15
|
+
if (parts.dir !== '' && !fs.existsSync(parts.dir)) {
|
|
16
|
+
fs.mkdirSync(parts.dir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
// TODO(joyeecheung): what if the file is a dir?
|
|
19
|
+
fs.writeFileSync(file, content, 'utf8');
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function writeJson(file, obj) {
|
|
23
|
+
writeFile(file, `${JSON.stringify(obj, null, 2)}\n`);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function readFile(file) {
|
|
27
|
+
if (fs.existsSync(file)) {
|
|
28
|
+
return fs.readFileSync(file, 'utf8');
|
|
29
|
+
}
|
|
30
|
+
return '';
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export function readJson(file) {
|
|
34
|
+
const content = readFile(file);
|
|
35
|
+
if (content) {
|
|
36
|
+
return JSON.parse(content);
|
|
37
|
+
}
|
|
38
|
+
return {};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function removeDirectory(directory) {
|
|
42
|
+
return fs.promises.rm(directory, { recursive: true, force: true });
|
|
43
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
## Planning
|
|
2
|
+
|
|
3
|
+
* [X] Open an [issue](https://github.com/nodejs-private/node-private) titled
|
|
4
|
+
`Next Security Release`, and put this checklist in the description.
|
|
5
|
+
|
|
6
|
+
* [ ] Get agreement on the list of vulnerabilities to be addressed:
|
|
7
|
+
%REPORTS%
|
|
8
|
+
|
|
9
|
+
* [ ] PR release announcements in [private](https://github.com/nodejs-private/nodejs.org-private):
|
|
10
|
+
* [ ] pre-release: %PRE_RELEASE_PRIV%
|
|
11
|
+
* [ ] post-release: %POS_RELEASE_PRIV%
|
|
12
|
+
* List vulnerabilities in order of descending severity
|
|
13
|
+
* Ask the HackerOne reporter if they would like to be credited on the
|
|
14
|
+
security release blog page
|
|
15
|
+
|
|
16
|
+
* [ ] Get agreement on the planned date for the release: %RELEASE_DATE%
|
|
17
|
+
|
|
18
|
+
* [ ] Get release team volunteers for all affected lines:
|
|
19
|
+
%AFFECTED_LINES%
|
|
20
|
+
|
|
21
|
+
## Announcement (one week in advance of the planned release)
|
|
22
|
+
|
|
23
|
+
* [ ] Verify that GitHub Actions are working as normal: <https://www.githubstatus.com/>.
|
|
24
|
+
|
|
25
|
+
* [ ] Check that all vulnerabilities are ready for release integration:
|
|
26
|
+
* PRs against all affected release lines or cherry-pick clean
|
|
27
|
+
* Approved
|
|
28
|
+
* (optional) Approved by the reporter
|
|
29
|
+
* Build and send the binary to the reporter according to its architecture
|
|
30
|
+
and ask for a review. This step is important to avoid insufficient fixes
|
|
31
|
+
between Security Releases.
|
|
32
|
+
* Have CVEs
|
|
33
|
+
* Make sure that dependent libraries have CVEs for their issues. We should
|
|
34
|
+
only create CVEs for vulnerabilities in Node.js itself. This is to avoid
|
|
35
|
+
having duplicate CVEs for the same vulnerability.
|
|
36
|
+
* Described in the pre/post announcements
|
|
37
|
+
|
|
38
|
+
* [ ] Pre-release announcement to nodejs.org blog: TBD
|
|
39
|
+
(Re-PR the pre-approved branch from nodejs-private/nodejs.org-private to
|
|
40
|
+
nodejs/nodejs.org)
|
|
41
|
+
|
|
42
|
+
* [ ] Pre-release announcement [email](https://groups.google.com/forum/#!forum/nodejs-sec): TBD
|
|
43
|
+
* Subject: `Node.js security updates for all active release lines, Month Year`
|
|
44
|
+
|
|
45
|
+
* [ ] CC `oss-security@lists.openwall.com` on pre-release
|
|
46
|
+
* [ ] Forward the email you receive to `oss-security@lists.openwall.com`.
|
|
47
|
+
|
|
48
|
+
* [ ] Create a new issue in [nodejs/tweet](https://github.com/nodejs/tweet/issues)
|
|
49
|
+
|
|
50
|
+
* [ ] Request releaser(s) to start integrating the PRs to be released.
|
|
51
|
+
|
|
52
|
+
* [ ] Notify [docker-node](https://github.com/nodejs/docker-node/issues) of upcoming security release date: TBD
|
|
53
|
+
|
|
54
|
+
* [ ] Notify build-wg of upcoming security release date by opening an issue
|
|
55
|
+
in [nodejs/build](https://github.com/nodejs/build/issues) to request WG members are available to fix any CI issues: TBD
|
|
56
|
+
|
|
57
|
+
## Release day
|
|
58
|
+
|
|
59
|
+
* [ ] [Lock CI](https://github.com/nodejs/build/blob/HEAD/doc/jenkins-guide.md#before-the-release)
|
|
60
|
+
|
|
61
|
+
* [ ] The releaser(s) run the release process to completion.
|
|
62
|
+
|
|
63
|
+
* [ ] [Unlock CI](https://github.com/nodejs/build/blob/HEAD/doc/jenkins-guide.md#after-the-release)
|
|
64
|
+
|
|
65
|
+
* [ ] Post-release announcement to Nodejs.org blog: https://github.com/nodejs/nodejs.org/pull/5447
|
|
66
|
+
* (Re-PR the pre-approved branch from nodejs-private/nodejs.org-private to
|
|
67
|
+
nodejs/nodejs.org)
|
|
68
|
+
|
|
69
|
+
* [ ] Post-release announcement in reply email: TBD
|
|
70
|
+
|
|
71
|
+
* [ ] Create a new issue in nodejs/tweet
|
|
72
|
+
|
|
73
|
+
* [ ] Comment in [docker-node][] issue that release is ready for integration.
|
|
74
|
+
The docker-node team will build and release docker image updates.
|
|
75
|
+
|
|
76
|
+
* [ ] For every H1 report resolved:
|
|
77
|
+
* Close as Resolved
|
|
78
|
+
* Request Disclosure
|
|
79
|
+
* Request publication of H1 CVE requests
|
|
80
|
+
* (Check that the "Version Fixed" field in the CVE is correct, and provide
|
|
81
|
+
links to the release blogs in the "Public Reference" section)
|
|
82
|
+
|
|
83
|
+
* [ ] PR machine-readable JSON descriptions of the vulnerabilities to the
|
|
84
|
+
[core](https://github.com/nodejs/security-wg/tree/HEAD/vuln/core)
|
|
85
|
+
vulnerability DB. https://github.com/nodejs/security-wg/pull/1029
|
|
86
|
+
* For each vulnerability add a `#.json` file, one can copy an existing
|
|
87
|
+
[json](https://github.com/nodejs/security-wg/blob/0d82062d917cb9ddab88f910559469b2b13812bf/vuln/core/78.json)
|
|
88
|
+
file, and increment the latest created file number and use that as the name
|
|
89
|
+
of the new file to be added. For example, `79.json`.
|
|
90
|
+
|
|
91
|
+
* [ ] Close this issue
|
|
92
|
+
|
|
93
|
+
* [ ] Make sure the PRs for the vulnerabilities are closed.
|
|
94
|
+
|
|
95
|
+
* [ ] PR in that you stewarded the release in
|
|
96
|
+
[Security release stewards](https://github.com/nodejs/node/blob/HEAD/doc/contributing/security-release-process.md#security-release-stewards).
|
|
97
|
+
If necessary add the next rotation of the steward rotation.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { flatten } from '../utils.js';
|
|
2
|
+
|
|
3
|
+
const COMMIT_QUERY = 'LastCommit';
|
|
4
|
+
const TREE_QUERY = 'TreeEntries';
|
|
5
|
+
|
|
6
|
+
export default class GitHubTree {
|
|
7
|
+
constructor(cli, request, argv) {
|
|
8
|
+
this.cli = cli;
|
|
9
|
+
this.request = request;
|
|
10
|
+
|
|
11
|
+
this.owner = argv.owner;
|
|
12
|
+
this.repo = argv.repo;
|
|
13
|
+
this.branch = argv.branch;
|
|
14
|
+
|
|
15
|
+
if (argv.path.endsWith('/')) {
|
|
16
|
+
this.path = argv.path.slice(0, argv.path - 1);
|
|
17
|
+
} else {
|
|
18
|
+
this.path = argv.path;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.lastCommit = argv.commit || null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get repoUrl() {
|
|
25
|
+
const base = 'https://github.com';
|
|
26
|
+
const { owner, repo } = this;
|
|
27
|
+
return `${base}/${owner}/${repo}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async _getLastCommit() {
|
|
31
|
+
const { request, owner, repo, branch, path } = this;
|
|
32
|
+
const data = await request.gql(COMMIT_QUERY, {
|
|
33
|
+
owner,
|
|
34
|
+
repo,
|
|
35
|
+
branch,
|
|
36
|
+
path
|
|
37
|
+
});
|
|
38
|
+
return data.repository.ref.target.history.nodes[0].oid;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @returns {string} the hash of the last commit in the tree
|
|
43
|
+
*/
|
|
44
|
+
async getLastCommit() {
|
|
45
|
+
if (this.lastCommit) {
|
|
46
|
+
return this.lastCommit;
|
|
47
|
+
}
|
|
48
|
+
this.lastCommit = await this._getLastCommit();
|
|
49
|
+
return this.lastCommit;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getPermanentUrl() {
|
|
53
|
+
if (!this.lastCommit) {
|
|
54
|
+
throw new Error('Call await tree.getLastCommit() first');
|
|
55
|
+
}
|
|
56
|
+
const commit = this.lastCommit;
|
|
57
|
+
return `${this.repoUrl}/tree/${commit.slice(0, 10)}/${this.path}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async buffer(assetPath) {
|
|
61
|
+
await this.getLastCommit();
|
|
62
|
+
const url = this.getAssetUrl(assetPath);
|
|
63
|
+
return this.request.buffer(url);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get the url of an asset. If the assetPath starts with `/`,
|
|
68
|
+
* it will be treated as an absolute path and the
|
|
69
|
+
* the path of the tree will not be prefixed in the url.
|
|
70
|
+
* @param {string} assetPath
|
|
71
|
+
*/
|
|
72
|
+
getAssetUrl(assetPath) {
|
|
73
|
+
if (!this.lastCommit) {
|
|
74
|
+
throw new Error('Call await tree.getLastCommit() first');
|
|
75
|
+
}
|
|
76
|
+
const base = 'https://raw.githubusercontent.com';
|
|
77
|
+
const { owner, repo, lastCommit, path } = this;
|
|
78
|
+
const prefix = `${base}/${owner}/${repo}/${lastCommit}`;
|
|
79
|
+
if (assetPath.startsWith('/')) { // absolute
|
|
80
|
+
return `${prefix}/${assetPath}`;
|
|
81
|
+
} else {
|
|
82
|
+
return `${prefix}/${path}/${assetPath}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get a list of files inside the tree (recursively).
|
|
88
|
+
* The returned file names will be relative to the path of the tree,
|
|
89
|
+
* e.g. `url/resources/data.json` in a tree with `url` as path
|
|
90
|
+
* will be `resources/data.json`
|
|
91
|
+
*
|
|
92
|
+
* @returns {{name: string, type: string}[]}
|
|
93
|
+
*/
|
|
94
|
+
async getFiles(path) {
|
|
95
|
+
if (!path) {
|
|
96
|
+
path = this.path;
|
|
97
|
+
}
|
|
98
|
+
let lastCommit = this.lastCommit;
|
|
99
|
+
if (!lastCommit) {
|
|
100
|
+
lastCommit = await this.getLastCommit();
|
|
101
|
+
}
|
|
102
|
+
const { request, owner, repo } = this;
|
|
103
|
+
|
|
104
|
+
const expression = `${lastCommit}:${path}`;
|
|
105
|
+
this.cli.updateSpinner(`Querying files for ${path}`);
|
|
106
|
+
const data = await request.gql(TREE_QUERY, {
|
|
107
|
+
owner,
|
|
108
|
+
repo,
|
|
109
|
+
expression
|
|
110
|
+
});
|
|
111
|
+
const files = data.repository.object.entries;
|
|
112
|
+
|
|
113
|
+
const dirs = files.filter((file) => file.type === 'tree');
|
|
114
|
+
const nondirs = files.filter((file) => file.type !== 'tree');
|
|
115
|
+
|
|
116
|
+
if (dirs.length) {
|
|
117
|
+
const expanded = await Promise.all(
|
|
118
|
+
dirs.map((dir) =>
|
|
119
|
+
this.getFiles(`${path}/${dir.name}`)
|
|
120
|
+
.then(files => files.map(
|
|
121
|
+
({ name, type }) => ({ name: `${dir.name}/${name}`, type })
|
|
122
|
+
))
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
return nondirs.concat(flatten(expanded));
|
|
126
|
+
} else {
|
|
127
|
+
return nondirs;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
getCacheKey() {
|
|
132
|
+
const { branch, owner, repo, path } = this;
|
|
133
|
+
return `tree-${owner}-${repo}-${branch}-${clean(path)}`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function clean(path) {
|
|
138
|
+
if (!path) {
|
|
139
|
+
return '';
|
|
140
|
+
}
|
|
141
|
+
return path.replace('/', '-');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Uncomment this when testing to avoid extra network costs
|
|
145
|
+
// import Cache from '../cache.js';
|
|
146
|
+
// const treeCache = new Cache();
|
|
147
|
+
|
|
148
|
+
// treeCache.wrap(GitHubTree, {
|
|
149
|
+
// _getLastCommit() {
|
|
150
|
+
// return { key: `${this.getCacheKey()}-commit`, ext: '.json' };
|
|
151
|
+
// },
|
|
152
|
+
// getFiles(path) {
|
|
153
|
+
// return {
|
|
154
|
+
// key: `${this.getCacheKey()}-${clean(path)}-files`,
|
|
155
|
+
// ext: '.json'
|
|
156
|
+
// };
|
|
157
|
+
// },
|
|
158
|
+
// text(assetPath) {
|
|
159
|
+
// return { key: `${this.getCacheKey()}-${clean(assetPath)}`, ext: '.txt' };
|
|
160
|
+
// }
|
|
161
|
+
// });
|
|
162
|
+
// treeCache.enable();
|