@wyxos/zephyr 0.2.7 → 0.2.8
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 +1 -1
- package/src/release-node.mjs +55 -59
package/package.json
CHANGED
package/src/release-node.mjs
CHANGED
|
@@ -5,24 +5,14 @@ import { readFile } from 'node:fs/promises'
|
|
|
5
5
|
import fs from 'node:fs'
|
|
6
6
|
import path from 'node:path'
|
|
7
7
|
import process from 'node:process'
|
|
8
|
-
|
|
9
|
-
const STEP_PREFIX = '→'
|
|
10
|
-
const OK_PREFIX = '✔'
|
|
11
|
-
const WARN_PREFIX = '⚠'
|
|
8
|
+
import chalk from 'chalk'
|
|
12
9
|
|
|
13
10
|
const IS_WINDOWS = process.platform === 'win32'
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function logSuccess(message) {
|
|
20
|
-
console.log(`${OK_PREFIX} ${message}`)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function logWarning(message) {
|
|
24
|
-
console.warn(`${WARN_PREFIX} ${message}`)
|
|
25
|
-
}
|
|
12
|
+
const logProcessing = (message = '') => console.log(chalk.yellow(message))
|
|
13
|
+
const logSuccess = (message = '') => console.log(chalk.green(message))
|
|
14
|
+
const logWarning = (message = '') => console.warn(chalk.yellow(message))
|
|
15
|
+
const logError = (message = '') => console.error(chalk.red(message))
|
|
26
16
|
|
|
27
17
|
function runCommand(command, args, { cwd = process.cwd(), capture = false, useShell = false } = {}) {
|
|
28
18
|
return new Promise((resolve, reject) => {
|
|
@@ -114,7 +104,7 @@ async function ensureUpToDateWithUpstream(branch, upstreamRef, rootDir = process
|
|
|
114
104
|
const remoteBranch = branchParts.join('/')
|
|
115
105
|
|
|
116
106
|
if (remoteName && remoteBranch) {
|
|
117
|
-
|
|
107
|
+
logProcessing(`Fetching latest updates from ${remoteName}/${remoteBranch}...`)
|
|
118
108
|
try {
|
|
119
109
|
await runCommand('git', ['fetch', remoteName, remoteBranch], { cwd: rootDir })
|
|
120
110
|
} catch (error) {
|
|
@@ -136,7 +126,7 @@ async function ensureUpToDateWithUpstream(branch, upstreamRef, rootDir = process
|
|
|
136
126
|
|
|
137
127
|
if (Number.isFinite(behind) && behind > 0) {
|
|
138
128
|
if (remoteName && remoteBranch) {
|
|
139
|
-
|
|
129
|
+
logProcessing(`Fast-forwarding ${branch} with ${upstreamRef}...`)
|
|
140
130
|
|
|
141
131
|
try {
|
|
142
132
|
await runCommand('git', ['pull', '--ff-only', remoteName, remoteBranch], { cwd: rootDir })
|
|
@@ -198,11 +188,11 @@ async function runLint(skipLint, pkg, rootDir = process.cwd()) {
|
|
|
198
188
|
}
|
|
199
189
|
|
|
200
190
|
if (!hasScript(pkg, 'lint')) {
|
|
201
|
-
|
|
191
|
+
logProcessing('Skipping lint (no lint script found in package.json).')
|
|
202
192
|
return
|
|
203
193
|
}
|
|
204
194
|
|
|
205
|
-
|
|
195
|
+
logProcessing('Running lint...')
|
|
206
196
|
await runCommand('npm', ['run', 'lint'], { cwd: rootDir })
|
|
207
197
|
logSuccess('Lint passed.')
|
|
208
198
|
}
|
|
@@ -215,11 +205,11 @@ async function runTests(skipTests, pkg, rootDir = process.cwd()) {
|
|
|
215
205
|
|
|
216
206
|
// Check for test:run or test script
|
|
217
207
|
if (!hasScript(pkg, 'test:run') && !hasScript(pkg, 'test')) {
|
|
218
|
-
|
|
208
|
+
logProcessing('Skipping tests (no test or test:run script found in package.json).')
|
|
219
209
|
return
|
|
220
210
|
}
|
|
221
211
|
|
|
222
|
-
|
|
212
|
+
logProcessing('Running test suite...')
|
|
223
213
|
|
|
224
214
|
let dotInterval = null
|
|
225
215
|
try {
|
|
@@ -251,10 +241,10 @@ async function runTests(skipTests, pkg, rootDir = process.cwd()) {
|
|
|
251
241
|
}
|
|
252
242
|
process.stdout.write('\n')
|
|
253
243
|
if (error.stdout) {
|
|
254
|
-
|
|
244
|
+
logError(error.stdout)
|
|
255
245
|
}
|
|
256
246
|
if (error.stderr) {
|
|
257
|
-
|
|
247
|
+
logError(error.stderr)
|
|
258
248
|
}
|
|
259
249
|
throw error
|
|
260
250
|
}
|
|
@@ -267,11 +257,11 @@ async function runBuild(skipBuild, pkg, rootDir = process.cwd()) {
|
|
|
267
257
|
}
|
|
268
258
|
|
|
269
259
|
if (!hasScript(pkg, 'build')) {
|
|
270
|
-
|
|
260
|
+
logProcessing('Skipping build (no build script found in package.json).')
|
|
271
261
|
return
|
|
272
262
|
}
|
|
273
263
|
|
|
274
|
-
|
|
264
|
+
logProcessing('Building project...')
|
|
275
265
|
await runCommand('npm', ['run', 'build'], { cwd: rootDir })
|
|
276
266
|
logSuccess('Build completed.')
|
|
277
267
|
}
|
|
@@ -283,11 +273,11 @@ async function runLibBuild(skipBuild, pkg, rootDir = process.cwd()) {
|
|
|
283
273
|
}
|
|
284
274
|
|
|
285
275
|
if (!hasScript(pkg, 'build:lib')) {
|
|
286
|
-
|
|
276
|
+
logProcessing('Skipping library build (no build:lib script found in package.json).')
|
|
287
277
|
return false
|
|
288
278
|
}
|
|
289
279
|
|
|
290
|
-
|
|
280
|
+
logProcessing('Building library...')
|
|
291
281
|
await runCommand('npm', ['run', 'build:lib'], { cwd: rootDir })
|
|
292
282
|
logSuccess('Library built.')
|
|
293
283
|
|
|
@@ -299,7 +289,7 @@ async function runLibBuild(skipBuild, pkg, rootDir = process.cwd()) {
|
|
|
299
289
|
})
|
|
300
290
|
|
|
301
291
|
if (hasLibChanges) {
|
|
302
|
-
|
|
292
|
+
logProcessing('Committing lib build artifacts...')
|
|
303
293
|
await runCommand('git', ['add', 'lib/'], { cwd: rootDir })
|
|
304
294
|
await runCommand('git', ['commit', '-m', 'chore: build lib artifacts'], { cwd: rootDir })
|
|
305
295
|
logSuccess('Lib build artifacts committed.')
|
|
@@ -309,13 +299,13 @@ async function runLibBuild(skipBuild, pkg, rootDir = process.cwd()) {
|
|
|
309
299
|
}
|
|
310
300
|
|
|
311
301
|
async function ensureNpmAuth(rootDir = process.cwd()) {
|
|
312
|
-
|
|
302
|
+
logProcessing('Confirming npm authentication...')
|
|
313
303
|
await runCommand('npm', ['whoami'], { cwd: rootDir })
|
|
314
304
|
logSuccess('npm authenticated.')
|
|
315
305
|
}
|
|
316
306
|
|
|
317
307
|
async function bumpVersion(releaseType, rootDir = process.cwd()) {
|
|
318
|
-
|
|
308
|
+
logProcessing(`Bumping package version...`)
|
|
319
309
|
|
|
320
310
|
// Lib changes should already be committed by runLibBuild, but check anyway
|
|
321
311
|
const { stdout: statusBefore } = await runCommand('git', ['status', '--porcelain'], { capture: true, cwd: rootDir })
|
|
@@ -325,7 +315,7 @@ async function bumpVersion(releaseType, rootDir = process.cwd()) {
|
|
|
325
315
|
})
|
|
326
316
|
|
|
327
317
|
if (hasLibChanges) {
|
|
328
|
-
|
|
318
|
+
logProcessing('Stashing lib build artifacts...')
|
|
329
319
|
await runCommand('git', ['stash', 'push', '-u', '-m', 'temp: lib build artifacts', 'lib/'], { cwd: rootDir })
|
|
330
320
|
}
|
|
331
321
|
|
|
@@ -335,7 +325,7 @@ async function bumpVersion(releaseType, rootDir = process.cwd()) {
|
|
|
335
325
|
} finally {
|
|
336
326
|
// Restore lib changes and ensure they're in the commit
|
|
337
327
|
if (hasLibChanges) {
|
|
338
|
-
|
|
328
|
+
logProcessing('Restoring lib build artifacts...')
|
|
339
329
|
await runCommand('git', ['stash', 'pop'], { cwd: rootDir })
|
|
340
330
|
await runCommand('git', ['add', 'lib/'], { cwd: rootDir })
|
|
341
331
|
const { stdout: statusAfter } = await runCommand('git', ['status', '--porcelain'], { capture: true, cwd: rootDir })
|
|
@@ -356,7 +346,7 @@ async function bumpVersion(releaseType, rootDir = process.cwd()) {
|
|
|
356
346
|
}
|
|
357
347
|
|
|
358
348
|
async function pushChanges(rootDir = process.cwd()) {
|
|
359
|
-
|
|
349
|
+
logProcessing('Pushing commits and tags to origin...')
|
|
360
350
|
await runCommand('git', ['push', '--follow-tags'], { cwd: rootDir })
|
|
361
351
|
logSuccess('Git push completed.')
|
|
362
352
|
}
|
|
@@ -371,7 +361,7 @@ async function publishPackage(pkg, rootDir = process.cwd()) {
|
|
|
371
361
|
publishArgs.push('--access', access)
|
|
372
362
|
}
|
|
373
363
|
|
|
374
|
-
|
|
364
|
+
logProcessing(`Publishing ${pkg.name}@${pkg.version} to npm...`)
|
|
375
365
|
await runCommand('npm', publishArgs, { cwd: rootDir })
|
|
376
366
|
logSuccess('npm publish completed.')
|
|
377
367
|
}
|
|
@@ -405,11 +395,11 @@ async function deployGHPages(skipDeploy, pkg, rootDir = process.cwd()) {
|
|
|
405
395
|
}
|
|
406
396
|
|
|
407
397
|
if (!distExists) {
|
|
408
|
-
|
|
398
|
+
logProcessing('Skipping GitHub Pages deployment (no dist directory found).')
|
|
409
399
|
return
|
|
410
400
|
}
|
|
411
401
|
|
|
412
|
-
|
|
402
|
+
logProcessing('Deploying to GitHub Pages...')
|
|
413
403
|
|
|
414
404
|
// Write CNAME file to dist if homepage is set
|
|
415
405
|
const cnamePath = path.join(distPath, 'CNAME')
|
|
@@ -459,35 +449,41 @@ async function deployGHPages(skipDeploy, pkg, rootDir = process.cwd()) {
|
|
|
459
449
|
}
|
|
460
450
|
|
|
461
451
|
export async function releaseNode() {
|
|
462
|
-
|
|
463
|
-
|
|
452
|
+
try {
|
|
453
|
+
const { releaseType, skipTests, skipLint, skipBuild, skipDeploy } = parseArgs()
|
|
454
|
+
const rootDir = process.cwd()
|
|
464
455
|
|
|
465
|
-
|
|
466
|
-
|
|
456
|
+
logProcessing('Reading package metadata...')
|
|
457
|
+
const pkg = await readPackage(rootDir)
|
|
467
458
|
|
|
468
|
-
|
|
469
|
-
|
|
459
|
+
logProcessing('Checking working tree status...')
|
|
460
|
+
await ensureCleanWorkingTree(rootDir)
|
|
470
461
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
462
|
+
const branch = await getCurrentBranch(rootDir)
|
|
463
|
+
if (!branch) {
|
|
464
|
+
throw new Error('Unable to determine current branch.')
|
|
465
|
+
}
|
|
475
466
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
467
|
+
logProcessing(`Current branch: ${branch}`)
|
|
468
|
+
const upstreamRef = await getUpstreamRef(rootDir)
|
|
469
|
+
await ensureUpToDateWithUpstream(branch, upstreamRef, rootDir)
|
|
479
470
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
471
|
+
await runLint(skipLint, pkg, rootDir)
|
|
472
|
+
await runTests(skipTests, pkg, rootDir)
|
|
473
|
+
await runBuild(skipBuild, pkg, rootDir)
|
|
474
|
+
await runLibBuild(skipBuild, pkg, rootDir)
|
|
475
|
+
await ensureNpmAuth(rootDir)
|
|
485
476
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
477
|
+
const updatedPkg = await bumpVersion(releaseType, rootDir)
|
|
478
|
+
await pushChanges(rootDir)
|
|
479
|
+
await publishPackage(updatedPkg, rootDir)
|
|
480
|
+
await deployGHPages(skipDeploy, updatedPkg, rootDir)
|
|
490
481
|
|
|
491
|
-
|
|
482
|
+
logSuccess(`Release workflow completed for ${updatedPkg.name}@${updatedPkg.version}.`)
|
|
483
|
+
} catch (error) {
|
|
484
|
+
logError('\nRelease failed:')
|
|
485
|
+
logError(error.message)
|
|
486
|
+
throw error
|
|
487
|
+
}
|
|
492
488
|
}
|
|
493
489
|
|