@zerct/zerct 0.1.10 → 0.1.11
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/bin/zerct.js +58 -3
- package/package.json +1 -1
package/bin/zerct.js
CHANGED
|
@@ -4,9 +4,10 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSy
|
|
|
4
4
|
import { homedir } from 'node:os'
|
|
5
5
|
import path from 'node:path'
|
|
6
6
|
|
|
7
|
-
const VERSION = '0.1.
|
|
7
|
+
const VERSION = '0.1.11'
|
|
8
8
|
const DEFAULT_API_URL = 'https://api.zerct.com'
|
|
9
9
|
const ARCHIVE_LIMIT_BYTES = 48 * 1024 * 1024
|
|
10
|
+
const DEFAULT_DEPLOY_WAIT_TIMEOUT_SECONDS = 900
|
|
10
11
|
const SESSION_DIR = '.zerct'
|
|
11
12
|
const SESSION_FILE = 'session-token'
|
|
12
13
|
const SESSION_SERVICE = 'com.zerct.cli'
|
|
@@ -64,7 +65,7 @@ Usage:
|
|
|
64
65
|
zerct install [path]
|
|
65
66
|
zerct doctor [path] [--json]
|
|
66
67
|
zerct login [--token <token>] [--api <url>]
|
|
67
|
-
zerct deploy [path] [--database] [--api <url>] [--json]
|
|
68
|
+
zerct deploy [path] [--database] [--wait] [--wait-timeout <seconds>] [--api <url>] [--json]
|
|
68
69
|
zerct capabilities [--api <url>] [--json]
|
|
69
70
|
zerct me [--api <url>] [--json]
|
|
70
71
|
zerct usage [--api <url>] [--json]
|
|
@@ -184,8 +185,10 @@ function parseArgs(argv) {
|
|
|
184
185
|
limit: '',
|
|
185
186
|
cursor: '',
|
|
186
187
|
token: '',
|
|
188
|
+
waitTimeoutSeconds: DEFAULT_DEPLOY_WAIT_TIMEOUT_SECONDS,
|
|
187
189
|
json: false,
|
|
188
190
|
database: false,
|
|
191
|
+
wait: false,
|
|
189
192
|
help: false,
|
|
190
193
|
version: false
|
|
191
194
|
}
|
|
@@ -203,6 +206,11 @@ function parseArgs(argv) {
|
|
|
203
206
|
cli.database = true
|
|
204
207
|
} else if (arg === '--no-database') {
|
|
205
208
|
cli.database = false
|
|
209
|
+
} else if (arg === '--wait') {
|
|
210
|
+
cli.wait = true
|
|
211
|
+
} else if (arg === '--wait-timeout') {
|
|
212
|
+
cli.waitTimeoutSeconds = parsePositiveInteger(requireValue(argv, index, '--wait-timeout'), '--wait-timeout')
|
|
213
|
+
index += 1
|
|
206
214
|
} else if (arg === '--api') {
|
|
207
215
|
cli.apiUrl = requireValue(argv, index, '--api')
|
|
208
216
|
index += 1
|
|
@@ -238,6 +246,14 @@ function parseArgs(argv) {
|
|
|
238
246
|
return cli
|
|
239
247
|
}
|
|
240
248
|
|
|
249
|
+
function parsePositiveInteger(value, name) {
|
|
250
|
+
const parsed = Number.parseInt(value, 10)
|
|
251
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
252
|
+
throw agentError('invalid_argument', `${name} must be a positive integer.`, `Pass ${name} as seconds, for example ${name} 900.`, false)
|
|
253
|
+
}
|
|
254
|
+
return parsed
|
|
255
|
+
}
|
|
256
|
+
|
|
241
257
|
function requireValue(argv, index, name) {
|
|
242
258
|
const value = argv[index + 1]
|
|
243
259
|
if (!value || value.startsWith('--')) {
|
|
@@ -450,6 +466,9 @@ async function deploy(projectDir, cli) {
|
|
|
450
466
|
const token = await readOrLoginToken(project.dir, cli)
|
|
451
467
|
await preflightDeployLimits([project], cli, token, cli.database)
|
|
452
468
|
const result = await deployProject(project.dir, cli, token, cli.database)
|
|
469
|
+
if (cli.wait) {
|
|
470
|
+
result.final_build = await waitForBuild(cli, token, result.build_job.id)
|
|
471
|
+
}
|
|
453
472
|
printDeployResult(result, cli)
|
|
454
473
|
return
|
|
455
474
|
}
|
|
@@ -474,6 +493,12 @@ async function deploy(projectDir, cli) {
|
|
|
474
493
|
}
|
|
475
494
|
}
|
|
476
495
|
|
|
496
|
+
if (cli.wait) {
|
|
497
|
+
for (const result of results) {
|
|
498
|
+
result.finalBuild = await waitForBuild(cli, token, result.response.build_job.id)
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
477
502
|
printWorkspaceDeployResults(projectDir, results, cli)
|
|
478
503
|
}
|
|
479
504
|
|
|
@@ -561,7 +586,8 @@ function printWorkspaceDeployResults(projectDir, results, cli) {
|
|
|
561
586
|
kind: result.project.kind,
|
|
562
587
|
wants_database: result.wantsDatabase,
|
|
563
588
|
app: result.response.app,
|
|
564
|
-
build_job: result.response.build_job
|
|
589
|
+
build_job: result.response.build_job,
|
|
590
|
+
final_build: result.finalBuild || null
|
|
565
591
|
}))
|
|
566
592
|
}, null, 2))
|
|
567
593
|
return
|
|
@@ -573,6 +599,35 @@ function printWorkspaceDeployResults(projectDir, results, cli) {
|
|
|
573
599
|
}
|
|
574
600
|
}
|
|
575
601
|
|
|
602
|
+
async function waitForBuild(cli, token, buildId) {
|
|
603
|
+
const deadline = Date.now() + cli.waitTimeoutSeconds * 1000
|
|
604
|
+
let lastStatus = ''
|
|
605
|
+
|
|
606
|
+
while (Date.now() <= deadline) {
|
|
607
|
+
const response = await apiRequest(cli, 'GET', `/v1/builds/${encodeURIComponent(buildId)}`, token, null)
|
|
608
|
+
const build = response.build
|
|
609
|
+
if (!build?.status) {
|
|
610
|
+
throw agentError('build_status_unavailable', 'Build status is unavailable.', `Retry with \`npx @zerct/zerct logs --build ${buildId}\`.`, cli.json)
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (build.status !== lastStatus) {
|
|
614
|
+
progress(cli, `build ${build.id} ${build.status}`)
|
|
615
|
+
lastStatus = build.status
|
|
616
|
+
}
|
|
617
|
+
if (['succeeded', 'failed', 'canceled'].includes(build.status)) {
|
|
618
|
+
return build
|
|
619
|
+
}
|
|
620
|
+
await sleep(3000)
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
throw agentError(
|
|
624
|
+
'build_wait_timeout',
|
|
625
|
+
`Timed out waiting for build ${buildId}.`,
|
|
626
|
+
`Run \`npx @zerct/zerct logs --build ${buildId}\` to continue watching.`,
|
|
627
|
+
cli.json
|
|
628
|
+
)
|
|
629
|
+
}
|
|
630
|
+
|
|
576
631
|
async function logs(cli) {
|
|
577
632
|
const token = await readOrLoginToken(process.cwd(), cli)
|
|
578
633
|
const page = pageQuery(cli)
|