eas-cli 16.25.1 → 16.27.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.
@@ -21,7 +21,7 @@ This project is configured to use [EAS Workflows](https://docs.expo.dev/eas/work
21
21
 
22
22
  ### Previews
23
23
 
24
- Run `npm run preview` to [publish a preview update](https://docs.expo.dev/eas/workflows/examples/publish-preview-update/) of your project, which can be viewed in Expo Go or in a development build.
24
+ Run `npm run draft` to [publish a preview update](https://docs.expo.dev/eas/workflows/examples/publish-preview-update/) of your project, which can be viewed in Expo Go or in a development build.
25
25
 
26
26
  ### Development Builds
27
27
 
@@ -1,5 +1,5 @@
1
1
  import { WorkflowJobResult, WorkflowLogLine, WorkflowLogs, WorkflowRunResult, WorkflowTriggerType } from './types';
2
- import { WorkflowRunByIdWithJobsQuery, WorkflowRunFragment } from '../../graphql/generated';
2
+ import { WorkflowRunByIdQuery, WorkflowRunByIdWithJobsQuery, WorkflowRunFragment } from '../../graphql/generated';
3
3
  import { Choice } from '../../prompts';
4
4
  import { ExpoGraphqlClient } from '../context/contextUtils/createGraphqlClient';
5
5
  export declare function computeTriggerInfoForWorkflowRun(run: WorkflowRunFragment): {
@@ -18,6 +18,16 @@ export declare function fetchAndProcessLogsFromJobAsync(state: {
18
18
  graphqlClient: ExpoGraphqlClient;
19
19
  }, job: WorkflowJobResult): Promise<WorkflowLogs | null>;
20
20
  export declare function infoForActiveWorkflowRunAsync(graphqlClient: ExpoGraphqlClient, workflowRun: WorkflowRunByIdWithJobsQuery['workflowRuns']['byId'], maxLogLines?: number): Promise<string>;
21
- export declare function infoForFailedWorkflowRunAsync(graphqlClient: ExpoGraphqlClient, workflowRun: WorkflowRunByIdWithJobsQuery['workflowRuns']['byId']): Promise<string>;
21
+ export declare function infoForFailedWorkflowRunAsync(graphqlClient: ExpoGraphqlClient, workflowRun: WorkflowRunByIdWithJobsQuery['workflowRuns']['byId'], maxLogLines?: number): Promise<string>;
22
22
  export declare function fileExistsAsync(filePath: string): Promise<boolean>;
23
23
  export declare function maybeReadStdinAsync(): Promise<string | null>;
24
+ export declare function showWorkflowStatusAsync(graphqlClient: ExpoGraphqlClient, { workflowRunId, spinnerUsesStdErr, waitForCompletion, }: {
25
+ workflowRunId: string;
26
+ spinnerUsesStdErr: boolean;
27
+ waitForCompletion?: boolean;
28
+ }): Promise<WorkflowRunByIdQuery['workflowRuns']['byId']>;
29
+ export declare const workflowRunExitCodes: {
30
+ WORKFLOW_FAILED: number;
31
+ WORKFLOW_CANCELED: number;
32
+ WAIT_ABORTED: number;
33
+ };
@@ -1,13 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.maybeReadStdinAsync = exports.fileExistsAsync = exports.infoForFailedWorkflowRunAsync = exports.infoForActiveWorkflowRunAsync = exports.fetchAndProcessLogsFromJobAsync = exports.processWorkflowRuns = exports.choicesFromWorkflowLogs = exports.choiceFromWorkflowJob = exports.choiceFromWorkflowRun = exports.computeTriggerInfoForWorkflowRun = void 0;
3
+ exports.workflowRunExitCodes = exports.showWorkflowStatusAsync = exports.maybeReadStdinAsync = exports.fileExistsAsync = exports.infoForFailedWorkflowRunAsync = exports.infoForActiveWorkflowRunAsync = exports.fetchAndProcessLogsFromJobAsync = exports.processWorkflowRuns = exports.choicesFromWorkflowLogs = exports.choiceFromWorkflowJob = exports.choiceFromWorkflowRun = exports.computeTriggerInfoForWorkflowRun = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
6
  const fs = tslib_1.__importStar(require("node:fs"));
6
7
  const fetchLogs_1 = require("./fetchLogs");
7
8
  const types_1 = require("./types");
8
9
  const generated_1 = require("../../graphql/generated");
10
+ const WorkflowRunQuery_1 = require("../../graphql/queries/WorkflowRunQuery");
9
11
  const log_1 = tslib_1.__importDefault(require("../../log"));
12
+ const ora_1 = require("../../ora");
10
13
  const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
14
+ const promise_1 = require("../../utils/promise");
11
15
  function computeTriggerInfoForWorkflowRun(run) {
12
16
  let triggerType = types_1.WorkflowTriggerType.OTHER;
13
17
  let trigger = '';
@@ -190,9 +194,11 @@ async function infoForActiveWorkflowRunAsync(graphqlClient, workflowRun, maxLogL
190
194
  return statusLines.join('\n');
191
195
  }
192
196
  exports.infoForActiveWorkflowRunAsync = infoForActiveWorkflowRunAsync;
193
- async function infoForFailedWorkflowRunAsync(graphqlClient, workflowRun) {
197
+ async function infoForFailedWorkflowRunAsync(graphqlClient, workflowRun, maxLogLines = -1 // -1 means no limit
198
+ ) {
194
199
  const statusLines = [];
195
200
  const statusValues = [];
201
+ const logLinesToKeep = maxLogLines === -1 ? Infinity : maxLogLines;
196
202
  for (const job of workflowRun.jobs) {
197
203
  if (job.status !== generated_1.WorkflowJobStatus.Failure) {
198
204
  continue;
@@ -204,7 +210,7 @@ async function infoForFailedWorkflowRunAsync(graphqlClient, workflowRun) {
204
210
  if (steps.length > 0) {
205
211
  const failedStep = steps.find(step => step.status === 'fail');
206
212
  if (failedStep) {
207
- const logs = failedStep.logLines?.map(line => line.msg) ?? [];
213
+ const logs = failedStep.logLines?.map(line => line.msg).slice(-logLinesToKeep) ?? [];
208
214
  statusValues.push({ label: ' Failed step', value: failedStep.name });
209
215
  statusValues.push({
210
216
  label: ' Logs for failed step',
@@ -252,3 +258,68 @@ async function maybeReadStdinAsync() {
252
258
  });
253
259
  }
254
260
  exports.maybeReadStdinAsync = maybeReadStdinAsync;
261
+ async function showWorkflowStatusAsync(graphqlClient, { workflowRunId, spinnerUsesStdErr, waitForCompletion = true, }) {
262
+ log_1.default.log('Waiting for workflow run to complete. You can press Ctrl+C to exit.');
263
+ const spinner = (0, ora_1.ora)({
264
+ stream: spinnerUsesStdErr ? process.stderr : process.stdout,
265
+ text: '',
266
+ }).start();
267
+ spinner.prefixText = (0, chalk_1.default) `{bold.yellow Workflow run is waiting to start:}`;
268
+ let failedFetchesCount = 0;
269
+ while (true) {
270
+ try {
271
+ const workflowRun = await WorkflowRunQuery_1.WorkflowRunQuery.withJobsByIdAsync(graphqlClient, workflowRunId, {
272
+ useCache: false,
273
+ });
274
+ failedFetchesCount = 0;
275
+ switch (workflowRun.status) {
276
+ case generated_1.WorkflowRunStatus.New:
277
+ break;
278
+ case generated_1.WorkflowRunStatus.InProgress: {
279
+ spinner.prefixText = (0, chalk_1.default) `{bold.green Workflow run is in progress:}`;
280
+ spinner.text = await infoForActiveWorkflowRunAsync(graphqlClient, workflowRun, 5);
281
+ break;
282
+ }
283
+ case generated_1.WorkflowRunStatus.ActionRequired:
284
+ spinner.prefixText = (0, chalk_1.default) `{bold.yellow Workflow run is waiting for action:}`;
285
+ break;
286
+ case generated_1.WorkflowRunStatus.Canceled:
287
+ spinner.prefixText = (0, chalk_1.default) `{bold.yellow Workflow has been canceled.}`;
288
+ spinner.stopAndPersist();
289
+ return workflowRun;
290
+ case generated_1.WorkflowRunStatus.Failure: {
291
+ spinner.prefixText = (0, chalk_1.default) `{bold.red Workflow has failed.}`;
292
+ const failedInfo = await infoForFailedWorkflowRunAsync(graphqlClient, workflowRun, 30);
293
+ spinner.fail(failedInfo);
294
+ return workflowRun;
295
+ }
296
+ case generated_1.WorkflowRunStatus.Success:
297
+ spinner.prefixText = (0, chalk_1.default) `{bold.green Workflow has completed successfully.}`;
298
+ spinner.text = '';
299
+ spinner.succeed('');
300
+ return workflowRun;
301
+ }
302
+ if (!waitForCompletion) {
303
+ if (spinner.isSpinning) {
304
+ spinner.stopAndPersist();
305
+ }
306
+ return workflowRun;
307
+ }
308
+ }
309
+ catch {
310
+ spinner.text = '⚠ Failed to fetch the workflow run status. Check your network connection.';
311
+ failedFetchesCount += 1;
312
+ if (failedFetchesCount > 6) {
313
+ spinner.fail('Failed to fetch the workflow run status 6 times in a row. Aborting wait.');
314
+ process.exit(exports.workflowRunExitCodes.WAIT_ABORTED);
315
+ }
316
+ }
317
+ await (0, promise_1.sleepAsync)(10 /* seconds */ * 1000 /* milliseconds */);
318
+ }
319
+ }
320
+ exports.showWorkflowStatusAsync = showWorkflowStatusAsync;
321
+ exports.workflowRunExitCodes = {
322
+ WORKFLOW_FAILED: 11,
323
+ WORKFLOW_CANCELED: 12,
324
+ WAIT_ABORTED: 13,
325
+ };
@@ -173,15 +173,6 @@ class EnvUpdate extends EasCommand_1.default {
173
173
  newType = undefined;
174
174
  }
175
175
  }
176
- let environmentFilePath;
177
- if ((newType ?? selectedVariable.type) === generated_1.EnvironmentSecretType.FileBase64 && value) {
178
- environmentFilePath = path_1.default.resolve(value);
179
- if (!(await fs_extra_1.default.pathExists(environmentFilePath))) {
180
- throw new Error(`File "${value}" does not exist`);
181
- }
182
- fileName = path_1.default.basename(environmentFilePath);
183
- }
184
- value = environmentFilePath ? await fs_extra_1.default.readFile(environmentFilePath, 'base64') : value;
185
176
  if (!environments || environments.length === 0) {
186
177
  environments = await (0, prompts_2.promptVariableEnvironmentAsync)({
187
178
  nonInteractive,
@@ -204,6 +195,23 @@ class EnvUpdate extends EasCommand_1.default {
204
195
  }
205
196
  }
206
197
  }
198
+ // If value is provided but type is not explicitly set, preserve the existing type
199
+ if (value && !newType) {
200
+ newType = selectedVariable.type;
201
+ }
202
+ if (newType === generated_1.EnvironmentSecretType.FileBase64 && value) {
203
+ const environmentFilePath = path_1.default.resolve(value);
204
+ if (!(await fs_extra_1.default.pathExists(environmentFilePath))) {
205
+ if (type === 'file') {
206
+ throw new Error(`File "${value}" does not exist`);
207
+ }
208
+ else {
209
+ throw new Error(`Variable "${selectedVariable.name}" is a file type, but "${value}" does not exist as a file. If you want to convert it to a string, pass --type string.`);
210
+ }
211
+ }
212
+ fileName = path_1.default.basename(environmentFilePath);
213
+ value = await fs_extra_1.default.readFile(environmentFilePath, 'base64');
214
+ }
207
215
  if (visibility) {
208
216
  newVisibility = (0, prompts_2.parseVisibility)(visibility);
209
217
  }
@@ -29,7 +29,6 @@ export default class New extends EasCommand {
29
29
  static flags: {
30
30
  'package-manager': import("@oclif/core/lib/interfaces").OptionFlag<"npm" | "pnpm" | "bun" | "yarn">;
31
31
  };
32
- static hidden: boolean;
33
32
  static contextDefinition: {
34
33
  loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
35
34
  };
@@ -86,7 +86,6 @@ class New extends EasCommand_1.default {
86
86
  default: 'npm',
87
87
  }),
88
88
  };
89
- static hidden = true;
90
89
  static contextDefinition = {
91
90
  ...this.ContextOptions.LoggedIn,
92
91
  };
@@ -114,10 +113,10 @@ class New extends EasCommand_1.default {
114
113
  log_1.default.log('🎉 We finished creating your new project.');
115
114
  log_1.default.newLine();
116
115
  log_1.default.log('Next steps:');
117
- log_1.default.withInfo(`Run \`cd ${(0, utils_1.printDirectory)(projectDirectory)}\` to navigate to your project.`);
118
- log_1.default.withInfo(`Run \`${packageManager} run draft\` to create a preview on EAS. ${(0, log_1.learnMore)('https://docs.expo.dev/eas/workflows/examples/publish-preview-update/')}`);
119
- log_1.default.withInfo(`Run \`${packageManager} run start\` to start developing locally. ${(0, log_1.learnMore)('https://docs.expo.dev/get-started/start-developing/')}`);
120
- log_1.default.withInfo(`See the README.md for more information about your project.`);
116
+ log_1.default.withInfo(`Run ${chalk_1.default.bold(`cd ${(0, utils_1.printDirectory)(projectDirectory)}`)} to navigate to your project.`);
117
+ log_1.default.withInfo(`Run ${chalk_1.default.bold(`${packageManager} run draft`)} to create a preview on EAS. ${(0, log_1.learnMore)('https://docs.expo.dev/eas/workflows/examples/publish-preview-update/')}`);
118
+ log_1.default.withInfo(`Run ${chalk_1.default.bold(`${packageManager} run start`)} to start developing locally. ${(0, log_1.learnMore)('https://docs.expo.dev/get-started/start-developing/')}`);
119
+ log_1.default.withInfo(`See the ${chalk_1.default.bold('README.md')} for more information about your project.`);
121
120
  }
122
121
  }
123
122
  exports.default = New;
@@ -382,6 +382,9 @@ class UpdatePublish extends EasCommand_1.default {
382
382
  publishSpinner.fail('Failed to publish updates');
383
383
  throw e;
384
384
  }
385
+ if ((0, utils_1.isBundleDiffingEnabled)(exp)) {
386
+ await (0, utils_1.prewarmDiffingAsync)(graphqlClient, projectId, newUpdates);
387
+ }
385
388
  if (!skipBundler && emitMetadata) {
386
389
  log_1.default.log('Generating eas-update-metadata.json');
387
390
  await (0, publish_1.generateEasMetadataAsync)(distRoot, (0, utils_1.getUpdateJsonInfosForUpdates)(newUpdates));
@@ -59,18 +59,11 @@ const WorkflowRevisionMutation_1 = require("../../graphql/mutations/WorkflowRevi
59
59
  const WorkflowRunMutation_1 = require("../../graphql/mutations/WorkflowRunMutation");
60
60
  const WorkflowRunQuery_1 = require("../../graphql/queries/WorkflowRunQuery");
61
61
  const log_1 = tslib_1.__importStar(require("../../log"));
62
- const ora_1 = require("../../ora");
63
62
  const projectUtils_1 = require("../../project/projectUtils");
64
63
  const uploadAccountScopedFileAsync_1 = require("../../project/uploadAccountScopedFileAsync");
65
64
  const uploadAccountScopedProjectSourceAsync_1 = require("../../project/uploadAccountScopedProjectSourceAsync");
66
65
  const json_1 = require("../../utils/json");
67
- const promise_1 = require("../../utils/promise");
68
66
  const workflowFile_1 = require("../../utils/workflowFile");
69
- const EXIT_CODES = {
70
- WORKFLOW_FAILED: 11,
71
- WORKFLOW_CANCELED: 12,
72
- WAIT_ABORTED: 13,
73
- };
74
67
  class WorkflowRun extends EasCommand_1.default {
75
68
  static description = 'run an EAS workflow. The entire local project directory will be packaged and uploaded to EAS servers for the workflow run, unless the --ref flag is used.';
76
69
  static args = [{ name: 'file', description: 'Path to the workflow file to run' }];
@@ -110,7 +103,9 @@ class WorkflowRun extends EasCommand_1.default {
110
103
  nonInteractive: flags['non-interactive'],
111
104
  withServerSideEnvironment: null,
112
105
  });
113
- const { projectId, exp: { slug: projectName }, } = await getDynamicPrivateProjectConfigAsync();
106
+ const { projectId, exp: { slug: projectName }, } = await getDynamicPrivateProjectConfigAsync({
107
+ skipPlugins: true,
108
+ });
114
109
  const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId);
115
110
  let yamlConfig;
116
111
  let workflowRunId;
@@ -294,7 +289,7 @@ class WorkflowRun extends EasCommand_1.default {
294
289
  process.exit(0);
295
290
  }
296
291
  const spinnerUsesStdErr = (0, getenv_1.boolish)('CI', false) || flags.json;
297
- const { status } = await waitForWorkflowRunToEndAsync(graphqlClient, {
292
+ const { status } = await (0, utils_1.showWorkflowStatusAsync)(graphqlClient, {
298
293
  workflowRunId,
299
294
  spinnerUsesStdErr,
300
295
  });
@@ -308,64 +303,11 @@ class WorkflowRun extends EasCommand_1.default {
308
303
  });
309
304
  }
310
305
  if (status === generated_1.WorkflowRunStatus.Failure) {
311
- process.exit(EXIT_CODES.WORKFLOW_FAILED);
306
+ process.exit(utils_1.workflowRunExitCodes.WORKFLOW_FAILED);
312
307
  }
313
308
  else if (status === generated_1.WorkflowRunStatus.Canceled) {
314
- process.exit(EXIT_CODES.WORKFLOW_CANCELED);
309
+ process.exit(utils_1.workflowRunExitCodes.WORKFLOW_CANCELED);
315
310
  }
316
311
  }
317
312
  }
318
313
  exports.default = WorkflowRun;
319
- async function waitForWorkflowRunToEndAsync(graphqlClient, { workflowRunId, spinnerUsesStdErr }) {
320
- log_1.default.log('Waiting for workflow run to complete. You can press Ctrl+C to exit.');
321
- const spinner = (0, ora_1.ora)({
322
- stream: spinnerUsesStdErr ? process.stderr : process.stdout,
323
- text: '',
324
- }).start();
325
- spinner.prefixText = (0, chalk_1.default) `{bold.yellow Workflow run is waiting to start:}`;
326
- let failedFetchesCount = 0;
327
- while (true) {
328
- try {
329
- const workflowRun = await WorkflowRunQuery_1.WorkflowRunQuery.withJobsByIdAsync(graphqlClient, workflowRunId, {
330
- useCache: false,
331
- });
332
- failedFetchesCount = 0;
333
- switch (workflowRun.status) {
334
- case generated_1.WorkflowRunStatus.New:
335
- break;
336
- case generated_1.WorkflowRunStatus.InProgress: {
337
- spinner.prefixText = (0, chalk_1.default) `{bold.green Workflow run is in progress:}`;
338
- spinner.text = await (0, utils_1.infoForActiveWorkflowRunAsync)(graphqlClient, workflowRun, 5);
339
- break;
340
- }
341
- case generated_1.WorkflowRunStatus.ActionRequired:
342
- spinner.prefixText = (0, chalk_1.default) `{bold.yellow Workflow run is waiting for action:}`;
343
- break;
344
- case generated_1.WorkflowRunStatus.Canceled:
345
- spinner.prefixText = (0, chalk_1.default) `{bold.yellow Workflow has been canceled.}`;
346
- spinner.stopAndPersist();
347
- return workflowRun;
348
- case generated_1.WorkflowRunStatus.Failure: {
349
- spinner.prefixText = (0, chalk_1.default) `{bold.red Workflow has failed.}`;
350
- const failedInfo = await (0, utils_1.infoForFailedWorkflowRunAsync)(graphqlClient, workflowRun);
351
- spinner.fail(failedInfo);
352
- return workflowRun;
353
- }
354
- case generated_1.WorkflowRunStatus.Success:
355
- spinner.prefixText = (0, chalk_1.default) `{bold.green Workflow has completed successfully.}`;
356
- spinner.text = '';
357
- spinner.succeed('');
358
- return workflowRun;
359
- }
360
- }
361
- catch {
362
- spinner.text = '⚠ Failed to fetch the workflow run status. Check your network connection.';
363
- failedFetchesCount += 1;
364
- if (failedFetchesCount > 6) {
365
- spinner.fail('Failed to fetch the workflow run status 6 times in a row. Aborting wait.');
366
- process.exit(EXIT_CODES.WAIT_ABORTED);
367
- }
368
- }
369
- await (0, promise_1.sleepAsync)(10 /* seconds */ * 1000 /* milliseconds */);
370
- }
371
- }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * EAS Workflow Status Command
3
+ *
4
+ * This command shows the status of an existing workflow run.
5
+ *
6
+ * If no run ID is provided, you will be prompted to select from recent workflow runs for the current project.
7
+ *
8
+ * If the selected run is still in progress, the command will show the progress of the run, with an option
9
+ * to show periodic status updates while waiting for completion (similar to `eas workflow:run --wait`).
10
+ *
11
+ */
12
+ import EasCommand from '../../commandUtils/EasCommand';
13
+ export default class WorkflowStatus extends EasCommand {
14
+ static description: string;
15
+ static args: {
16
+ name: string;
17
+ description: string;
18
+ }[];
19
+ static flags: {
20
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
21
+ wait: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ };
24
+ static contextDefinition: {
25
+ loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
26
+ vcsClient: import("../../commandUtils/context/VcsClientContextField").default;
27
+ projectDir: import("../../commandUtils/context/ProjectDirContextField").default;
28
+ getDynamicPublicProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicPublicProjectConfigContextField;
29
+ getDynamicPrivateProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicPrivateProjectConfigContextField;
30
+ };
31
+ runAsync(): Promise<void>;
32
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * EAS Workflow Status Command
4
+ *
5
+ * This command shows the status of an existing workflow run.
6
+ *
7
+ * If no run ID is provided, you will be prompted to select from recent workflow runs for the current project.
8
+ *
9
+ * If the selected run is still in progress, the command will show the progress of the run, with an option
10
+ * to show periodic status updates while waiting for completion (similar to `eas workflow:run --wait`).
11
+ *
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const tslib_1 = require("tslib");
15
+ const core_1 = require("@oclif/core");
16
+ const getenv_1 = require("getenv");
17
+ const url_1 = require("../../build/utils/url");
18
+ const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
19
+ const flags_1 = require("../../commandUtils/flags");
20
+ const utils_1 = require("../../commandUtils/workflow/utils");
21
+ const generated_1 = require("../../graphql/generated");
22
+ const AppQuery_1 = require("../../graphql/queries/AppQuery");
23
+ const WorkflowRunQuery_1 = require("../../graphql/queries/WorkflowRunQuery");
24
+ const log_1 = tslib_1.__importStar(require("../../log"));
25
+ const projectUtils_1 = require("../../project/projectUtils");
26
+ const prompts_1 = require("../../prompts");
27
+ const json_1 = require("../../utils/json");
28
+ class WorkflowStatus extends EasCommand_1.default {
29
+ static description = 'show the status of an existing workflow run. If no run ID is provided, you will be prompted to select from recent workflow runs for the current project.';
30
+ static args = [
31
+ {
32
+ name: 'WORKFLOW_RUN_ID',
33
+ description: 'A workflow run ID.',
34
+ },
35
+ ];
36
+ static flags = {
37
+ ...flags_1.EASNonInteractiveFlag,
38
+ wait: core_1.Flags.boolean({
39
+ default: false,
40
+ allowNo: true,
41
+ description: 'Exit codes: 0 = success, 11 = failure, 12 = canceled, 13 = wait aborted.',
42
+ summary: 'Wait for workflow run to complete. Defaults to false.',
43
+ }),
44
+ ...flags_1.EasJsonOnlyFlag,
45
+ };
46
+ static contextDefinition = {
47
+ ...this.ContextOptions.DynamicProjectConfig,
48
+ ...this.ContextOptions.ProjectDir,
49
+ ...this.ContextOptions.Vcs,
50
+ ...this.ContextOptions.LoggedIn,
51
+ };
52
+ async runAsync() {
53
+ const { flags, args } = await this.parse(WorkflowStatus);
54
+ if (flags.json) {
55
+ (0, json_1.enableJsonOutput)();
56
+ }
57
+ const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, } = await this.getContextAsync(WorkflowStatus, {
58
+ nonInteractive: flags['non-interactive'],
59
+ withServerSideEnvironment: null,
60
+ });
61
+ const { projectId, exp: { slug: projectName }, } = await getDynamicPrivateProjectConfigAsync();
62
+ const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId);
63
+ let workflowRunId = args.WORKFLOW_RUN_ID;
64
+ if (!workflowRunId && flags['non-interactive']) {
65
+ throw new Error('Workflow run ID is required in non-interactive mode');
66
+ }
67
+ if (!workflowRunId) {
68
+ const queryResult = await AppQuery_1.AppQuery.byIdWorkflowRunsFilteredByStatusAsync(graphqlClient, projectId, undefined, 50);
69
+ const runs = (0, utils_1.processWorkflowRuns)(queryResult);
70
+ if (runs.length === 0) {
71
+ log_1.default.warn('No workflow runs to show');
72
+ return;
73
+ }
74
+ const answers = await (0, prompts_1.promptAsync)({
75
+ type: 'select',
76
+ name: 'selectedRun',
77
+ message: 'Select a workflow run:',
78
+ choices: runs.map(run => (0, utils_1.choiceFromWorkflowRun)(run)),
79
+ });
80
+ workflowRunId = answers.selectedRun;
81
+ }
82
+ log_1.default.addNewLineIfNone();
83
+ log_1.default.log(`See logs: ${(0, log_1.link)((0, url_1.getWorkflowRunUrl)(account.name, projectName, workflowRunId))}`);
84
+ log_1.default.addNewLineIfNone();
85
+ const spinnerUsesStdErr = (0, getenv_1.boolish)('CI', false) || flags.json;
86
+ await (0, utils_1.showWorkflowStatusAsync)(graphqlClient, {
87
+ workflowRunId,
88
+ spinnerUsesStdErr,
89
+ waitForCompletion: flags.wait,
90
+ });
91
+ const workflowRun = await WorkflowRunQuery_1.WorkflowRunQuery.withJobsByIdAsync(graphqlClient, workflowRunId, {
92
+ useCache: false,
93
+ });
94
+ const status = workflowRun.status;
95
+ if (flags.json) {
96
+ (0, json_1.printJsonOnlyOutput)({
97
+ ...workflowRun,
98
+ url: (0, url_1.getWorkflowRunUrl)(account.name, projectName, workflowRunId),
99
+ });
100
+ }
101
+ if (status === generated_1.WorkflowRunStatus.Failure) {
102
+ process.exit(utils_1.workflowRunExitCodes.WORKFLOW_FAILED);
103
+ }
104
+ else if (status === generated_1.WorkflowRunStatus.Canceled) {
105
+ process.exit(utils_1.workflowRunExitCodes.WORKFLOW_CANCELED);
106
+ }
107
+ }
108
+ }
109
+ exports.default = WorkflowStatus;