@layr-labs/ecloud-cli 0.2.0-dev.1 → 0.2.0-dev.2

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 (58) hide show
  1. package/VERSION +2 -2
  2. package/dist/commands/auth/generate.js +2 -2
  3. package/dist/commands/auth/generate.js.map +1 -1
  4. package/dist/commands/auth/login.js.map +1 -1
  5. package/dist/commands/auth/logout.js.map +1 -1
  6. package/dist/commands/auth/migrate.js.map +1 -1
  7. package/dist/commands/auth/whoami.js +3 -5
  8. package/dist/commands/auth/whoami.js.map +1 -1
  9. package/dist/commands/billing/cancel.js +3 -6
  10. package/dist/commands/billing/cancel.js.map +1 -1
  11. package/dist/commands/billing/status.js +3 -6
  12. package/dist/commands/billing/status.js.map +1 -1
  13. package/dist/commands/billing/subscribe.js +7 -12
  14. package/dist/commands/billing/subscribe.js.map +1 -1
  15. package/dist/commands/compute/app/create.js.map +1 -1
  16. package/dist/commands/compute/app/deploy.js +86 -614
  17. package/dist/commands/compute/app/deploy.js.map +1 -1
  18. package/dist/commands/compute/app/info.js +10 -59
  19. package/dist/commands/compute/app/info.js.map +1 -1
  20. package/dist/commands/compute/app/list.js +9 -10
  21. package/dist/commands/compute/app/list.js.map +1 -1
  22. package/dist/commands/compute/app/logs.js +11 -61
  23. package/dist/commands/compute/app/logs.js.map +1 -1
  24. package/dist/commands/compute/app/profile/set.js +20 -145
  25. package/dist/commands/compute/app/profile/set.js.map +1 -1
  26. package/dist/commands/compute/app/start.js +11 -61
  27. package/dist/commands/compute/app/start.js.map +1 -1
  28. package/dist/commands/compute/app/stop.js +11 -61
  29. package/dist/commands/compute/app/stop.js.map +1 -1
  30. package/dist/commands/compute/app/terminate.js +11 -61
  31. package/dist/commands/compute/app/terminate.js.map +1 -1
  32. package/dist/commands/compute/app/upgrade.js +52 -615
  33. package/dist/commands/compute/app/upgrade.js.map +1 -1
  34. package/dist/commands/compute/environment/list.js.map +1 -1
  35. package/dist/commands/compute/environment/set.js.map +1 -1
  36. package/dist/commands/compute/environment/show.js.map +1 -1
  37. package/dist/commands/compute/undelegate.js +9 -11
  38. package/dist/commands/compute/undelegate.js.map +1 -1
  39. package/dist/commands/telemetry/disable.js.map +1 -1
  40. package/dist/commands/telemetry/enable.js.map +1 -1
  41. package/dist/commands/telemetry/status.js.map +1 -1
  42. package/dist/commands/upgrade.js.map +1 -1
  43. package/dist/commands/version.js.map +1 -1
  44. package/package.json +2 -7
  45. package/dist/commands/compute/app/releases.js +0 -1111
  46. package/dist/commands/compute/app/releases.js.map +0 -1
  47. package/dist/commands/compute/build/info.js +0 -500
  48. package/dist/commands/compute/build/info.js.map +0 -1
  49. package/dist/commands/compute/build/list.js +0 -494
  50. package/dist/commands/compute/build/list.js.map +0 -1
  51. package/dist/commands/compute/build/logs.js +0 -459
  52. package/dist/commands/compute/build/logs.js.map +0 -1
  53. package/dist/commands/compute/build/status.js +0 -481
  54. package/dist/commands/compute/build/status.js.map +0 -1
  55. package/dist/commands/compute/build/submit.js +0 -618
  56. package/dist/commands/compute/build/submit.js.map +0 -1
  57. package/dist/commands/compute/build/verify.js +0 -439
  58. package/dist/commands/compute/build/verify.js.map +0 -1
