eas-cli 16.15.0 → 16.16.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.
Files changed (38) hide show
  1. package/README.md +137 -84
  2. package/build/commandUtils/workflow/fetchLogs.d.ts +2 -0
  3. package/build/commandUtils/workflow/fetchLogs.js +16 -0
  4. package/build/commandUtils/workflow/stateMachine.d.ts +44 -0
  5. package/build/commandUtils/workflow/stateMachine.js +212 -0
  6. package/build/commandUtils/workflow/types.d.ts +39 -0
  7. package/build/commandUtils/workflow/types.js +13 -0
  8. package/build/commandUtils/workflow/utils.d.ts +12 -0
  9. package/build/commandUtils/workflow/utils.js +116 -0
  10. package/build/commands/workflow/cancel.js +3 -6
  11. package/build/commands/workflow/logs.d.ts +18 -0
  12. package/build/commands/workflow/logs.js +94 -0
  13. package/build/commands/workflow/run.d.ts +105 -0
  14. package/build/commands/workflow/run.js +280 -0
  15. package/build/commands/workflow/runs.js +4 -3
  16. package/build/commands/workflow/view.d.ts +17 -0
  17. package/build/commands/workflow/view.js +95 -0
  18. package/build/credentials/ios/appstore/bundleIdCapabilities.d.ts +4 -17
  19. package/build/credentials/ios/appstore/bundleIdCapabilities.js +45 -625
  20. package/build/credentials/ios/appstore/capabilityIdentifiers.js +33 -34
  21. package/build/credentials/ios/appstore/capabilityList.d.ts +33 -0
  22. package/build/credentials/ios/appstore/capabilityList.js +646 -0
  23. package/build/graphql/generated.d.ts +236 -19
  24. package/build/graphql/queries/WorkflowJobQuery.d.ts +7 -0
  25. package/build/graphql/queries/WorkflowJobQuery.js +29 -0
  26. package/build/graphql/queries/WorkflowRunQuery.js +13 -13
  27. package/build/graphql/types/WorkflowJob.d.ts +1 -0
  28. package/build/graphql/types/WorkflowJob.js +32 -0
  29. package/build/graphql/types/WorkflowRun.js +18 -0
  30. package/build/worker/assets.d.ts +0 -3
  31. package/build/worker/assets.js +3 -3
  32. package/build/worker/upload.js +4 -8
  33. package/build/worker/utils/multipart.d.ts +5 -4
  34. package/build/worker/utils/multipart.js +44 -9
  35. package/oclif.manifest.json +85 -1
  36. package/package.json +2 -2
  37. package/build/commandUtils/workflows.d.ts +0 -20
  38. package/build/commandUtils/workflows.js +0 -21
