@o/scripts 0.16.19 → 0.16.20-canary.1791848111568
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/package.json +5 -5
- package/src/ensure-zero-sqlite.ts +22 -24
- package/src/env-update.test.ts +72 -0
- package/src/env-update.ts +35 -28
- package/src/up.ts +47 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@o/scripts",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.20-canary.1791848111568",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/cmd.ts",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"lint": "oxlint src",
|
|
24
|
+
"test": "bun test src",
|
|
24
25
|
"lint:fix": "oxfmt src && oxlint --fix --fix-suggestions src",
|
|
25
26
|
"typecheck": "tko run typecheck"
|
|
26
27
|
},
|
|
@@ -29,8 +30,8 @@
|
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@clack/prompts": "^0.8.2",
|
|
32
|
-
"@o/helpers": "0.16.
|
|
33
|
-
"@o/run": "0.16.
|
|
33
|
+
"@o/helpers": "0.16.20-canary.1791848111568",
|
|
34
|
+
"@o/run": "0.16.20-canary.1791848111568",
|
|
34
35
|
"picocolors": "^1.1.1",
|
|
35
36
|
"@aws-sdk/client-s3": "^3.709.0",
|
|
36
37
|
"fs-extra": "^11.2.0",
|
|
@@ -52,6 +53,5 @@
|
|
|
52
53
|
"optional": true
|
|
53
54
|
}
|
|
54
55
|
},
|
|
55
|
-
"
|
|
56
|
-
"optionalDependencies": null
|
|
56
|
+
"releaseSourceCommit": "541e39001d511200c35f30786b84516ed2af9b5b"
|
|
57
57
|
}
|
|
@@ -1,31 +1,29 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process'
|
|
2
|
+
|
|
1
3
|
import { cmd } from './cmd'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
await cmd`ensure zero-sqlite3 native module is available`.run(() => {
|
|
6
|
+
const result = spawnSync(
|
|
7
|
+
'node',
|
|
8
|
+
[
|
|
9
|
+
'--input-type=commonjs',
|
|
10
|
+
'-e',
|
|
11
|
+
`const { createRequire } = require('node:module');
|
|
12
|
+
const { resolve } = require('node:path');
|
|
13
|
+
const load = createRequire(resolve('package.json'));
|
|
14
|
+
const Database = load('@rocicorp/zero-sqlite3');
|
|
15
|
+
const database = new Database(':memory:');
|
|
16
|
+
database.close();`,
|
|
17
|
+
],
|
|
18
|
+
{ stdio: 'inherit' }
|
|
19
|
+
)
|
|
5
20
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return
|
|
21
|
+
if (result.error) {
|
|
22
|
+
throw result.error
|
|
9
23
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// chain (`npm run install` = `prebuild-install || <binding exists?> ||
|
|
14
|
-
// node-gyp rebuild`), which prefers the PREBUILT binary and only source-builds
|
|
15
|
-
// as a last resort. @rocicorp/zero-sqlite3 >=1.1.2 is prebuilt-ONLY — its npm
|
|
16
|
-
// tarball omits generated headers (e.g. unicode_case_data.h), so a direct
|
|
17
|
-
// `npm run build-release` (node-gyp) fails; prebuild-install is the supported
|
|
18
|
-
// path. success is "the binding now exists" (the install chain can exit
|
|
19
|
-
// non-zero from a failed prebuild-install fallback even when an earlier step
|
|
20
|
-
// already produced the binding).
|
|
21
|
-
const result = await $`cd node_modules/@rocicorp/zero-sqlite3 && npm run install`
|
|
22
|
-
.quiet()
|
|
23
|
-
.nothrow()
|
|
24
|
-
|
|
25
|
-
if (!fs.existsSync(SQLITE_NODE_PATH)) {
|
|
26
|
-
console.error(
|
|
27
|
-
'zero-sqlite3 native module unavailable, will fall back to wasm:',
|
|
28
|
-
result.stderr.toString()
|
|
24
|
+
if (result.status !== 0) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
'zero-sqlite3 native module unavailable; install a compatible prebuilt for the current Node runtime'
|
|
29
27
|
)
|
|
30
28
|
}
|
|
31
29
|
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { afterEach, expect, test } from 'bun:test'
|
|
2
|
+
import { execFileSync } from 'node:child_process'
|
|
3
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
4
|
+
import { tmpdir } from 'node:os'
|
|
5
|
+
import { join, resolve } from 'node:path'
|
|
6
|
+
|
|
7
|
+
const script = resolve(import.meta.dir, 'env-update.ts')
|
|
8
|
+
const directories: string[] = []
|
|
9
|
+
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
for (const directory of directories.splice(0)) {
|
|
12
|
+
rmSync(directory, { recursive: true, force: true })
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('preserves explicit workflow bindings per block while adding new keys', () => {
|
|
17
|
+
const directory = mkdtempSync(join(tmpdir(), 'o-env-update-'))
|
|
18
|
+
directories.push(directory)
|
|
19
|
+
mkdirSync(join(directory, 'src'))
|
|
20
|
+
mkdirSync(join(directory, '.github/workflows'), { recursive: true })
|
|
21
|
+
writeFileSync(join(directory, 'package.json'), '{}')
|
|
22
|
+
writeFileSync(
|
|
23
|
+
join(directory, 'src/env.ts'),
|
|
24
|
+
`export const production = {
|
|
25
|
+
NEW_SERVICE_KEY: Symbol.for('take-out/env/expected'),
|
|
26
|
+
UNCHANGED_KEY: Symbol.for('take-out/env/expected'),
|
|
27
|
+
ADDED_KEY: Symbol.for('take-out/env/expected'),
|
|
28
|
+
}
|
|
29
|
+
export const versions = { ZERO_VERSION: '1.9.0' }
|
|
30
|
+
`
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const workflow = join(directory, '.github/workflows/deploy.yml')
|
|
34
|
+
const initial = `jobs:
|
|
35
|
+
production:
|
|
36
|
+
env:
|
|
37
|
+
# 🔒 start - this is generated by "bun env:update"
|
|
38
|
+
NEW_SERVICE_KEY: \${{ secrets.DEPLOYED_SERVICE_KEY }}
|
|
39
|
+
UNCHANGED_KEY: \${{ secrets.UNCHANGED_KEY }}
|
|
40
|
+
ZERO_VERSION: \${{ secrets.ZERO_VERSION }}
|
|
41
|
+
REMOVED_KEY: \${{ secrets.REMOVED_KEY }}
|
|
42
|
+
# 🔒 end - this is generated by "bun env:update"
|
|
43
|
+
staging:
|
|
44
|
+
env:
|
|
45
|
+
# 🔒 start - this is generated by "bun env:update"
|
|
46
|
+
NEW_SERVICE_KEY: '\${{ secrets.STAGING_SERVICE_KEY }}' # explicit staging binding
|
|
47
|
+
UNCHANGED_KEY: \${{ secrets.UNCHANGED_KEY }}
|
|
48
|
+
# 🔒 end - this is generated by "bun env:update"
|
|
49
|
+
`
|
|
50
|
+
writeFileSync(workflow, initial)
|
|
51
|
+
|
|
52
|
+
const run = () => execFileSync(process.execPath, [script], { cwd: directory })
|
|
53
|
+
run()
|
|
54
|
+
const generated = readFileSync(workflow, 'utf8')
|
|
55
|
+
const expected = initial
|
|
56
|
+
.replaceAll(
|
|
57
|
+
' NEW_SERVICE_KEY:',
|
|
58
|
+
' ADDED_KEY: ${{ secrets.ADDED_KEY }}\n NEW_SERVICE_KEY:'
|
|
59
|
+
)
|
|
60
|
+
.replace('ZERO_VERSION: ${{ secrets.ZERO_VERSION }}', "ZERO_VERSION: '1.9.0'")
|
|
61
|
+
.replace(' REMOVED_KEY: ${{ secrets.REMOVED_KEY }}\n', '')
|
|
62
|
+
// the version is generated in every block, including newly populated blocks.
|
|
63
|
+
expect(generated).toBe(
|
|
64
|
+
expected.replace(
|
|
65
|
+
' UNCHANGED_KEY: ${{ secrets.UNCHANGED_KEY }}\n # 🔒 end',
|
|
66
|
+
" UNCHANGED_KEY: ${{ secrets.UNCHANGED_KEY }}\n ZERO_VERSION: '1.9.0'\n # 🔒 end"
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
run()
|
|
71
|
+
expect(readFileSync(workflow, 'utf8')).toBe(generated)
|
|
72
|
+
})
|
package/src/env-update.ts
CHANGED
|
@@ -201,49 +201,56 @@ await cmd`sync environment variables from src/env.ts to matching files`
|
|
|
201
201
|
content: string,
|
|
202
202
|
startMarker: string,
|
|
203
203
|
endMarker: string,
|
|
204
|
-
newSection: string
|
|
204
|
+
newSection: string | ((section: string, indent: string) => string)
|
|
205
205
|
): string {
|
|
206
206
|
const re = new RegExp(
|
|
207
207
|
`^([ \\t]*)${escapeRegExp(startMarker)}(.|\n)*?${escapeRegExp(endMarker)}`,
|
|
208
208
|
'gm'
|
|
209
209
|
)
|
|
210
|
-
return content.replace(re, (
|
|
211
|
-
|
|
210
|
+
return content.replace(re, (match, indent) => {
|
|
211
|
+
const section =
|
|
212
|
+
typeof newSection === 'function' ? newSection(match, indent) : newSection
|
|
213
|
+
return `${indent}${startMarker}\n${section}\n${indent}${endMarker}`
|
|
212
214
|
})
|
|
213
215
|
}
|
|
214
216
|
|
|
215
217
|
function applyYamlMarkers(filePath: string, content: string): string {
|
|
216
|
-
const markerMatch = content.match(
|
|
217
|
-
new RegExp(`^(\\s*)${escapeRegExp(yamlStart)}`, 'm')
|
|
218
|
-
)
|
|
219
|
-
const indent = markerMatch?.[1] || ' '
|
|
220
|
-
|
|
221
218
|
const beforeMarker = content.slice(0, content.indexOf(yamlStart))
|
|
222
219
|
const isMap = /x-[\w-]+:.*&[\w-]+/s.test(beforeMarker)
|
|
223
220
|
const isGithubActions = filePath.includes('.github/workflows')
|
|
224
221
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
// secret once pinned an old zero-cache protocol against a newer
|
|
234
|
-
// client). matches the .env codegen below, which already does this.
|
|
235
|
-
return dep
|
|
236
|
-
? `${indent}${key}: '${dep}'`
|
|
237
|
-
: `${indent}${key}: \${{ secrets.${key} }}`
|
|
222
|
+
return replaceMarkerSection(content, yamlStart, yamlEnd, (section, indent) => {
|
|
223
|
+
// bindings belong to their block; jobs may use different deployed secrets.
|
|
224
|
+
const bindings = new Map<string, string>()
|
|
225
|
+
if (isGithubActions) {
|
|
226
|
+
for (const match of section.matchAll(
|
|
227
|
+
/^[ \t]*([A-Za-z_][\w]*):[ \t]*(\S[^\r\n]*)/gm
|
|
228
|
+
)) {
|
|
229
|
+
bindings.set(match[1]!, match[2]!)
|
|
238
230
|
}
|
|
231
|
+
}
|
|
239
232
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
233
|
+
return entries
|
|
234
|
+
.map(({ key, defaultValue }) => {
|
|
235
|
+
const dep = depResolved[key]
|
|
236
|
+
const val = dep || defaultValue
|
|
237
|
+
|
|
238
|
+
if (isGithubActions) {
|
|
239
|
+
// deps-derived versions track package.json — emit a literal so a
|
|
240
|
+
// stale repo secret can never shadow them (a stale ZERO_VERSION
|
|
241
|
+
// secret once pinned an old zero-cache protocol against a newer
|
|
242
|
+
// client). matches the .env codegen below, which already does this.
|
|
243
|
+
return dep
|
|
244
|
+
? `${indent}${key}: '${dep}'`
|
|
245
|
+
: `${indent}${key}: ${bindings.get(key) ?? `\${{ secrets.${key} }}`}`
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return isMap
|
|
249
|
+
? `${indent}${key}: \${${key}:-${val}}`
|
|
250
|
+
: `${indent}- ${key}=\${${key}:-${val}}`
|
|
251
|
+
})
|
|
252
|
+
.join('\n')
|
|
253
|
+
})
|
|
247
254
|
}
|
|
248
255
|
|
|
249
256
|
function applyDotenvSection(_filePath: string, content: string): string {
|
package/src/up.ts
CHANGED
|
@@ -7,6 +7,9 @@ interface PackageJson {
|
|
|
7
7
|
devDependencies?: Record<string, string>
|
|
8
8
|
peerDependencies?: Record<string, string>
|
|
9
9
|
optionalDependencies?: Record<string, string>
|
|
10
|
+
workspaces?: string[] | { packages?: string[] }
|
|
11
|
+
upgradePackageJsonGlobs?: string[]
|
|
12
|
+
upgradeSets?: Record<string, string[]>
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
await cmd`upgrade packages by name or pattern`
|
|
@@ -22,6 +25,9 @@ await cmd`upgrade packages by name or pattern`
|
|
|
22
25
|
fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8')
|
|
23
26
|
)
|
|
24
27
|
const upgradeSets: Record<string, string[]> = rootPackageJson.upgradeSets || {}
|
|
28
|
+
const upgradePackageJsonGlobs = Array.isArray(rootPackageJson.upgradePackageJsonGlobs)
|
|
29
|
+
? rootPackageJson.upgradePackageJsonGlobs
|
|
30
|
+
: []
|
|
25
31
|
|
|
26
32
|
for (const arg of args.rest) {
|
|
27
33
|
if (arg in upgradeSets) {
|
|
@@ -48,18 +54,30 @@ await cmd`upgrade packages by name or pattern`
|
|
|
48
54
|
process.exit(1)
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
function findPackageJsonFiles(
|
|
57
|
+
function findPackageJsonFiles(
|
|
58
|
+
dir: string,
|
|
59
|
+
extraPackageJsonGlobs = upgradePackageJsonGlobs
|
|
60
|
+
): string[] {
|
|
52
61
|
const results: string[] = []
|
|
62
|
+
const seen = new Set<string>()
|
|
63
|
+
|
|
64
|
+
const addPackageJson = (packageJsonPath: string) => {
|
|
65
|
+
if (seen.has(packageJsonPath)) return
|
|
66
|
+
seen.add(packageJsonPath)
|
|
67
|
+
results.push(packageJsonPath)
|
|
68
|
+
}
|
|
53
69
|
|
|
54
70
|
if (fs.existsSync(path.join(dir, 'package.json'))) {
|
|
55
|
-
|
|
71
|
+
addPackageJson(path.join(dir, 'package.json'))
|
|
56
72
|
}
|
|
57
73
|
|
|
58
74
|
// check if it's a monorepo with workspaces
|
|
59
75
|
try {
|
|
60
76
|
const packageJson = JSON.parse(
|
|
61
77
|
fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')
|
|
62
|
-
)
|
|
78
|
+
) as PackageJson
|
|
79
|
+
const packageJsonGlobs = [...extraPackageJsonGlobs]
|
|
80
|
+
|
|
63
81
|
if (packageJson.workspaces) {
|
|
64
82
|
let workspacePaths: string[] = []
|
|
65
83
|
|
|
@@ -69,9 +87,15 @@ await cmd`upgrade packages by name or pattern`
|
|
|
69
87
|
workspacePaths = packageJson.workspaces.packages
|
|
70
88
|
}
|
|
71
89
|
|
|
72
|
-
|
|
90
|
+
packageJsonGlobs.unshift(...workspacePaths)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (packageJsonGlobs.length > 0) {
|
|
94
|
+
for (const workspace of packageJsonGlobs) {
|
|
73
95
|
// handle glob patterns like "packages/*", "code/**/*", "./code/ui/**/*"
|
|
74
|
-
const normalizedWorkspace = workspace
|
|
96
|
+
const normalizedWorkspace = workspace
|
|
97
|
+
.replace(/^\.\//, '')
|
|
98
|
+
.replace(/\/package\.json$/, '')
|
|
75
99
|
|
|
76
100
|
if (normalizedWorkspace.includes('**')) {
|
|
77
101
|
// nested glob pattern - use glob to find all package.json files
|
|
@@ -87,7 +111,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
87
111
|
const subPath = path.join(searchDir, entry.name)
|
|
88
112
|
const pkgPath = path.join(subPath, 'package.json')
|
|
89
113
|
if (fs.existsSync(pkgPath)) {
|
|
90
|
-
|
|
114
|
+
addPackageJson(pkgPath)
|
|
91
115
|
}
|
|
92
116
|
// recurse into subdirectories
|
|
93
117
|
findPackages(subPath)
|
|
@@ -112,7 +136,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
112
136
|
|
|
113
137
|
for (const subdir of subdirs) {
|
|
114
138
|
if (fs.existsSync(path.join(subdir, 'package.json'))) {
|
|
115
|
-
|
|
139
|
+
addPackageJson(path.join(subdir, 'package.json'))
|
|
116
140
|
}
|
|
117
141
|
}
|
|
118
142
|
}
|
|
@@ -120,7 +144,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
120
144
|
// exact path like "code/tamagui.dev" or "./code/sandbox"
|
|
121
145
|
const pkgPath = path.join(dir, normalizedWorkspace, 'package.json')
|
|
122
146
|
if (fs.existsSync(pkgPath)) {
|
|
123
|
-
|
|
147
|
+
addPackageJson(pkgPath)
|
|
124
148
|
}
|
|
125
149
|
}
|
|
126
150
|
}
|
|
@@ -219,7 +243,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
219
243
|
}
|
|
220
244
|
|
|
221
245
|
async function updatePackages(
|
|
222
|
-
|
|
246
|
+
packagesByManifest: Map<string, { dir: string; packages: string[] }>,
|
|
223
247
|
rootDir: string,
|
|
224
248
|
packageJsonFiles: string[]
|
|
225
249
|
) {
|
|
@@ -234,7 +258,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
234
258
|
|
|
235
259
|
// collect all unique packages to update
|
|
236
260
|
const allPackages = new Set<string>()
|
|
237
|
-
for (const { packages } of
|
|
261
|
+
for (const { packages } of packagesByManifest.values()) {
|
|
238
262
|
packages.forEach((pkg) => allPackages.add(pkg))
|
|
239
263
|
}
|
|
240
264
|
|
|
@@ -272,14 +296,14 @@ await cmd`upgrade packages by name or pattern`
|
|
|
272
296
|
let totalUpdates = 0
|
|
273
297
|
|
|
274
298
|
for (const packageJsonPath of packageJsonFiles) {
|
|
275
|
-
const
|
|
276
|
-
|
|
299
|
+
const packagesInManifest =
|
|
300
|
+
packagesByManifest.get(getWorkspaceName(packageJsonPath, rootDir))?.packages ||
|
|
277
301
|
[]
|
|
278
302
|
|
|
279
|
-
if (
|
|
303
|
+
if (packagesInManifest.length > 0) {
|
|
280
304
|
const updates = updatePackageJsonVersions(
|
|
281
305
|
packageJsonPath,
|
|
282
|
-
|
|
306
|
+
packagesInManifest,
|
|
283
307
|
versionMap
|
|
284
308
|
)
|
|
285
309
|
if (updates > 0) {
|
|
@@ -330,9 +354,11 @@ await cmd`upgrade packages by name or pattern`
|
|
|
330
354
|
const packageJsonFiles = findPackageJsonFiles(rootDir)
|
|
331
355
|
console.info(`Found ${packageJsonFiles.length} package.json files`)
|
|
332
356
|
|
|
357
|
+
const workspacePackageJsonFiles = findPackageJsonFiles(rootDir, [])
|
|
358
|
+
|
|
333
359
|
// get workspace package names to exclude from updates
|
|
334
360
|
const workspacePackageNames = new Set<string>()
|
|
335
|
-
for (const packageJsonPath of
|
|
361
|
+
for (const packageJsonPath of workspacePackageJsonFiles) {
|
|
336
362
|
if (packageJsonPath === path.join(rootDir, 'package.json')) continue
|
|
337
363
|
|
|
338
364
|
try {
|
|
@@ -350,8 +376,8 @@ await cmd`upgrade packages by name or pattern`
|
|
|
350
376
|
`Found ${workspacePackageNames.size} workspace packages to exclude from updates`
|
|
351
377
|
)
|
|
352
378
|
|
|
353
|
-
// build map of packages to update per
|
|
354
|
-
const
|
|
379
|
+
// build map of packages to update per manifest
|
|
380
|
+
const packagesByManifest = new Map<string, { dir: string; packages: string[] }>()
|
|
355
381
|
const allMatchingDeps = new Set<string>()
|
|
356
382
|
|
|
357
383
|
for (const packageJsonPath of packageJsonFiles) {
|
|
@@ -374,7 +400,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
374
400
|
if (matchingDeps.length > 0) {
|
|
375
401
|
const dir = packageJsonPath.replace('/package.json', '')
|
|
376
402
|
const name = getWorkspaceName(packageJsonPath, rootDir)
|
|
377
|
-
|
|
403
|
+
packagesByManifest.set(name, { dir, packages: matchingDeps })
|
|
378
404
|
}
|
|
379
405
|
}
|
|
380
406
|
|
|
@@ -397,7 +423,7 @@ await cmd`upgrade packages by name or pattern`
|
|
|
397
423
|
allMatchingDeps.add(pkg)
|
|
398
424
|
}
|
|
399
425
|
|
|
400
|
-
|
|
426
|
+
packagesByManifest.set('root', {
|
|
401
427
|
dir: rootDir,
|
|
402
428
|
packages: exactPatterns,
|
|
403
429
|
})
|
|
@@ -417,14 +443,14 @@ await cmd`upgrade packages by name or pattern`
|
|
|
417
443
|
console.info(
|
|
418
444
|
`Found ${allMatchingDeps.size} dependencies matching patterns: ${packagePatterns.join(', ')}`
|
|
419
445
|
)
|
|
420
|
-
console.info(`Found matches in ${
|
|
446
|
+
console.info(`Found matches in ${packagesByManifest.size} package manifest(s)`)
|
|
421
447
|
}
|
|
422
448
|
|
|
423
449
|
if (globalTag) {
|
|
424
450
|
console.info(`🏷️ Using tag '${globalTag}'`)
|
|
425
451
|
}
|
|
426
452
|
|
|
427
|
-
await updatePackages(
|
|
453
|
+
await updatePackages(packagesByManifest, rootDir, packageJsonFiles)
|
|
428
454
|
|
|
429
455
|
// sync resolved $dep: values (like ZERO_VERSION) to all env targets
|
|
430
456
|
if (
|