@@ -1,618 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/commands/compute/build/submit.ts
4
- import { Command, Flags as Flags2 } from "@oclif/core";
5
- import chalk from "chalk";
6
-
7
- // src/flags.ts
8
- import { Flags } from "@oclif/core";
9
- import { getBuildType as getBuildType2 } from "@layr-labs/ecloud-sdk";
10
-
11
- // src/utils/prompts.ts
12
- import { input, select, password, confirm as inquirerConfirm } from "@inquirer/prompts";
13
- import fs3 from "fs";
14
- import path3 from "path";
15
- import os3 from "os";
16
- import { isAddress as isAddress2 } from "viem";
17
- import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
18
- import {
19
- getEnvironmentConfig,
20
- getAvailableEnvironments,
21
- isEnvironmentAvailable,
22
- getAllAppsByDeveloper as getAllAppsByDeveloper2,
23
- getCategoryDescriptions,
24
- fetchTemplateCatalog,
25
- PRIMARY_LANGUAGES,
26
- validateAppName,
27
- validateImageReference,
28
- validateFilePath,
29
- validatePrivateKeyFormat,
30
- extractAppNameFromImage,
31
- UserApiClient as UserApiClient2
32
- } from "@layr-labs/ecloud-sdk";
33
-
34
- // src/utils/appResolver.ts
35
- import { isAddress } from "viem";
36
- import { privateKeyToAccount } from "viem/accounts";
37
- import {
38
- UserApiClient,
39
- getAllAppsByDeveloper
40
- } from "@layr-labs/ecloud-sdk";
41
-
42
- // src/utils/globalConfig.ts
43
- import * as fs from "fs";
44
- import * as path from "path";
45
- import * as os from "os";
46
- import { load as loadYaml, dump as dumpYaml } from "js-yaml";
47
- import { getBuildType } from "@layr-labs/ecloud-sdk";
48
- import * as crypto from "crypto";
49
- var GLOBAL_CONFIG_FILE = "config.yaml";
50
- var PROFILE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
51
- function getGlobalConfigDir() {
52
- const configHome = process.env.XDG_CONFIG_HOME;
53
- let baseDir;
54
- if (configHome && path.isAbsolute(configHome)) {
55
- baseDir = configHome;
56
- } else {
57
- baseDir = path.join(os.homedir(), ".config");
58
- }
59
- const buildType = getBuildType();
60
- const buildSuffix = buildType === "dev" ? "-dev" : "";
61
- const configDirName = `ecloud${buildSuffix}`;
62
- return path.join(baseDir, configDirName);
63
- }
64
- function getGlobalConfigPath() {
65
- return path.join(getGlobalConfigDir(), GLOBAL_CONFIG_FILE);
66
- }
67
- function loadGlobalConfig() {
68
- const configPath = getGlobalConfigPath();
69
- if (!fs.existsSync(configPath)) {
70
- return {
71
- first_run: true
72
- };
73
- }
74
- try {
75
- const content = fs.readFileSync(configPath, "utf-8");
76
- const config = loadYaml(content);
77
- return config || { first_run: true };
78
- } catch {
79
- return {
80
- first_run: true
81
- };
82
- }
83
- }
84
- function saveGlobalConfig(config) {
85
- const configPath = getGlobalConfigPath();
86
- const configDir = path.dirname(configPath);
87
- fs.mkdirSync(configDir, { recursive: true, mode: 493 });
88
- const content = dumpYaml(config, { lineWidth: -1 });
89
- fs.writeFileSync(configPath, content, { mode: 420 });
90
- }
91
- function getDefaultEnvironment() {
92
- const config = loadGlobalConfig();
93
- return config.default_environment;
94
- }
95
- function getGlobalTelemetryPreference() {
96
- const config = loadGlobalConfig();
97
- return config.telemetry_enabled;
98
- }
99
- function getOrCreateUserUUID() {
100
- const config = loadGlobalConfig();
101
- if (config.user_uuid) {
102
- return config.user_uuid;
103
- }
104
- const uuid = generateUUID();
105
- config.user_uuid = uuid;
106
- config.first_run = false;
107
- saveGlobalConfig(config);
108
- return uuid;
109
- }
110
- function generateUUID() {
111
- const bytes = crypto.randomBytes(16);
112
- bytes[6] = bytes[6] & 15 | 64;
113
- bytes[8] = bytes[8] & 63 | 128;
114
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0"));
115
- return hex.slice(0, 4).join("") + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 12).join("") + "-" + hex.slice(12, 16).join("");
116
- }
117
-
118
- // src/utils/appNames.ts
119
- import * as fs2 from "fs";
120
- import * as path2 from "path";
121
- import * as os2 from "os";
122
- import { load as loadYaml2, dump as dumpYaml2 } from "js-yaml";
123
- var CONFIG_DIR = path2.join(os2.homedir(), ".eigenx");
124
- var APPS_DIR = path2.join(CONFIG_DIR, "apps");
125
-
126
- // src/utils/version.ts
127
- function getCliVersion() {
128
- return true ? "0.2.0-dev.1" : "0.0.0";
129
- }
130
- function getClientId() {
131
- return `ecloud-cli/v${getCliVersion()}`;
132
- }
133
-
134
- // src/utils/prompts.ts
135
- async function promptVerifiableGitSourceInputs() {
136
- const repoUrl = (await input({
137
- message: "Enter public git repository URL:",
138
- default: "",
139
- validate: (value) => {
140
- if (!value.trim()) return "Repository URL is required";
141
- try {
142
- const url = new URL(value.trim());
143
- if (url.protocol !== "https:") return "Repository URL must start with https://";
144
- if (url.hostname.toLowerCase() !== "github.com")
145
- return "Repository URL must be a public GitHub HTTPS URL (github.com)";
146
- const parts = url.pathname.replace(/\/+$/, "").split("/").filter(Boolean);
147
- if (parts.length < 2) return "Repository URL must be https://github.com/<owner>/<repo>";
148
- const [owner, repo] = parts;
149
- if (!owner || !repo) return "Repository URL must be https://github.com/<owner>/<repo>";
150
- if (repo.toLowerCase() === "settings") return "Repository URL looks invalid";
151
- if (url.search || url.hash)
152
- return "Repository URL must not include query params or fragments";
153
- } catch {
154
- return "Invalid URL format";
155
- }
156
- return true;
157
- }
158
- })).trim();
159
- const gitRef = (await input({
160
- message: "Enter git commit SHA (40 hex chars):",
161
- default: "",
162
- validate: (value) => {
163
- const trimmed = value.trim();
164
- if (!trimmed) return "Commit SHA is required";
165
- if (!/^[0-9a-f]{40}$/i.test(trimmed))
166
- return "Commit must be a 40-character hexadecimal SHA";
167
- return true;
168
- }
169
- })).trim();
170
- const buildContextPath = (await input({
171
- message: "Enter build context path (relative to repo):",
172
- default: ".",
173
- validate: (value) => value.trim() ? true : "Build context path cannot be empty"
174
- })).trim();
175
- const dockerfilePath = (await input({
176
- message: "Enter Dockerfile path (relative to build context):",
177
- default: "Dockerfile",
178
- validate: (value) => value.trim() ? true : "Dockerfile path cannot be empty"
179
- })).trim();
180
- const caddyfileRaw = (await input({
181
- message: "Enter Caddyfile path (relative to build context, optional):",
182
- default: "",
183
- validate: (value) => {
184
- const trimmed = value.trim();
185
- if (!trimmed) return true;
186
- if (trimmed.includes("..")) return "Caddyfile path must not contain '..'";
187
- return true;
188
- }
189
- })).trim();
190
- const depsRaw = (await input({
191
- message: "Enter dependency digests (comma-separated sha256:..., optional):",
192
- default: "",
193
- validate: (value) => {
194
- const trimmed = value.trim();
195
- if (!trimmed) return true;
196
- const parts = trimmed.split(",").map((p) => p.trim()).filter(Boolean);
197
- for (const p of parts) {
198
- if (!/^sha256:[0-9a-f]{64}$/i.test(p)) {
199
- return `Invalid dependency digest: ${p} (expected sha256:<64 hex>)`;
200
- }
201
- }
202
- return true;
203
- }
204
- })).trim();
205
- const dependencies = depsRaw === "" ? [] : depsRaw.split(",").map((p) => p.trim()).filter(Boolean);
206
- return {
207
- repoUrl,
208
- gitRef,
209
- dockerfilePath,
210
- caddyfilePath: caddyfileRaw === "" ? void 0 : caddyfileRaw,
211
- buildContextPath,
212
- dependencies
213
- };
214
- }
215
- async function getPrivateKeyInteractive(privateKey) {
216
- if (privateKey) {
217
- if (!validatePrivateKeyFormat(privateKey)) {
218
- throw new Error("Invalid private key format");
219
- }
220
- return privateKey;
221
- }
222
- const { getPrivateKeyWithSource: getPrivateKeyWithSource2 } = await import("@layr-labs/ecloud-sdk");
223
- const result = await getPrivateKeyWithSource2({ privateKey: void 0 });
224
- if (result) {
225
- return result.key;
226
- }
227
- const key = await password({
228
- message: "Enter private key:",
229
- mask: true,
230
- validate: (value) => {
231
- if (!value.trim()) {
232
- return "Private key is required";
233
- }
234
- if (!validatePrivateKeyFormat(value)) {
235
- return "Invalid private key format (must be 64 hex characters, optionally prefixed with 0x)";
236
- }
237
- return true;
238
- }
239
- });
240
- return key.trim();
241
- }
242
- async function getEnvironmentInteractive(environment) {
243
- if (environment) {
244
- try {
245
- getEnvironmentConfig(environment);
246
- if (!isEnvironmentAvailable(environment)) {
247
- throw new Error(`Environment ${environment} is not available in this build`);
248
- }
249
- return environment;
250
- } catch {
251
- }
252
- }
253
- const availableEnvs = getAvailableEnvironments();
254
- let defaultEnv;
255
- const configDefaultEnv = getDefaultEnvironment();
256
- if (configDefaultEnv && availableEnvs.includes(configDefaultEnv)) {
257
- try {
258
- getEnvironmentConfig(configDefaultEnv);
259
- defaultEnv = configDefaultEnv;
260
- } catch {
261
- }
262
- }
263
- const choices = [];
264
- if (availableEnvs.includes("sepolia")) {
265
- choices.push({ name: "sepolia - Ethereum Sepolia testnet", value: "sepolia" });
266
- }
267
- if (availableEnvs.includes("sepolia-dev")) {
268
- choices.push({ name: "sepolia-dev - Ethereum Sepolia testnet (dev)", value: "sepolia-dev" });
269
- }
270
- if (availableEnvs.includes("mainnet-alpha")) {
271
- choices.push({
272
- name: "mainnet-alpha - Ethereum mainnet (\u26A0\uFE0F uses real funds)",
273
- value: "mainnet-alpha"
274
- });
275
- }
276
- if (choices.length === 0) {
277
- throw new Error("No environments available in this build");
278
- }
279
- const env = await select({
280
- message: "Select environment:",
281
- choices,
282
- default: defaultEnv
283
- });
284
- return env;
285
- }
286
- var MAX_IMAGE_SIZE = 4 * 1024 * 1024;
287
-
288
- // src/flags.ts
289
- var commonFlags = {
290
- environment: Flags.string({
291
- required: false,
292
- description: "Deployment environment to use",
293
- env: "ECLOUD_ENV",
294
- default: async () => getDefaultEnvironment() || (getBuildType2() === "dev" ? "sepolia-dev" : "sepolia")
295
- }),
296
- "private-key": Flags.string({
297
- required: false,
298
- description: "Private key for signing transactions",
299
- env: "ECLOUD_PRIVATE_KEY"
300
- }),
301
- "rpc-url": Flags.string({
302
- required: false,
303
- description: "RPC URL to connect to blockchain",
304
- env: "ECLOUD_RPC_URL"
305
- }),
306
- verbose: Flags.boolean({
307
- required: false,
308
- description: "Enable verbose logging (default: false)",
309
- default: false
310
- })
311
- };
312
- async function validateCommonFlags(flags, options) {
313
- flags["environment"] = await getEnvironmentInteractive(flags["environment"]);
314
- if (options?.requirePrivateKey !== false) {
315
- flags["private-key"] = await getPrivateKeyInteractive(flags["private-key"]);
316
- }
317
- return flags;
318
- }
319
-
320
- // src/client.ts
321
- import {
322
- createComputeModule,
323
- createBillingModule,
324
- createBuildModule,
325
- getEnvironmentConfig as getEnvironmentConfig2,
326
- requirePrivateKey,
327
- getPrivateKeyWithSource
328
- } from "@layr-labs/ecloud-sdk";
329
- async function createBuildClient(flags) {
330
- flags = await validateCommonFlags(flags, { requirePrivateKey: false });
331
- return createBuildModule({
332
- verbose: flags.verbose,
333
- privateKey: flags["private-key"],
334
- environment: flags.environment,
335
- clientId: getClientId(),
336
- skipTelemetry: true
337
- // CLI already has telemetry, skip SDK telemetry
338
- });
339
- }
340
-
341
- // src/telemetry.ts
342
- import {
343
- createTelemetryClient,
344
- createAppEnvironment,
345
- createMetricsContext,
346
- addMetric,
347
- addMetricWithDimensions,
348
- emitMetrics,
349
- getBuildType as getBuildType3
350
- } from "@layr-labs/ecloud-sdk";
351
- function createCLITelemetryClient() {
352
- const userUUID = getOrCreateUserUUID();
353
- const environment = createAppEnvironment(userUUID);
354
- const telemetryEnabled = getGlobalTelemetryPreference();
355
- return createTelemetryClient(environment, "ecloud-cli", {
356
- telemetryEnabled: telemetryEnabled !== false
357
- // Enabled by default, disabled only if explicitly set to false
358
- });
359
- }
360
- async function withTelemetry(command, action) {
361
- const client = createCLITelemetryClient();
362
- const metrics = createMetricsContext();
363
- metrics.properties["source"] = "ecloud-cli";
364
- metrics.properties["command"] = command.id || command.constructor.name;
365
- const environment = getDefaultEnvironment() || "sepolia";
366
- metrics.properties["environment"] = environment;
367
- const buildType = getBuildType3() || "prod";
368
- metrics.properties["build_type"] = buildType;
369
- const cliVersion = command.config.version;
370
- if (cliVersion) {
371
- metrics.properties["cli_version"] = cliVersion;
372
- }
373
- addMetric(metrics, "Count", 1);
374
- let actionError;
375
- let result;
376
- try {
377
- result = await action();
378
- return result;
379
- } catch (err) {
380
- actionError = err instanceof Error ? err : new Error(String(err));
381
- throw err;
382
- } finally {
383
- const resultValue = actionError ? "Failure" : "Success";
384
- const dimensions = {};
385
- if (actionError) {
386
- dimensions["error"] = actionError.message;
387
- }
388
- addMetricWithDimensions(metrics, resultValue, 1, dimensions);
389
- const duration = Date.now() - metrics.startTime.getTime();
390
- addMetric(metrics, "DurationMilliseconds", duration);
391
- try {
392
- await emitMetrics(client, metrics);
393
- await client.close();
394
- } catch {
395
- }
396
- }
397
- }
398
-
399
- // src/commands/compute/build/submit.ts
400
- import { BUILD_STATUS as BUILD_STATUS2 } from "@layr-labs/ecloud-sdk";
401
-
402
- // src/utils/build.ts
403
- function formatSourceLink(repoUrl, gitRef) {
404
- const normalizedRepo = repoUrl.replace(/\.git$/, "");
405
- try {
406
- const url = new URL(normalizedRepo);
407
- const host = url.host.toLowerCase();
408
- if (host === "github.com") {
409
- const path4 = url.pathname.replace(/\/+$/, "");
410
- if (path4.split("/").filter(Boolean).length >= 2) {
411
- return `https://github.com${path4}/tree/${gitRef}`;
412
- }
413
- }
414
- } catch {
415
- }
416
- return `${repoUrl}@${gitRef}`;
417
- }
418
- function extractRepoName(repoUrl) {
419
- const normalized = repoUrl.replace(/\.git$/, "");
420
- const match = normalized.match(/\/([^/]+?)$/);
421
- return match?.[1];
422
- }
423
- function formatDependencyLines(dependencies) {
424
- if (!dependencies || Object.keys(dependencies).length === 0) return [];
425
- const lines = [];
426
- lines.push("Dependencies (resolved builds):");
427
- for (const [digest, dep] of Object.entries(dependencies)) {
428
- const name = extractRepoName(dep.repoUrl);
429
- const depSource = formatSourceLink(dep.repoUrl, dep.gitRef);
430
- lines.push(` - ${digest} \u2713${name ? ` ${name}` : ""}`);
431
- lines.push(` ${depSource}`);
432
- }
433
- return lines;
434
- }
435
- function formatVerifiableBuildSummary(options) {
436
- const lines = [];
437
- lines.push("Build completed successfully \u2713");
438
- lines.push("");
439
- lines.push(`Image: ${options.imageUrl}`);
440
- lines.push(`Digest: ${options.imageDigest}`);
441
- lines.push(`Source: ${formatSourceLink(options.repoUrl, options.gitRef)}`);
442
- const depLines = formatDependencyLines(options.dependencies);
443
- if (depLines.length) {
444
- lines.push("");
445
- lines.push(...depLines);
446
- }
447
- lines.push("");
448
- lines.push("Provenance signature verified \u2713");
449
- lines.push(`provenance_signature: ${options.provenanceSignature}`);
450
- if (options.buildId) {
451
- lines.push("");
452
- lines.push(`Build ID: ${options.buildId}`);
453
- }
454
- return lines;
455
- }
456
-
457
- // src/utils/verifiableBuild.ts
458
- import { BUILD_STATUS } from "@layr-labs/ecloud-sdk";
459
- function assertCommitSha40(commit) {
460
- if (!/^[0-9a-f]{40}$/i.test(commit)) {
461
- throw new Error("Commit must be a 40-character hexadecimal SHA");
462
- }
463
- }
464
- async function runVerifiableBuildAndVerify(client, request, options = {}) {
465
- const { buildId } = await client.submit(request);
466
- const completed = await client.waitForBuild(buildId, { onLog: options.onLog });
467
- if (completed.status !== BUILD_STATUS.SUCCESS) {
468
- throw new Error(`Build did not complete successfully (status: ${completed.status})`);
469
- }
470
- const [build, verify] = await Promise.all([client.get(buildId), client.verify(buildId)]);
471
- if (verify.status !== "verified") {
472
- throw new Error(`Provenance verification failed: ${verify.error}`);
473
- }
474
- return { build, verified: verify };
475
- }
476
-
477
- // src/commands/compute/build/submit.ts
478
- var BuildSubmit = class _BuildSubmit extends Command {
479
- static description = "Submit a new verifiable build";
480
- static examples = [
481
- `$ ecloud compute build submit --repo https://github.com/myorg/myapp --commit abc123...`,
482
- `$ ecloud compute build submit --repo https://github.com/myorg/myapp --commit abc123... --dependencies sha256:def456...`,
483
- `$ ecloud compute build submit --repo https://github.com/myorg/myapp --commit abc123... --build-caddyfile Caddyfile`,
484
- `$ ecloud compute build submit --repo https://github.com/myorg/myapp --commit abc123... --no-follow`
485
- ];
486
- static flags = {
487
- ...commonFlags,
488
- repo: Flags2.string({
489
- description: "Git repository URL",
490
- required: false,
491
- env: "ECLOUD_BUILD_REPO"
492
- }),
493
- commit: Flags2.string({
494
- description: "Git commit SHA (40 hex characters)",
495
- required: false,
496
- env: "ECLOUD_BUILD_COMMIT"
497
- }),
498
- dockerfile: Flags2.string({
499
- description: "Path to Dockerfile",
500
- default: "Dockerfile",
501
- env: "ECLOUD_BUILD_DOCKERFILE"
502
- }),
503
- "build-caddyfile": Flags2.string({
504
- description: "Optional path to Caddyfile inside the repo (relative to build context). If omitted, no Caddyfile is copied into the image",
505
- required: false,
506
- env: "ECLOUD_BUILD_CADDYFILE"
507
- }),
508
- context: Flags2.string({
509
- description: "Build context path",
510
- default: ".",
511
- env: "ECLOUD_BUILD_CONTEXT"
512
- }),
513
- dependencies: Flags2.string({
514
- description: "Dependency image digests (sha256:...)",
515
- multiple: true
516
- }),
517
- "no-follow": Flags2.boolean({
518
- description: "Don't follow logs, exit after submission",
519
- default: false
520
- }),
521
- json: Flags2.boolean({
522
- description: "Output JSON instead of formatted text",
523
- default: false
524
- })
525
- };
526
- async run() {
527
- return withTelemetry(this, async () => {
528
- const { flags } = await this.parse(_BuildSubmit);
529
- const validatedFlags = await validateCommonFlags(flags);
530
- const interactiveInputs = flags.repo && flags.commit ? void 0 : await promptVerifiableGitSourceInputs();
531
- const repoUrl = flags.repo ?? interactiveInputs.repoUrl;
532
- const gitRef = flags.commit ?? interactiveInputs.gitRef;
533
- const dockerfilePath = flags.dockerfile ?? interactiveInputs.dockerfilePath;
534
- const buildContextPath = flags.context ?? interactiveInputs.buildContextPath;
535
- const dependencies = flags.dependencies && flags.dependencies.length > 0 ? flags.dependencies : interactiveInputs?.dependencies;
536
- const caddyfilePath = flags["build-caddyfile"] ?? interactiveInputs?.caddyfilePath;
537
- try {
538
- assertCommitSha40(gitRef);
539
- } catch (e) {
540
- this.error(e?.message || String(e));
541
- }
542
- const client = await createBuildClient(validatedFlags);
543
- this.log(chalk.gray("Submitting build..."));
544
- try {
545
- if (flags["no-follow"]) {
546
- const { buildId } = await client.submit({
547
- repoUrl,
548
- gitRef,
549
- dockerfilePath,
550
- caddyfilePath,
551
- buildContextPath,
552
- dependencies
553
- });
554
- this.log(chalk.green(`Build submitted: ${buildId}`));
555
- if (flags.json) {
556
- this.log(JSON.stringify({ buildId }, null, 2));
557
- } else {
558
- this.log(`
559
- Build ID: ${chalk.cyan(buildId)}`);
560
- this.log(
561
- `
562
- Use ${chalk.yellow(`ecloud compute build logs ${buildId} --follow`)} to watch progress`
563
- );
564
- }
565
- return;
566
- }
567
- this.log("");
568
- const { build, verified } = await runVerifiableBuildAndVerify(
569
- client,
570
- {
571
- repoUrl,
572
- gitRef,
573
- dockerfilePath,
574
- caddyfilePath,
575
- buildContextPath,
576
- dependencies
577
- },
578
- {
579
- onLog: (chunk) => process.stdout.write(chunk)
580
- }
581
- );
582
- this.log("");
583
- await this.printBuildResult(build, flags.json, verified);
584
- } catch (error) {
585
- this.log(chalk.red("Build submission failed"));
586
- if (error?.name === "BuildFailedError") {
587
- this.error(`Build failed: ${error.message}`);
588
- }
589
- throw error;
590
- }
591
- });
592
- }
593
- async printBuildResult(build, json, verify) {
594
- if (json) {
595
- this.log(JSON.stringify(build, null, 2));
596
- return;
597
- }
598
- if (build.status === BUILD_STATUS2.SUCCESS && verify?.status === "verified") {
599
- for (const line of formatVerifiableBuildSummary({
600
- buildId: build.buildId,
601
- imageUrl: build.imageUrl || "",
602
- imageDigest: build.imageDigest || "",
603
- repoUrl: build.repoUrl,
604
- gitRef: build.gitRef,
605
- dependencies: build.dependencies,
606
- provenanceSignature: verify.provenanceSignature
607
- })) {
608
- this.log(line);
609
- }
610
- } else {
611
- this.log(chalk.red(`Build failed: ${build.errorMessage ?? "Unknown error"}`));
612
- }
613
- }
614
- };
615
- export {
616
- BuildSubmit as default
617
- };
618
- //# sourceMappingURL=submit.js.map