@@ -0,0 +1,2 @@
1
+ import { WorkflowJobResult } from './types';
2
+ export declare function fetchRawLogsForJobAsync(job: WorkflowJobResult): Promise<string | null>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchRawLogsForJobAsync = void 0;
4
+ // This function is in a separate module for testing purposes
5
+ async function fetchRawLogsForJobAsync(job) {
6
+ const firstLogFileUrl = job.turtleJobRun?.logFileUrls?.[0];
7
+ if (!firstLogFileUrl) {
8
+ return null;
9
+ }
10
+ const response = await fetch(firstLogFileUrl, {
11
+ method: 'GET',
12
+ });
13
+ const rawLogs = await response.text();
14
+ return rawLogs;
15
+ }
16
+ exports.fetchRawLogsForJobAsync = fetchRawLogsForJobAsync;
@@ -0,0 +1,44 @@
1
+ import { WorkflowJobResult, WorkflowLogs } from './types';
2
+ import { ExpoGraphqlClient } from '../context/contextUtils/createGraphqlClient';
3
+ export declare enum WorkflowCommandSelectionStateValue {
4
+ WORKFLOW_RUN_SELECTION = "WORKFLOW_RUN_SELECTION",
5
+ WORKFLOW_JOB_SELECTION = "WORKFLOW_JOB_SELECTION",
6
+ WORKFLOW_STEP_SELECTION = "WORKFLOW_STEP_SELECTION",
7
+ FINISH = "FINISH",
8
+ ERROR = "ERROR"
9
+ }
10
+ export type WorkflowCommandSelectionState = {
11
+ graphqlClient: ExpoGraphqlClient;
12
+ projectId: string;
13
+ nonInteractive: boolean;
14
+ allSteps: boolean;
15
+ state: WorkflowCommandSelectionStateValue;
16
+ runId?: string;
17
+ jobId?: string;
18
+ step?: string;
19
+ job?: WorkflowJobResult;
20
+ logs?: WorkflowLogs | null;
21
+ message?: string;
22
+ };
23
+ export type WorkflowCommandSelectionStateParameters = Omit<WorkflowCommandSelectionState, 'graphqlClient' | 'projectId' | 'state' | 'nonInteractive' | 'allSteps'>;
24
+ export type WorkflowCommandSelectionAction = (prevState: WorkflowCommandSelectionState) => Promise<WorkflowCommandSelectionState>;
25
+ export declare function moveToNewWorkflowCommandSelectionState(previousState: WorkflowCommandSelectionState, newStateValue: WorkflowCommandSelectionStateValue, parameters: WorkflowCommandSelectionStateParameters): WorkflowCommandSelectionState;
26
+ export declare function moveToWorkflowRunSelectionState(previousState: WorkflowCommandSelectionState, params?: {
27
+ runId?: string | undefined;
28
+ }): WorkflowCommandSelectionState;
29
+ export declare function moveToWorkflowJobSelectionState(previousState: WorkflowCommandSelectionState, params: {
30
+ jobId?: string | undefined;
31
+ runId?: string | undefined;
32
+ }): WorkflowCommandSelectionState;
33
+ export declare function moveToWorkflowStepSelectionState(previousState: WorkflowCommandSelectionState, params: {
34
+ job: WorkflowJobResult;
35
+ }): WorkflowCommandSelectionState;
36
+ export declare function moveToWorkflowSelectionFinishedState(previousState: WorkflowCommandSelectionState, params: {
37
+ step: string;
38
+ logs: WorkflowLogs;
39
+ }): WorkflowCommandSelectionState;
40
+ export declare function moveToWorkflowSelectionErrorState(previousState: WorkflowCommandSelectionState, message: string): WorkflowCommandSelectionState;
41
+ export declare const workflowRunSelectionAction: WorkflowCommandSelectionAction;
42
+ export declare const workflowJobSelectionAction: WorkflowCommandSelectionAction;
43
+ export declare const workflowStepSelectionAction: WorkflowCommandSelectionAction;
44
+ export declare const executeWorkflowSelectionActionsAsync: WorkflowCommandSelectionAction;
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeWorkflowSelectionActionsAsync = exports.workflowStepSelectionAction = exports.workflowJobSelectionAction = exports.workflowRunSelectionAction = exports.moveToWorkflowSelectionErrorState = exports.moveToWorkflowSelectionFinishedState = exports.moveToWorkflowStepSelectionState = exports.moveToWorkflowJobSelectionState = exports.moveToWorkflowRunSelectionState = exports.moveToNewWorkflowCommandSelectionState = exports.WorkflowCommandSelectionStateValue = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const utils_1 = require("./utils");
6
+ const AppQuery_1 = require("../../graphql/queries/AppQuery");
7
+ const WorkflowJobQuery_1 = require("../../graphql/queries/WorkflowJobQuery");
8
+ const WorkflowRunQuery_1 = require("../../graphql/queries/WorkflowRunQuery");
9
+ const log_1 = tslib_1.__importDefault(require("../../log"));
10
+ const prompts_1 = require("../../prompts");
11
+ /*
12
+ * State machine types and functions for moving between different workflow command states
13
+ */
14
+ var WorkflowCommandSelectionStateValue;
15
+ (function (WorkflowCommandSelectionStateValue) {
16
+ WorkflowCommandSelectionStateValue["WORKFLOW_RUN_SELECTION"] = "WORKFLOW_RUN_SELECTION";
17
+ WorkflowCommandSelectionStateValue["WORKFLOW_JOB_SELECTION"] = "WORKFLOW_JOB_SELECTION";
18
+ WorkflowCommandSelectionStateValue["WORKFLOW_STEP_SELECTION"] = "WORKFLOW_STEP_SELECTION";
19
+ WorkflowCommandSelectionStateValue["FINISH"] = "FINISH";
20
+ WorkflowCommandSelectionStateValue["ERROR"] = "ERROR";
21
+ })(WorkflowCommandSelectionStateValue || (exports.WorkflowCommandSelectionStateValue = WorkflowCommandSelectionStateValue = {}));
22
+ const workflowCommandSelectionAllowedStateTransitions = {
23
+ WORKFLOW_JOB_SELECTION: [
24
+ WorkflowCommandSelectionStateValue.WORKFLOW_STEP_SELECTION,
25
+ WorkflowCommandSelectionStateValue.WORKFLOW_RUN_SELECTION,
26
+ WorkflowCommandSelectionStateValue.ERROR,
27
+ WorkflowCommandSelectionStateValue.FINISH,
28
+ ],
29
+ WORKFLOW_RUN_SELECTION: [
30
+ WorkflowCommandSelectionStateValue.WORKFLOW_JOB_SELECTION,
31
+ WorkflowCommandSelectionStateValue.ERROR,
32
+ ],
33
+ WORKFLOW_STEP_SELECTION: [
34
+ WorkflowCommandSelectionStateValue.WORKFLOW_JOB_SELECTION,
35
+ WorkflowCommandSelectionStateValue.ERROR,
36
+ WorkflowCommandSelectionStateValue.FINISH,
37
+ ],
38
+ ERROR: [WorkflowCommandSelectionStateValue.WORKFLOW_RUN_SELECTION],
39
+ FINISH: [],
40
+ };
41
+ function moveToNewWorkflowCommandSelectionState(previousState, newStateValue, parameters) {
42
+ if (!workflowCommandSelectionAllowedStateTransitions[previousState.state].includes(newStateValue)) {
43
+ const errorMessage = `Invalid state transition from ${previousState.state} to ${newStateValue}. Allowed transitions from ${previousState.state}: ${workflowCommandSelectionAllowedStateTransitions[previousState.state].join(', ')}`;
44
+ throw new Error(errorMessage);
45
+ }
46
+ return {
47
+ ...previousState,
48
+ state: newStateValue,
49
+ ...parameters,
50
+ };
51
+ }
52
+ exports.moveToNewWorkflowCommandSelectionState = moveToNewWorkflowCommandSelectionState;
53
+ function moveToWorkflowRunSelectionState(previousState, params) {
54
+ return moveToNewWorkflowCommandSelectionState(previousState, WorkflowCommandSelectionStateValue.WORKFLOW_RUN_SELECTION, {
55
+ runId: params?.runId,
56
+ jobId: undefined,
57
+ });
58
+ }
59
+ exports.moveToWorkflowRunSelectionState = moveToWorkflowRunSelectionState;
60
+ function moveToWorkflowJobSelectionState(previousState, params) {
61
+ return moveToNewWorkflowCommandSelectionState(previousState, WorkflowCommandSelectionStateValue.WORKFLOW_JOB_SELECTION, params);
62
+ }
63
+ exports.moveToWorkflowJobSelectionState = moveToWorkflowJobSelectionState;
64
+ function moveToWorkflowStepSelectionState(previousState, params) {
65
+ return moveToNewWorkflowCommandSelectionState(previousState, WorkflowCommandSelectionStateValue.WORKFLOW_STEP_SELECTION, params);
66
+ }
67
+ exports.moveToWorkflowStepSelectionState = moveToWorkflowStepSelectionState;
68
+ function moveToWorkflowSelectionFinishedState(previousState, params) {
69
+ return moveToNewWorkflowCommandSelectionState(previousState, WorkflowCommandSelectionStateValue.FINISH, params);
70
+ }
71
+ exports.moveToWorkflowSelectionFinishedState = moveToWorkflowSelectionFinishedState;
72
+ function moveToWorkflowSelectionErrorState(previousState, message) {
73
+ return moveToNewWorkflowCommandSelectionState(previousState, WorkflowCommandSelectionStateValue.ERROR, {
74
+ message,
75
+ });
76
+ }
77
+ exports.moveToWorkflowSelectionErrorState = moveToWorkflowSelectionErrorState;
78
+ // eslint-disable-next-line async-protect/async-suffix
79
+ const workflowRunSelectionAction = async (prevState) => {
80
+ const { graphqlClient, projectId, runId, jobId, allSteps } = prevState;
81
+ log_1.default.debug(`workflowRunSelectionAction: runId = ${runId}, jobId = ${jobId}, allSteps = ${allSteps}`);
82
+ if (runId) {
83
+ return moveToWorkflowJobSelectionState(prevState, { runId });
84
+ }
85
+ const runs = await AppQuery_1.AppQuery.byIdWorkflowRunsFilteredByStatusAsync(graphqlClient, projectId, undefined, 20);
86
+ if (runs.length === 0) {
87
+ return moveToWorkflowSelectionErrorState(prevState, 'No workflow runs found');
88
+ }
89
+ const processedRuns = (0, utils_1.processWorkflowRuns)(runs);
90
+ const choices = processedRuns.map(run => (0, utils_1.choiceFromWorkflowRun)(run));
91
+ const selectedId = (await (0, prompts_1.promptAsync)({
92
+ type: 'select',
93
+ name: 'selectedRun',
94
+ message: 'Select a workflow run:',
95
+ choices,
96
+ })).selectedRun;
97
+ return moveToWorkflowJobSelectionState(prevState, { runId: selectedId });
98
+ };
99
+ exports.workflowRunSelectionAction = workflowRunSelectionAction;
100
+ // eslint-disable-next-line async-protect/async-suffix
101
+ const workflowJobSelectionAction = async (prevState) => {
102
+ const { graphqlClient, runId, jobId, nonInteractive, allSteps } = prevState;
103
+ log_1.default.debug(`workflowJobSelectionAction: runId = ${runId}, jobId = ${jobId}, allSteps = ${allSteps}`);
104
+ if (jobId) {
105
+ let workflowJobResult = undefined;
106
+ try {
107
+ workflowJobResult = await WorkflowJobQuery_1.WorkflowJobQuery.byIdAsync(graphqlClient, jobId, {
108
+ useCache: false,
109
+ });
110
+ return moveToWorkflowStepSelectionState(prevState, { job: workflowJobResult });
111
+ }
112
+ catch { }
113
+ if (nonInteractive && !workflowJobResult) {
114
+ return moveToWorkflowSelectionErrorState(prevState, 'No workflow job found that matched the provided ID');
115
+ }
116
+ else {
117
+ // The passed in ID may be a run ID, pass it back to run selection action
118
+ return moveToWorkflowRunSelectionState(prevState, { runId: jobId });
119
+ }
120
+ }
121
+ else {
122
+ // No job ID was passed in
123
+ if (nonInteractive) {
124
+ return moveToWorkflowSelectionErrorState(prevState, 'No workflow job ID provided in non-interactive mode');
125
+ }
126
+ else if (!runId) {
127
+ // If no jobId or runId, we should go back to run selection
128
+ return moveToWorkflowRunSelectionState(prevState);
129
+ }
130
+ const workflowRunResult = await WorkflowRunQuery_1.WorkflowRunQuery.withJobsByIdAsync(graphqlClient, runId, {
131
+ useCache: false,
132
+ });
133
+ if (!workflowRunResult) {
134
+ return moveToWorkflowSelectionErrorState(prevState, 'No workflow run found that matched the provided ID');
135
+ }
136
+ const choices = [
137
+ ...workflowRunResult.jobs.map((job, i) => (0, utils_1.choiceFromWorkflowJob)(job, i)),
138
+ {
139
+ title: 'Go back and select a different workflow run',
140
+ value: -1,
141
+ },
142
+ ];
143
+ const selectedJobIndex = (await (0, prompts_1.promptAsync)({
144
+ type: 'select',
145
+ name: 'selectedJob',
146
+ message: 'Select a job:',
147
+ choices,
148
+ })).selectedJob;
149
+ if (selectedJobIndex === -1) {
150
+ return moveToWorkflowRunSelectionState(prevState);
151
+ }
152
+ const selectedJob = workflowRunResult.jobs[selectedJobIndex];
153
+ return moveToWorkflowStepSelectionState(prevState, { job: selectedJob });
154
+ }
155
+ };
156
+ exports.workflowJobSelectionAction = workflowJobSelectionAction;
157
+ // eslint-disable-next-line async-protect/async-suffix
158
+ const workflowStepSelectionAction = async (prevState) => {
159
+ const { job, allSteps } = prevState;
160
+ log_1.default.debug(`workflowStepSelectionAction: job = ${job?.id}, allSteps = ${allSteps}`);
161
+ if (!job) {
162
+ return moveToWorkflowSelectionErrorState(prevState, 'No job found');
163
+ }
164
+ const logs = await (0, utils_1.processLogsFromJobAsync)(job);
165
+ if (!logs) {
166
+ return moveToWorkflowSelectionErrorState(prevState, 'No logs found');
167
+ }
168
+ if (allSteps) {
169
+ return moveToWorkflowSelectionFinishedState(prevState, { step: '', logs });
170
+ }
171
+ const choices = [
172
+ ...(0, utils_1.choicesFromWorkflowLogs)(logs),
173
+ {
174
+ title: 'Go back and select a different workflow job',
175
+ value: 'go-back',
176
+ },
177
+ ];
178
+ const selectedStep = (await (0, prompts_1.promptAsync)({
179
+ type: 'select',
180
+ name: 'selectedStep',
181
+ message: 'Select a step:',
182
+ choices,
183
+ })).selectedStep ?? '';
184
+ if (selectedStep === 'go-back') {
185
+ return moveToWorkflowJobSelectionState(prevState, {
186
+ runId: job.workflowRun.id,
187
+ jobId: undefined,
188
+ });
189
+ }
190
+ return moveToWorkflowSelectionFinishedState(prevState, { step: selectedStep, logs });
191
+ };
192
+ exports.workflowStepSelectionAction = workflowStepSelectionAction;
193
+ const executeWorkflowSelectionActionsAsync = async (prevState) => {
194
+ let currentState = prevState;
195
+ while (currentState.state !== WorkflowCommandSelectionStateValue.FINISH &&
196
+ currentState.state !== WorkflowCommandSelectionStateValue.ERROR) {
197
+ log_1.default.debug(`${currentState.state}`);
198
+ switch (currentState.state) {
199
+ case WorkflowCommandSelectionStateValue.WORKFLOW_JOB_SELECTION:
200
+ currentState = await (0, exports.workflowJobSelectionAction)(currentState);
201
+ break;
202
+ case WorkflowCommandSelectionStateValue.WORKFLOW_RUN_SELECTION:
203
+ currentState = await (0, exports.workflowRunSelectionAction)(currentState);
204
+ break;
205
+ case WorkflowCommandSelectionStateValue.WORKFLOW_STEP_SELECTION:
206
+ currentState = await (0, exports.workflowStepSelectionAction)(currentState);
207
+ break;
208
+ }
209
+ }
210
+ return currentState;
211
+ };
212
+ exports.executeWorkflowSelectionActionsAsync = executeWorkflowSelectionActionsAsync;
@@ -0,0 +1,39 @@
1
+ import { WorkflowJobByIdQuery, WorkflowRunByIdWithJobsQuery } from '../../graphql/generated';
2
+ export declare enum WorkflowTriggerType {
3
+ MANUAL = "Manual",
4
+ GITHUB = "GitHub",
5
+ SCHEDULED = "Scheduled",
6
+ OTHER = "Other"
7
+ }
8
+ export type WorkflowRunResult = {
9
+ id: string;
10
+ status: string;
11
+ gitCommitMessage: string | null;
12
+ gitCommitHash: string | null;
13
+ triggerType: WorkflowTriggerType;
14
+ trigger: string | null;
15
+ startedAt: string;
16
+ finishedAt: string;
17
+ workflowId: string;
18
+ workflowName: string | null;
19
+ workflowFileName: string;
20
+ };
21
+ export type WorkflowResult = {
22
+ id: string;
23
+ name?: string | null | undefined;
24
+ fileName: string;
25
+ createdAt: string;
26
+ updatedAt: string;
27
+ };
28
+ export type WorkflowJobResult = WorkflowRunByIdWithJobsQuery['workflowRuns']['byId']['jobs'][number] | WorkflowJobByIdQuery['workflowJobs']['byId'];
29
+ export type WorkflowRunWithJobsResult = WorkflowRunResult & {
30
+ jobs: WorkflowJobResult[];
31
+ logs?: string;
32
+ };
33
+ export type WorkflowLogLine = {
34
+ time: string;
35
+ msg: string;
36
+ result?: string;
37
+ marker?: string;
38
+ };
39
+ export type WorkflowLogs = Map<string, WorkflowLogLine[]>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkflowTriggerType = void 0;
4
+ /*
5
+ * Utility types for workflow commands
6
+ */
7
+ var WorkflowTriggerType;
8
+ (function (WorkflowTriggerType) {
9
+ WorkflowTriggerType["MANUAL"] = "Manual";
10
+ WorkflowTriggerType["GITHUB"] = "GitHub";
11
+ WorkflowTriggerType["SCHEDULED"] = "Scheduled";
12
+ WorkflowTriggerType["OTHER"] = "Other";
13
+ })(WorkflowTriggerType || (exports.WorkflowTriggerType = WorkflowTriggerType = {}));
@@ -0,0 +1,12 @@
1
+ import { WorkflowJobResult, WorkflowLogs, WorkflowRunResult, WorkflowTriggerType } from './types';
2
+ import { WorkflowRunFragment } from '../../graphql/generated';
3
+ import { Choice } from '../../prompts';
4
+ export declare function computeTriggerInfoForWorkflowRun(run: WorkflowRunFragment): {
5
+ triggerType: WorkflowTriggerType;
6
+ trigger: string | null;
7
+ };
8
+ export declare function choiceFromWorkflowRun(run: WorkflowRunResult): Choice;
9
+ export declare function choiceFromWorkflowJob(job: WorkflowJobResult, index: number): Choice;
10
+ export declare function choicesFromWorkflowLogs(logs: WorkflowLogs): Choice[];
11
+ export declare function processWorkflowRuns(runs: WorkflowRunFragment[]): WorkflowRunResult[];
12
+ export declare function processLogsFromJobAsync(job: WorkflowJobResult): Promise<WorkflowLogs | null>;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processLogsFromJobAsync = exports.processWorkflowRuns = exports.choicesFromWorkflowLogs = exports.choiceFromWorkflowJob = exports.choiceFromWorkflowRun = exports.computeTriggerInfoForWorkflowRun = void 0;
4
+ const fetchLogs_1 = require("./fetchLogs");
5
+ const types_1 = require("./types");
6
+ const generated_1 = require("../../graphql/generated");
7
+ function computeTriggerInfoForWorkflowRun(run) {
8
+ let triggerType = types_1.WorkflowTriggerType.OTHER;
9
+ let trigger = '';
10
+ if (run.actor?.__typename === 'Robot') {
11
+ if (run.actor.firstName?.startsWith('GitHub App · ')) {
12
+ trigger = `${run.requestedGitRef ?? ''}@${run.gitCommitHash?.substring(0, 12) ?? ''}`;
13
+ }
14
+ }
15
+ else if (run.actor?.__typename === 'User') {
16
+ trigger = run.actor.username;
17
+ }
18
+ switch (run.triggerEventType) {
19
+ case generated_1.WorkflowRunTriggerEventType.Manual:
20
+ triggerType = types_1.WorkflowTriggerType.MANUAL;
21
+ break;
22
+ case generated_1.WorkflowRunTriggerEventType.GithubPullRequestLabeled:
23
+ case generated_1.WorkflowRunTriggerEventType.GithubPullRequestOpened:
24
+ case generated_1.WorkflowRunTriggerEventType.GithubPullRequestReopened:
25
+ case generated_1.WorkflowRunTriggerEventType.GithubPullRequestSynchronize:
26
+ case generated_1.WorkflowRunTriggerEventType.GithubPush:
27
+ triggerType = types_1.WorkflowTriggerType.GITHUB;
28
+ break;
29
+ case generated_1.WorkflowRunTriggerEventType.Schedule:
30
+ triggerType = types_1.WorkflowTriggerType.SCHEDULED;
31
+ trigger = run.triggeringSchedule ?? '';
32
+ break;
33
+ }
34
+ return { triggerType, trigger };
35
+ }
36
+ exports.computeTriggerInfoForWorkflowRun = computeTriggerInfoForWorkflowRun;
37
+ function choiceFromWorkflowRun(run) {
38
+ const titleArray = [
39
+ run.workflowFileName,
40
+ run.status,
41
+ run.startedAt,
42
+ run.triggerType,
43
+ run.trigger,
44
+ ];
45
+ return {
46
+ title: titleArray.join(' - '),
47
+ value: run.id,
48
+ description: `ID: ${run.id}, Message: ${run.gitCommitMessage?.split('\n')[0] ?? ''}`,
49
+ };
50
+ }
51
+ exports.choiceFromWorkflowRun = choiceFromWorkflowRun;
52
+ function choiceFromWorkflowJob(job, index) {
53
+ return {
54
+ title: `${job.name} - ${job.status}`,
55
+ value: index,
56
+ description: `ID: ${job.id}`,
57
+ };
58
+ }
59
+ exports.choiceFromWorkflowJob = choiceFromWorkflowJob;
60
+ function choicesFromWorkflowLogs(logs) {
61
+ return Array.from(logs.keys()).map(step => {
62
+ const logLines = logs.get(step);
63
+ const stepStatus = logLines?.filter((line) => line.marker === 'end-step')[0]?.result ?? '';
64
+ return {
65
+ title: `${step} - ${stepStatus}`,
66
+ value: step,
67
+ };
68
+ });
69
+ }
70
+ exports.choicesFromWorkflowLogs = choicesFromWorkflowLogs;
71
+ function processWorkflowRuns(runs) {
72
+ return runs.map(run => {
73
+ const finishedAt = run.status === generated_1.WorkflowRunStatus.InProgress ? null : run.updatedAt;
74
+ const { triggerType, trigger } = computeTriggerInfoForWorkflowRun(run);
75
+ return {
76
+ id: run.id,
77
+ status: run.status,
78
+ gitCommitMessage: run.gitCommitMessage?.split('\n')[0] ?? null,
79
+ gitCommitHash: run.gitCommitHash ?? null,
80
+ startedAt: run.createdAt,
81
+ finishedAt,
82
+ triggerType,
83
+ trigger,
84
+ workflowId: run.workflow.id,
85
+ workflowName: run.workflow.name ?? null,
86
+ workflowFileName: run.workflow.fileName,
87
+ };
88
+ });
89
+ }
90
+ exports.processWorkflowRuns = processWorkflowRuns;
91
+ async function processLogsFromJobAsync(job) {
92
+ const rawLogs = await (0, fetchLogs_1.fetchRawLogsForJobAsync)(job);
93
+ if (!rawLogs) {
94
+ return null;
95
+ }
96
+ const logs = new Map();
97
+ const logKeys = new Set();
98
+ rawLogs.split('\n').forEach(line => {
99
+ try {
100
+ const parsedLine = JSON.parse(line);
101
+ const { result, marker } = parsedLine;
102
+ const { buildStepDisplayName, buildStepInternalId, time, msg } = parsedLine;
103
+ const stepId = buildStepDisplayName ?? buildStepInternalId;
104
+ if (stepId) {
105
+ if (!logKeys.has(stepId)) {
106
+ logKeys.add(stepId);
107
+ logs.set(stepId, []);
108
+ }
109
+ logs.get(stepId)?.push({ time, msg, result, marker });
110
+ }
111
+ }
112
+ catch { }
113
+ });
114
+ return logs;
115
+ }
116
+ exports.processLogsFromJobAsync = processLogsFromJobAsync;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
5
5
  const flags_1 = require("../../commandUtils/flags");
