@npmcli/template-oss 4.21.4 → 4.23.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 (50) hide show
  1. package/bin/apply.js +2 -5
  2. package/bin/check.js +2 -4
  3. package/bin/release-manager.js +1 -1
  4. package/bin/release-please.js +22 -18
  5. package/lib/apply/apply-files.js +14 -19
  6. package/lib/apply/apply-version.js +1 -5
  7. package/lib/apply/index.js +1 -4
  8. package/lib/check/check-apply.js +38 -39
  9. package/lib/check/check-changelog.js +1 -4
  10. package/lib/check/check-engines.js +5 -6
  11. package/lib/check/check-gitignore.js +14 -14
  12. package/lib/check/check-required.js +13 -15
  13. package/lib/check/check-unwanted.js +2 -3
  14. package/lib/check/index.js +9 -8
  15. package/lib/config.js +86 -35
  16. package/lib/content/LICENSE-md.hbs +2 -2
  17. package/lib/content/_job-matrix-yml.hbs +10 -0
  18. package/lib/content/_job-release-integration-yml.hbs +5 -10
  19. package/lib/content/_step-git-yml.hbs +1 -1
  20. package/lib/content/_step-node-yml.hbs +1 -1
  21. package/lib/content/action-create-check-yml.hbs +1 -1
  22. package/lib/content/ci-release-yml.hbs +2 -2
  23. package/lib/content/eslintrc-js.hbs +4 -5
  24. package/lib/content/gitignore.hbs +0 -3
  25. package/lib/content/index.js +39 -38
  26. package/lib/content/package-json.hbs +12 -2
  27. package/lib/content/prettier-js.hbs +6 -0
  28. package/lib/content/prettierignore.hbs +3 -0
  29. package/lib/content/release-yml.hbs +3 -3
  30. package/lib/index.js +3 -3
  31. package/lib/release/changelog.js +41 -44
  32. package/lib/release/node-workspace-format.js +29 -16
  33. package/lib/release/release-manager.js +61 -76
  34. package/lib/release/release-please.js +50 -61
  35. package/lib/release/util.js +11 -8
  36. package/lib/util/ci-versions.js +3 -3
  37. package/lib/util/dependabot.js +2 -2
  38. package/lib/util/files.js +34 -32
  39. package/lib/util/git.js +8 -5
  40. package/lib/util/gitignore.js +13 -11
  41. package/lib/util/has-package.js +7 -12
  42. package/lib/util/import-or-require.js +1 -1
  43. package/lib/util/json-diff.js +22 -21
  44. package/lib/util/merge.js +19 -16
  45. package/lib/util/output.js +8 -5
  46. package/lib/util/parser.js +86 -70
  47. package/lib/util/path.js +4 -4
  48. package/lib/util/template.js +13 -9
  49. package/package.json +13 -8
  50. package/lib/release/node-workspace.js +0 -103
@@ -27,7 +27,7 @@ const traverse = (value, visit, keys = []) => {
27
27
  }
28
28
  }
29
29
 
