@node-core/utils 6.4.0 → 7.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.
Files changed (56) hide show
  1. package/README.md +2 -5
  2. package/bin/ncu-ci.js +3 -19
  3. package/components/git/benchmark.js +112 -0
  4. package/components/git/land.js +3 -3
  5. package/components/git/metadata.js +34 -1
  6. package/components/git/release.js +3 -5
  7. package/components/git/security.js +258 -27
  8. package/components/git/v8.js +6 -3
  9. package/components/metadata.js +75 -7
  10. package/lib/auth.js +3 -4
  11. package/lib/backport_session.js +3 -3
  12. package/lib/benchmark.js +243 -0
  13. package/lib/cherry_pick.js +32 -11
  14. package/lib/ci/failure_aggregator.js +16 -20
  15. package/lib/ci/run_ci.js +1 -1
  16. package/lib/cli.js +25 -1
  17. package/lib/config.js +7 -7
  18. package/lib/file.js +5 -5
  19. package/lib/landing_session.js +65 -24
  20. package/lib/links.js +4 -4
  21. package/lib/pr_checker.js +163 -31
  22. package/lib/pr_data.js +1 -1
  23. package/lib/pr_summary.js +1 -1
  24. package/lib/prepare_release.js +270 -85
  25. package/lib/prepare_security.js +312 -46
  26. package/lib/promote_release.js +19 -16
  27. package/lib/queries/ListSecurityReleasePRs.gql +19 -0
  28. package/lib/queries/PR.gql +4 -1
  29. package/lib/request.js +41 -0
  30. package/lib/run.js +5 -5
  31. package/lib/security-announcement.js +10 -5
  32. package/lib/security-release/security-release.js +160 -20
  33. package/lib/security_blog.js +130 -65
  34. package/lib/session.js +4 -3
  35. package/lib/team_info.js +1 -1
  36. package/lib/update-v8/applyNodeChanges.js +1 -3
  37. package/lib/update-v8/backport.js +6 -6
  38. package/lib/update-v8/commitUpdate.js +3 -6
  39. package/lib/update-v8/common.js +30 -6
  40. package/lib/update-v8/constants.js +5 -0
  41. package/lib/update-v8/deps.js +3 -5
  42. package/lib/update-v8/index.js +14 -5
  43. package/lib/update-v8/majorUpdate.js +5 -4
  44. package/lib/update-v8/minorUpdate.js +4 -4
  45. package/lib/update-v8/updateCrates.js +192 -0
  46. package/lib/update-v8/updateV8Clone.js +1 -1
  47. package/lib/update-v8/updateVersionNumbers.js +3 -6
  48. package/lib/update-v8/util.js +3 -3
  49. package/lib/update_security_release.js +347 -105
  50. package/lib/utils.js +5 -5
  51. package/lib/verbosity.js +3 -3
  52. package/lib/wpt/index.js +1 -23
  53. package/package.json +18 -22
  54. package/bin/get-metadata.js +0 -11
  55. package/lib/wpt/templates/README.md +0 -16
  56. package/npm-shrinkwrap.json +0 -20380
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { promises as fs } from 'node:fs';
3
3
 
4
- import { getCurrentV8Version } from './common.js';
4
+ import { getV8Version } from './common.js';
5
5
  import { isVersionString } from './util.js';
6
6
  import { forceRunAsync } from '../run.js';
7
7
 
@@ -10,13 +10,13 @@ export default function minorUpdate() {
10
10
  title: 'Minor V8 update',
11
11
  task: (ctx, task) => {
12
12
  return task.newListr([
13
- getCurrentV8Version(),
13
+ getV8Version('current'),
14
14
  getLatestV8Version(),
15
15
  doMinorUpdate()
16
16
  ]);
17
17
  }
18
18
  };
19
- };
19
+ }
20
20
 