6
- const workflows_1 = require("../../commandUtils/workflows");
6
+ const utils_1 = require("../../commandUtils/workflow/utils");
7
7
  const generated_1 = require("../../graphql/generated");
8
8
  const WorkflowRunMutation_1 = require("../../graphql/mutations/WorkflowRunMutation");
9
9
  const AppQuery_1 = require("../../graphql/queries/AppQuery");
@@ -44,7 +44,7 @@ class WorkflowRunCancel extends EasCommand_1.default {
44
44
  }
45
45
  // Run the workflow run list query and select runs to cancel
46
46
  const queryResult = await AppQuery_1.AppQuery.byIdWorkflowRunsFilteredByStatusAsync(graphqlClient, projectId, generated_1.WorkflowRunStatus.InProgress, 50);
47
- const runs = (0, workflows_1.processWorkflowRuns)(queryResult);
47
+ const runs = (0, utils_1.processWorkflowRuns)(queryResult);
48
48
  if (runs.length === 0) {
49
49
  log_1.default.warn('No workflow runs to cancel');
50
50
  return;
@@ -53,10 +53,7 @@ class WorkflowRunCancel extends EasCommand_1.default {
53
53
  type: 'multiselect',
54
54
  name: 'selectedRuns',
55
55
  message: 'Select IN_PROGRESS workflow runs to cancel',
56
- choices: runs.map(run => ({
57
- title: `${run.id} - ${run.workflowFileName}, ${run.gitCommitMessage ?? ''}, ${run.startedAt}`,
58
- value: run.id,
59
- })),
56
+ choices: runs.map(run => (0, utils_1.choiceFromWorkflowRun)(run)),
60
57
  });