30
- const fsOk = (code) => (error) => {
30
+ const fsOk = code => error => {
31
31
  if (error.code === 'ENOENT') {
32
32
  return null
33
33
  }
@@ -37,101 +37,114 @@ const fsOk = (code) => (error) => {
37
37
  class Base {
38
38
  static types = []
39
39
  static header = 'This file is automatically added by {{ __NAME__ }}. Do not edit.'
40
- comment = (v) => v
40
+ comment = v => v
41
41
  merge = false // supply a merge function which runs on prepare for certain types
42
42
  DELETE = template.DELETE
43
43
 
44
- constructor (target, source, options, fileOptions) {
44
+ constructor(target, source, options, fileOptions) {
45
45
  this.target = target
46
46
  this.source = source
47
47
  this.options = options
48
48
  this.fileOptions = fileOptions
49
49
  }
50
50
 
51
- header () {
51
+ header() {
52
52
  if (typeof this.comment === 'function') {
53
53
  return this.comment(this.template(this.constructor.header || ''))
54
54
  }
55
55
  }
56
56
 
57
- clean () {
57
+ clean() {
58
58
  if (this.fileOptions.clean) {
59
59
  return fs.rm(this.target).catch(fsOk())
60
60
  }
61
61
  return null
62
62
  }
63
63
 
64
- read (s) {
64
+ read(s) {
65
+ if (Array.isArray(s)) {
66
+ return Promise.all(s.map(f => this.read(f)))
67
+ }
65
68
  return fs.readFile(s, { encoding: 'utf-8' })
66
69
  }
67
70
 
68
- template (s) {
71
+ template(s) {
72
+ if (Array.isArray(s)) {
73
+ return Promise.all(s.map(f => this.template(f)))
74
+ }
69
75
  return template(s, this.options)
70
76
  }
71
77
 
72
- parse (s) {
78
+ parse(s) {
73
79
  return s
74
80
  }
75
81
 
76
- prepare (s) {
82
+ prepare(s) {
77
83
  const header = this.header()
78
84
  return header ? `${header}\n\n${s}` : s
79
85
  }
80
86
 
81
- prepareTarget (s) {
87
+ prepareTarget(s) {
82
88
  return s
83
89
  }
84
90
 
85
- toString (s) {
91
+ toString(s) {
86
92
  return s.toString()
87
93
  }
88
94
 
89
- async write (s) {
95
+ async write(s) {
90
96
  // XXX: find more efficient way to do this. we can build all possible dirs before get here
91
97
  await fs.mkdir(dirname(this.target), { owner: 'inherit', recursive: true, force: true })
92
98
  return fs.writeFile(this.target, this.toString(s), { owner: 'inherit' })
93
99
  }
94
100
 
95
- diffPatch (t, s) {
101
+ diffPatch(t, s) {
96
102
  // create a patch and strip out the filename. if it ends up an empty string
97
103
  // then return true since the files are equal
98
- return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n'))
99
- .split('\n').slice(4).join('\n')
104
+ return Diff.createPatch('', t.replace(/\r\n/g, '\n'), s.replace(/\r\n/g, '\n')).split('\n').slice(4).join('\n')
100
105
  }
101
106
 
102
- diff (t, s) {
107
+ diff(t, s) {
103
108
  return this.diffPatch(t, s)
104
109
  }
105
110
 
106
111
  // the apply methods are the only ones that should be called publically
107
112
  // XXX: everything is allowed to be overridden in base classes but we could
108
113
  // find a different solution than making everything public
109
- applyWrite () {
110
- return Promise.resolve(this.clean())
111
- .then(() => this.read(this.source))
112
- // replace template vars first, this will throw for nonexistant vars
113
- // because it must be parseable after this step
114
- .then((s) => this.template(s))
115
- // parse into whatever data structure is necessary for maniuplating
116
- // diffing, merging, etc. by default its a string
117
- .then((s) => {
118
- this.sourcePreParse = s
119
- return this.parse(s)
120
- })
121
- // prepare the source for writing and diffing, pass in current
122
- // target for merging. errors parsing or preparing targets are ok here
123
- .then((s) => this.applyTarget().catch(() => null).then((t) => this.prepare(s, t)))
124
- .then((s) => this.write(s))
125
- }
126
-
127
- applyTarget () {
128
- return Promise.resolve(this.read(this.target))
129
- .then((s) => this.parse(s))
130
- // for only preparing the target for diffing
131
- .then((s) => this.prepareTarget(s))
132
- }
133
-
134
- async applyDiff () {
114
+ applyWrite() {
115
+ return (
116
+ Promise.resolve(this.clean())
117
+ .then(() => this.read(this.source))
118
+ // replace template vars first, this will throw for nonexistant vars
119
+ // because it must be parseable after this step
120
+ .then(s => this.template(s))
121
+ // parse into whatever data structure is necessary for maniuplating
122
+ // diffing, merging, etc. by default its a string
123
+ .then(s => {
124
+ this.sourcePreParse = s
125
+ return this.parse(s)
126
+ })
127
+ // prepare the source for writing and diffing, pass in current
128
+ // target for merging. errors parsing or preparing targets are ok here
129
+ .then(s =>
130
+ this.applyTarget()
131
+ .catch(() => null)
132
+ .then(t => this.prepare(s, t)),
133
+ )
134
+ .then(s => this.write(s))
135
+ )
136
+ }
137
+
138
+ applyTarget() {
139
+ return (
140
+ Promise.resolve(this.read(this.target))
141
+ .then(s => this.parse(s))
142
+ // for only preparing the target for diffing
143
+ .then(s => this.prepareTarget(s))
144
+ )
145
+ }
146
+
147
+ async applyDiff() {
135
148
  // handle if old does not exist
136
149
  const targetError = 'ETARGETERROR'
137
150
  const target = await this.applyTarget().catch(fsOk(targetError))
@@ -142,10 +155,10 @@ class Base {
142
155
  }
143
156
 
144
157
  const source = await Promise.resolve(this.read(this.source))
145
- .then((s) => this.template(s))
146
- .then((s) => this.parse(s))
158
+ .then(s => this.template(s))
159
+ .then(s => this.parse(s))
147
160
  // gets the target to diff against in case it needs to merge, etc
148
- .then((s) => this.prepare(s, target))
161
+ .then(s => this.prepare(s, target))
149
162
 
150
163
  // if there was a target error then there is no need to diff
151
164
  // so we just show the source with an error message
@@ -168,28 +181,28 @@ class Base {
168
181
  }
169
182
 
170
183
  class Gitignore extends Base {
171
- static types = ['codeowners', '.gitignore']
172
- comment = (c) => `# ${c}`
184
+ static types = ['codeowners', '.gitignore', '.prettierignore']
185
+ comment = c => `# ${c}`
173
186
  }
174
187
 
175
188
  class Js extends Base {
176
189
  static types = ['*.js', '*.cjs']
177
- comment = (c) => `/* ${c} */`
190
+ comment = c => `/* ${c} */`
178
191
  }
179
192
 
180
193
  class Ini extends Base {
181
194
  static types = ['*.ini']
182
- comment = (c) => `; ${c}`
195
+ comment = c => `; ${c}`
183
196
 
184
- toString (s) {
197
+ toString(s) {
185
198
  return typeof s === 'string' ? s : ini.stringify(s)
186
199
  }
187
200
 
188
- parse (s) {
201
+ parse(s) {
189
202
  return typeof s === 'string' ? ini.parse(s) : s
190
203
  }
191
204
 
192
- prepare (s, t) {
205
+ prepare(s, t) {
193
206
  let source = s
194
207
  if (typeof this.merge === 'function' && t) {
195
208
  source = this.merge(t, s)
@@ -197,7 +210,7 @@ class Ini extends Base {
197
210
  return super.prepare(this.toString(source))
198
211
  }
199
212
 
200
- diff (t, s) {
213
+ diff(t, s) {
201
214
  return jsonDiff(this.parse(t), this.parse(s), this.DELETE)
202
215
  }
203
216
  }
@@ -209,14 +222,14 @@ class IniMerge extends Ini {
209
222
 
210
223
  class Markdown extends Base {
211
224
  static types = ['*.md']
212
- comment = (c) => `<!-- ${c} -->`
225
+ comment = c => `<!-- ${c} -->`
213
226
  }
214
227
 
215
228
  class Yml extends Base {
216
229
  static types = ['*.yml']
217
- comment = (c) => ` ${c}`
230
+ comment = c => ` ${c}`
218
231
 
219
- toString (s) {
232
+ toString(s) {
220
233
  try {
221
234
  return s.toString({ lineWidth: 0, indent: 2 })
222
235
  } catch (err) {
@@ -225,22 +238,22 @@ class Yml extends Base {
225
238
  }
226
239
  }
227
240
 
228
- parse (s) {
241
+ parse(s) {
229
242
  return yaml.parseDocument(s)
230
243
  }
231
244
 
232
- prepare (s) {
245
+ prepare(s) {
233
246
  s.commentBefore = this.header()
234
247
  return this.toString(s)
235
248
  }
236
249
 
237
- prepareTarget (s) {
250
+ prepareTarget(s) {
238
251
  return this.toString(s)
239
252
  }
240
253
  }
241
254
 
242
255
  class YmlMerge extends Yml {
243
- prepare (source, t) {
256
+ prepare(source, t) {
244
257
  if (t === null) {
245
258
  // If target does not exist or is in an
246
259
  // error state, we cant do anything but write
@@ -250,7 +263,7 @@ class YmlMerge extends Yml {
250
263
 
251
264
  const key = [].concat(this.key)
252
265
 
253
- const getId = (node) => {
266
+ const getId = node => {
254
267
  const index = node.items.findIndex(p => p.key?.value === this.id)
255
268
  return index !== -1 ? node.items[index].value?.value : node.toJSON()
256
269
  }
@@ -278,17 +291,20 @@ class Json extends Base {
278
291
  static types = ['*.json']
279
292
  // its a json comment! not really but we do add a special key
280
293
  // to json objects
281
- comment = (c) => ({ [`//${this.options.config.__NAME__}`]: c })
294
+ comment = c => ({ [`//${this.options.config.__NAME__}`]: c })
282
295
 
283
- toString (s) {
284
- return JSON.stringify(s, (_, v) => v === this.DELETE ? undefined : v, 2).trim() + '\n'
296
+ toString(s) {
297
+ return JSON.stringify(s, (_, v) => (v === this.DELETE ? undefined : v), 2).trim() + '\n'
285
298
  }
286
299
 
287
- parse (s) {
300
+ parse(s) {
301
+ if (Array.isArray(s)) {
302
+ return s.map(f => this.parse(f)).reduce((a, f) => this.merge(a, f), {})
303
+ }
288
304
  return jsonParse(s)
289
305
  }
290
306
 
291
- prepare (s, t) {
307
+ prepare(s, t) {
292
308
  let source = s
293
309
  if (typeof this.merge === 'function' && t) {
294
310
  source = this.merge(t, s)
@@ -296,7 +312,7 @@ class Json extends Base {
296
312
  return setFirst(this.header(), source)
297
313
  }
298
314
 
299
- diff (t, s) {
315
+ diff(t, s) {
300
316
  return jsonDiff(t, s, this.DELETE)
301
317
  }
302
318
  }
@@ -313,7 +329,7 @@ class JsonMergeNoComment extends JsonMerge {
313
329
  class PackageJson extends JsonMerge {
314
330
  static types = ['package.json']
315
331
 
316
- async prepare (s, t) {
332
+ async prepare(s, t) {
317
333
  // merge new source with current pkg content
318
334
  const update = super.prepare(s, t)
319
335
 
@@ -327,7 +343,7 @@ class PackageJson extends JsonMerge {
327
343
  return update
328
344
  }
329
345
 
330
- async write (s) {
346
+ async write(s) {
331
347
  const pkg = await NpmPackageJson.load(dirname(this.target))
332
348
  pkg.update(s)
333
349
  traverse(pkg.content, (keys, value) => {
@@ -369,7 +385,7 @@ for (const parser of Object.values(Parsers)) {
369
385
  }
370
386
  }
371
387
 
372
- const getParser = (file) => {
388
+ const getParser = file => {
373
389
  for (const [type, parser] of parserLookup) {
374
390
  if (minimatch(file, type, { nocase: true, dot: true, matchBase: true })) {
375
391
  return parser
package/lib/util/path.js CHANGED
@@ -1,9 +1,9 @@
1
1
  const { posix, win32 } = require('path')
2
2
 
3
- const makePosix = (v) => v.split(win32.sep).join(posix.sep)
4
- const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
5
- const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
6
- const posixGlob = (str) => `${posixDir(str)}**`
3
+ const makePosix = v => v.split(win32.sep).join(posix.sep)
4
+ const deglob = v => makePosix(v).replace(/[/*]+$/, '')
5
+ const posixDir = v => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
6
+ const posixGlob = str => `${posixDir(str)}**`
7
7
 
8
8
  module.exports = {
9
9
  makePosix,
@@ -1,14 +1,15 @@
1
1
  const Handlebars = require('handlebars')
2
2
  const { basename, extname, join } = require('path')
3
+ const { Range } = require('semver')
3
4
  const fs = require('fs')
4
5
  const DELETE = '__DELETE__'
5
6
 
6
- const safeValues = (obj) => Object.entries(obj).map(([key, value]) =>
7
- [key, new Handlebars.SafeString(value)])
7
+ const safeValues = obj => Object.entries(obj).map(([key, value]) => [key, new Handlebars.SafeString(value)])
8
8
 
9
- const partialName = (s) => basename(s, extname(s)) // remove extension
10
- .replace(/^_/, '') // remove leading underscore
11
- .replace(/-([a-z])/g, (_, g) => g.toUpperCase()) // camelcase
9
+ const partialName = s =>
10
+ basename(s, extname(s)) // remove extension
11
+ .replace(/^_/, '') // remove leading underscore
12
+ .replace(/-([a-z])/g, (_, g) => g.toUpperCase()) // camelcase
12
13
 
13
14
  const makePartials = (dir, isBase) => {
14
15
  const partials = fs.readdirSync(dir).reduce((acc, f) => {
@@ -31,14 +32,17 @@ const makePartials = (dir, isBase) => {
31
32
  Handlebars.registerPartial(partials)
32
33
  }
33
34
 
34
- const setupHandlebars = (dirs) => {
35
+ const setupHandlebars = dirs => {
35
36
  Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
37
+ Handlebars.registerHelper('extGlob', arr => `{${arr.join(',')}}`)
36
38
  Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
37
39
  Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
38
- Handlebars.registerHelper('quote', (arr) => arr.map(a => `'${a}'`))
39
- Handlebars.registerHelper('last', (arr) => arr[arr.length - 1])
40
- Handlebars.registerHelper('json', (c) => JSON.stringify(c))
40
+ Handlebars.registerHelper('quote', arr => arr.map(a => `'${a}'`))
41
+ Handlebars.registerHelper('last', arr => arr[arr.length - 1])
42
+ Handlebars.registerHelper('json', c => JSON.stringify(c))
41
43
  Handlebars.registerHelper('del', () => JSON.stringify(DELETE))
44
+ Handlebars.registerHelper('semverRangeMajor', v => new Range(v).set[0][0].semver.major)
45
+ Handlebars.registerHelper('lte', (a, b) => a <= b)
42
46
 
43
47
  if (Array.isArray(dirs)) {
44
48
  const [baseDir, ...otherDirs] = dirs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/template-oss",
3
- "version": "4.21.4",
3
+ "version": "4.23.0",
4
4
  "description": "templated files used in npm CLI team oss projects",
5
5
  "main": "lib/content/index.js",
6
6
  "bin": {
@@ -10,21 +10,22 @@
10
10
  "template-oss-release-manager": "bin/release-manager.js"
11
11
  },
12
12
  "scripts": {
13
- "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
14
- "lintfix": "npm run lint -- --fix",
13
+ "lint": "npm run eslint && npm run prettier -- --check",
14
+ "lintfix": "npm run eslint -- --fix && npm run prettier -- --write",
15
15
  "posttest": "npm run lint",
16
16
  "snap": "tap",
17
17
  "test": "tap",
18
18
  "template-oss-apply": "template-oss-apply --force",
19
19
  "postlint": "template-oss-check",
20
20
  "postinstall": "template-oss-apply",
21
+ "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
22
+ "prettier": "prettier \"**/*.{js,cjs,ts,mjs,jsx,tsx,json}\"",
21
23
  "test-all": "npm run test -ws -iwr --if-present",
22
- "lint-all": "npm run lint -ws -iwr --if-present",
23
- "test:record": "TAP_SNAPSHOT=1 NOCK_RECORD=1 tap"
24
+ "lint-all": "npm run lint -ws -iwr --if-present"
24
25
  },
25
26
  "repository": {
26
27
  "type": "git",
27
- "url": "https://github.com/npm/template-oss.git"
28
+ "url": "git+https://github.com/npm/template-oss.git"
28
29
  },
29
30
  "keywords": [
30
31
  "npm",
@@ -56,7 +57,7 @@
56
57
  "minimatch": "^9.0.2",
57
58
  "npm-package-arg": "^11.0.1",
58
59
  "proc-log": "^4.0.0",
59
- "release-please": "16.3.1",
60
+ "release-please": "16.12.0",
60
61
  "semver": "^7.3.5",
61
62
  "undici": "^6.7.0",
62
63
  "yaml": "^2.1.1"
@@ -66,9 +67,12 @@
66
67
  "lib/"
67
68
  ],
68
69
  "devDependencies": {
70
+ "@github/prettier-config": "0.0.6",
69
71
  "@npmcli/eslint-config": "^4.0.0",
70
72
  "@npmcli/template-oss": "file:./",
73
+ "eslint-config-prettier": "^9.1.0",
71
74
  "nock": "^13.3.8",
75
+ "prettier": "^3.2.5",
72
76
  "tap": "^16.0.0"
73
77
  },
74
78
  "tap": {
@@ -86,7 +90,8 @@
86
90
  },
87
91
  "templateOSS": {
88
92
  "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
89
- "publish": true
93
+ "publish": true,
94
+ "prettier": true
90
95
  },
91
96
  "engines": {
92
97
  "node": "^18.17.0 || >=20.5.0"
@@ -1,103 +0,0 @@
1
- const { NodeWorkspace } = require('release-please/build/src/plugins/node-workspace')
2
- const { parseConventionalCommits } = require('release-please/build/src/commit')
3
- const { DEPS } = require('./util')
4
- const { WORKSPACE_MESSAGE } = require('./node-workspace-format')
5
-
6
- // This adds a preconfigure method to the release-please node-workspace plugin
7
- // which fixes https://github.com/googleapis/release-please/issues/2089 for our
8
- // use case. We should attempt to upstream this to release-please but it
9
- // fundamentally changes the way the node-workspace plugin behaves so it might
10
- // not be easy to land. For now we extend the base plugin and add one method
11
- // which is much better than previously when we needed to fork and maintain
12
- // release-please ourselves.
13
- /* istanbul ignore next: TODO fix flaky tests and enable coverage */
14
- class NpmNodeWorkspace extends NodeWorkspace {
15
- updateCandidate (pr) {
16
- // no-op so release-please node-workspace plugin does not add
17
- // its broken changelog to the workspace releases. our changelog
18
- // formatting and the preconfigure method below fix this.
19
- return pr
20
- }
21
-
22
- async preconfigure (strategiesByPath, commitsByPath, releasesByPath) {
23
- // First build a list of all releases that will happen based on the
24
- // conventional commits
25
- const candidates = []
26
- for (const path in strategiesByPath) {
27
- const pullRequest = await strategiesByPath[path].buildReleasePullRequest(
28
- parseConventionalCommits(commitsByPath[path]),
29
- releasesByPath[path]
30
- )
31
- // Release please types say this sometimes will return undefined but I could not
32
- // get any scenario where that was the case. If it was undefined we would want to
33
- // just ignore it anyway.
34
- /* istanbul ignore else */
35
- if (pullRequest) {
36
- candidates.push({
37
- path,
38
- pullRequest,
39
- config: this.repositoryConfig[path],
40
- })
41
- }
42
- }
43
-
44
- // Then build the graph of all those releases + any other connected workspaces
45
- const { allPackages, candidatesByPackage } = await this.buildAllPackages(candidates)
46
- const graph = await this.buildGraph(allPackages)
47
- const packageNamesToUpdate = this.packageNamesToUpdate(graph, candidatesByPackage)
48
- const graphPackages = this.buildGraphOrder(graph, packageNamesToUpdate)
49
-
50
- // Then build a list of all the updated versions
51
- const updatedVersions = {}
52
- for (const pkg of graphPackages) {
53
- const path = this.pathFromPackage(pkg)
54
- const packageName = this.packageNameFromPackage(pkg)
55
- const existingCandidate = candidatesByPackage[packageName]
56
-
57
- if (existingCandidate) {
58
- // If there is an existing pull request use that version
59
- updatedVersions[packageName] = existingCandidate.pullRequest?.version
60
- } else {
61
- // Otherwise build another pull request (that will be discarded) just
62
- // to see what the version would be if it only contained a deps commit.
63
- // This is to make sure we use any custom versioning or release strategy.
64
- const releasePullRequest = await strategiesByPath[path].buildReleasePullRequest(
65
- parseConventionalCommits([{ message: `${DEPS}: ${Math.random()}` }]),
66
- releasesByPath[path]
67
- )
68
- updatedVersions[packageName] = releasePullRequest?.version
69
- }
70
- }
71
-
72
- // Then go through all the packages again and add deps commits for each
73
- // updated workspace
74
- for (const pkg of graphPackages) {
75
- const path = this.pathFromPackage(pkg)
76
- const packageName = this.packageNameFromPackage(pkg)
77
- const graphPackage = graph.get(packageName)
78
-
79
- // Update dependency versions add a deps commit to each path so it gets
80
- // processed later. This else never happens in our cases because our
81
- // packages always have deps, but keeping this around to make it easier to
82
- // upstream in the future.
83
- /* istanbul ignore else */
84
- if (graphPackage.deps) {
85
- for (const depName of graphPackage.deps) {
86
- const depVersion = updatedVersions[depName]
87
- // Same as the above check, we always have a version here but technically
88
- // we could not in which it would be safe to ignore it.
89
- /* istanbul ignore else */
90
- if (depVersion) {
91
- commitsByPath[path].push({
92
- message: WORKSPACE_MESSAGE(depName, depVersion.toString()),
93
- })
94
- }
95
- }
96
- }
97
- }
98
-
99
- return strategiesByPath
100
- }
101
- }
102
-
103
- module.exports = NpmNodeWorkspace