21
21
  function getLatestV8Version() {
22
22
  return {
@@ -74,7 +74,7 @@ async function applyPatch(ctx, latestStr) {
74
74
  } catch (e) {
75
75
  const file = path.join(ctx.nodeDir, `${latestStr}.diff`);
76
76
  await fs.writeFile(file, diff);
77
- throw new Error(`Could not apply patch.\n${e}\nDiff was stored in ${file}`);
77
+ throw new Error(`Could not apply patch.\n${e}\nDiff was stored in ${file}`, { cause: e });
78
78
  }
79
79
  }
80
80
 
@@ -0,0 +1,192 @@
1
+ import semver from 'semver';
2
+ import * as TOML from 'smol-toml';
3
+ import { promises as fs } from 'node:fs';
4
+ import path from 'node:path';
5
+
6
+ import { removeDirectory } from './util.js';
7
+ import { forceRunAsync } from '../run.js';
8
+
9
+ export default function updateCrates() {
10
+ return {
11
+ title: 'Update Rust crates',
12
+ skip: (ctx) => ctx.newVersion.majorMinor < 139,
13
+ task: (ctx, task) => {
14
+ return task.newListr([
15
+ enumerateTemporalDependencies(),
16
+ removeExistingCrates(),
17
+ vendorCrates(),
18
+ buildManifest(),
19
+ generateLockfile(),
20
+ updateGYP(),
21
+ commitChanges()
22
+ ]);
23
+ }
24
+ };
25
+ }
26
+
27
+ const chromiumCratesDir = 'deps/v8/third_party/rust/chromium_crates_io';
28
+ const nodeCratesDir = 'deps/crates';
29
+
30
+ function enumerateTemporalDependencies() {
31
+ return {
32
+ title: 'Enumerate Temporal dependency tree',
33
+ task: async(ctx) => {
34
+ const tree = await forceRunAsync(
35
+ ctx.cargo,
36
+ ['tree', '-Z', 'bindeps', '--package', 'temporal_capi', '--prefix', 'none'],
37
+ {
38
+ ignoreFailure: false,
39
+ captureStdout: true,
40
+ spawnArgs: {
41
+ cwd: path.join(ctx.nodeDir, chromiumCratesDir),
42
+ env: { ...process.env, RUSTC_BOOTSTRAP: '1' }
43
+ }
44
+ }
45
+ );
46
+ const crates = new Set();
47
+ for (const crate of tree.trimEnd().split('\n').sort()) {
48
+ const [name, version] = crate.split(' ', 2);
49
+ crates.add(`${name}@${version.substring(1)}`);
50
+ }
51
+ ctx.temporalCrates = crates;
52
+ },
53
+ };
54
+ }
55
+
56
+ function removeExistingCrates() {
57
+ return {
58
+ title: 'Remove existing crates',
59
+ task: (ctx) => removeDirectory(path.join(ctx.nodeDir, nodeCratesDir, 'vendor'))
60
+ };
61
+ }
62
+
63
+ // Note that the crates vendored in third_party/rust/chromium_crates_io already have any custom
64
+ // Chromium patches applied by gnrt, so we don't need to worry about patching them ourselves.
65
+ function vendorCrates() {
66
+ return {
67
+ title: 'Copy vendored crates',
68
+ task: async(ctx, task) => {
69
+ const chromiumVendor = path.join(ctx.nodeDir, chromiumCratesDir, 'vendor');
70
+ const nodeVendor = path.join(ctx.nodeDir, nodeCratesDir, 'vendor');
71
+ await fs.mkdir(nodeVendor);
72
+
73
+ const subtasks = [];
74
+ const rustVersions = [];
75
+ for (const dir of await fs.readdir(chromiumVendor)) {
76
+ const crate = await getCrateInfo(dir);
77
+ if (!crate || !ctx.temporalCrates.has(`${crate.name}@${crate.version}`)) continue;
78
+ if (crate.name === 'temporal_capi') {
79
+ ctx.temporalCAPIDirectory = dir;
80
+ }
81
+ if (crate['rust-version']) {
82
+ rustVersions.push(crate['rust-version']);
83
+ }
84
+ subtasks.push({
85
+ title: dir,
86
+ task: async(ctx) => {
87
+ await fs.cp(
88
+ path.join(chromiumVendor, dir),
89
+ path.join(nodeVendor, dir),
90
+ { recursive: true }
91
+ );
92
+ }
93
+ });
94
+ }
95
+
96
+ if (rustVersions.length) {
97
+ const msrv = rustVersions.map(semver.coerce).reduce((a, b) => (semver.gt(a, b) ? a : b));
98
+ ctx.msrv = `${msrv.major}.${msrv.minor}`;
99
+ }
100
+
101
+ return task.newListr(subtasks, { concurrent: ctx.concurrent });
102
+
103
+ async function getCrateInfo(crate) {
104
+ try {
105
+ const manifest = TOML.parse(
106
+ await fs.readFile(path.join(chromiumVendor, crate, 'Cargo.toml'), 'utf8')
107
+ );
108
+ return manifest.package;
109
+ } catch {
110
+ return null;
111
+ }
112
+ }
113
+ }
114
+ };
115
+ }
116
+
117
+ function buildManifest() {
118
+ return {
119
+ title: 'Build new manifest',
120
+ task: async(ctx) => {
121
+ const sourceManifest = TOML.parse(
122
+ await fs.readFile(path.join(ctx.nodeDir, chromiumCratesDir, 'Cargo.toml'), 'utf8')
123
+ );
124
+
125
+ const header =
126
+ '# This manifest is generated by node-core-utils. Do not modify it directly.\n\n';
127
+ const manifest = {
128
+ package: {
129
+ edition: sourceManifest.package.edition,
130
+ name: 'node_crates',
131
+ version: `${ctx.newVersion.major}.${ctx.newVersion.minor}.${ctx.newVersion.build}`
132
+ },
133
+ lib: {
134
+ 'crate-type': ['staticlib']
135
+ },
136
+ dependencies: {}
137
+ };
138
+ if (ctx.msrv) {
139
+ manifest.package['rust-version'] = ctx.msrv;
140
+ }
141
+ for (const crate of ctx.temporalCrates) {
142
+ const name = crate.split('@', 1)[0];
143
+ if (name === 'temporal_capi' || typeof sourceManifest.dependencies[name] === 'object') {
144
+ manifest.dependencies[name] = sourceManifest.dependencies[name];
145
+ }
146
+ }
147
+
148
+ const cargoTOML = header + TOML.stringify(manifest);
149
+ await fs.writeFile(path.join(ctx.nodeDir, nodeCratesDir, 'Cargo.toml'), cargoTOML);
150
+ },
151
+ };
152
+ }
153
+
154
+ function generateLockfile() {
155
+ return {
156
+ title: 'Generate lockfile',
157
+ task: (ctx) => forceRunAsync(ctx.cargo, ['generate-lockfile', '--quiet', '--offline'], {
158
+ ignoreFailure: false,
159
+ spawnArgs: { cwd: path.join(ctx.nodeDir, nodeCratesDir) }
160
+ })
161
+ };
162
+ }
163
+
164
+ function updateGYP() {
165
+ return {
166
+ title: 'Update include path in crates.gyp',
167
+ task: async(ctx, task) => {
168
+ const filePath = path.join(ctx.nodeDir, nodeCratesDir, 'crates.gyp');
169
+ let gyp = await fs.readFile(filePath, 'utf8');
170
+ const [definition, currentDirectory] = gyp.match(/'temporal_capi_dir': '(.+?)'/);
171
+ if (currentDirectory === ctx.temporalCAPIDirectory) {
172
+ task.skip('crates.gyp already up-to-date');
173
+ return;
174
+ }
175
+ gyp = gyp.replace(definition, `'temporal_capi_dir': '${ctx.temporalCAPIDirectory}'`);
176
+ await fs.writeFile(filePath, gyp);
177
+ }
178
+ };
179
+ }
180
+
181
+ function commitChanges() {
182
+ return {
183
+ title: 'Commit changes',
184
+ task: async(ctx) => {
185
+ await ctx.execGitNode('add', ['--force', 'deps/crates']);
186
+ await ctx.execGitNode(
187
+ 'commit',
188
+ ['-m', `deps: update Rust crates for V8 ${ctx.newVersion}`]
189
+ );
190
+ }
191
+ };
192
+ }
@@ -10,7 +10,7 @@ export default function updateV8Clone() {
10
10
  return task.newListr([fetchOrigin(), createClone()]);
11
11
  }
12
12
  };