61
58
  answers.selectedRuns.forEach((id) => {
62
59
  workflowRunIds.add(id);
@@ -0,0 +1,18 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ export default class WorkflowLogView extends EasCommand {
3
+ static description: string;
4
+ static flags: {
5
+ 'all-steps': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ static args: {
10
+ name: string;
11
+ description: string;
12
+ }[];
13
+ static contextDefinition: {
14
+ loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
15
+ projectId: import("../../commandUtils/context/ProjectIdContextField").ProjectIdContextField;
16
+ };
17
+ runAsync(): Promise<void>;
18
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
6
+ const flags_1 = require("../../commandUtils/flags");
7
+ const stateMachine_1 = require("../../commandUtils/workflow/stateMachine");
8
+ const log_1 = tslib_1.__importDefault(require("../../log"));
9
+ const json_1 = require("../../utils/json");
10
+ function printLogsForAllSteps(logs) {
11
+ [...logs.keys()].forEach(step => {
12
+ const logLines = logs.get(step);
13
+ if (logLines) {
14
+ log_1.default.log(`Step: ${step}`);
15
+ logLines.forEach(line => {
16
+ log_1.default.log(` ${line.time} ${line.msg}`);
17
+ });
18
+ }
19
+ log_1.default.addNewLineIfNone();
20
+ });
21
+ }
22
+ class WorkflowLogView extends EasCommand_1.default {
23
+ static description = 'view logs for a workflow run, selecting a job and step to view. You can pass in either a workflow run ID or a job ID. If no ID is passed in, you will be prompted to select from recent workflow runs for the current project.';
24
+ static flags = {
25
+ ...flags_1.EasJsonOnlyFlag,
26
+ ...flags_1.EASNonInteractiveFlag,
27
+ 'all-steps': core_1.Flags.boolean({
28
+ description: 'Print all logs, rather than prompting for a specific step. This will be automatically set when in non-interactive mode.',
29
+ default: false,
30
+ }),
31
+ };
32
+ static args = [
33
+ { name: 'id', description: 'ID of the workflow run or workflow job to view logs for' },
34
+ ];
35
+ static contextDefinition = {
36
+ ...this.ContextOptions.ProjectId,
37
+ ...this.ContextOptions.LoggedIn,
38
+ };
39
+ async runAsync() {
40
+ const { args, flags } = await this.parse(WorkflowLogView);
41
+ const nonInteractive = flags['non-interactive'];
42
+ const allSteps = nonInteractive ? true : flags['all-steps'];
43
+ log_1.default.debug(`allSteps = ${allSteps}`);
44
+ log_1.default.debug(`nonInteractive = ${nonInteractive}`);
45
+ log_1.default.debug(`flags.json = ${flags.json}`);
46
+ log_1.default.debug(`args.id = ${args.id}`);
47
+ const { loggedIn: { graphqlClient }, projectId, } = await this.getContextAsync(WorkflowLogView, {
48
+ nonInteractive,
49
+ });
50
+ if (flags.json) {
51
+ (0, json_1.enableJsonOutput)();
52
+ }
53
+ const finalSelectionState = await (0, stateMachine_1.executeWorkflowSelectionActionsAsync)({
54
+ graphqlClient,
55
+ projectId,
56
+ nonInteractive,
57
+ allSteps,
58
+ state: stateMachine_1.WorkflowCommandSelectionStateValue.WORKFLOW_JOB_SELECTION,
59
+ jobId: args.id,
60
+ });
61
+ if (finalSelectionState.state === stateMachine_1.WorkflowCommandSelectionStateValue.ERROR) {
62
+ log_1.default.error(finalSelectionState.message);
63
+ return;
64
+ }
65
+ const logs = finalSelectionState?.logs;
66
+ if (allSteps) {
67
+ if (logs) {
68
+ if (flags.json) {
69
+ (0, json_1.printJsonOnlyOutput)(Object.fromEntries(logs));
70
+ }
71
+ else {
72
+ printLogsForAllSteps(logs);
73
+ }
74
+ }
75
+ }
76
+ else {
77
+ const selectedStep = finalSelectionState?.step;
78
+ const logLines = logs?.get(selectedStep);
79
+ if (logLines) {
80
+ if (flags.json) {
81
+ const output = {};
82
+ output[selectedStep] = logLines ?? null;
83
+ (0, json_1.printJsonOnlyOutput)(output);
84
+ }
85
+ else {
86
+ logLines.forEach(line => {
87
+ log_1.default.log(` ${line.time} ${line.msg}`);
88
+ });
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ exports.default = WorkflowLogView;