13
- };
13
+ }
14
14
 
15
15
  function fetchOrigin() {
16
16
  return {
@@ -1,8 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import { promises as fs } from 'node:fs';
3
3
 
4
- import { getNodeV8Version } from './util.js';
5
-
6
4
  export default function updateVersionNumbers() {
7
5
  return {
8
6
  title: 'Update version numbers',
@@ -10,16 +8,15 @@ export default function updateVersionNumbers() {
10
8
  return task.newListr([resetEmbedderString(), bumpNodeModule()]);
11
9
  }
12
10
  };
13
- };
11
+ }
14
12
 
15
13
  function bumpNodeModule() {
16
14
  return {
17
15
  title: 'Bump NODE_MODULE_VERSION',
18
16
  task: async(ctx) => {
19
- const v8Version = await getNodeV8Version(ctx.nodeDir);
20
17
  const newModuleVersion = await updateModuleVersionRegistry(
21
18
  ctx.nodeDir,
22
- v8Version,
19
+ ctx.newVersion,
23
20
  ctx.nodeMajorVersion
24
21
  );
25
22
  await updateModuleVersion(ctx.nodeDir, newModuleVersion);
@@ -33,7 +30,7 @@ function bumpNodeModule() {
33
30
  '-m',
34
31
  getCommitTitle(newModuleVersion),
35
32
  '-m',
36
- getCommitBody(v8Version)
33
+ getCommitBody(ctx.newVersion)
37
34
  ]
38
35
  );
39
36
  },
@@ -23,10 +23,10 @@ export async function getNodeV8Version(cwd) {
23
23
  : `${this.major}.${this.minor}.${this.build}`;
24
24
  }
25
25
  };
26
- } catch (e) {
27
- throw new Error('Could not find V8 version');
26
+ } catch (cause) {
27
+ throw new Error('Could not find V8 version', { cause });
28
28
  }
29
- };
29
+ }
30
30
 
31
31
  export function filterForVersion(list, version) {
32
32
  return list.filter((dep) => {