eas-cli 16.21.0 → 16.22.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.
- package/README.md +87 -87
- package/build/commandUtils/workflow/buildProfileUtils.d.ts +36 -0
- package/build/commandUtils/workflow/buildProfileUtils.js +210 -0
- package/build/commandUtils/workflow/creation.d.ts +20 -0
- package/build/commandUtils/workflow/creation.js +462 -0
- package/build/commandUtils/workflow/validation.d.ts +4 -0
- package/build/commandUtils/workflow/validation.js +8 -4
- package/build/commands/workflow/create.d.ts +4 -3
- package/build/commands/workflow/create.js +130 -56
- package/build/graphql/generated.d.ts +30 -0
- package/build/graphql/types/Workflow.js +11 -0
- package/oclif.manifest.json +8 -5
- package/package.json +2 -2
|
@@ -2,28 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkflowCreate = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const core_1 = require("@oclif/core");
|
|
5
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
7
|
const promises_1 = tslib_1.__importDefault(require("fs/promises"));
|
|
7
8
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
8
9
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
9
|
-
const prompts_1 = tslib_1.__importDefault(require("prompts"));
|
|
10
10
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
11
|
-
const
|
|
11
|
+
const buildProfileUtils_1 = require("../../commandUtils/workflow/buildProfileUtils");
|
|
12
|
+
const creation_1 = require("../../commandUtils/workflow/creation");
|
|
13
|
+
const validation_1 = require("../../commandUtils/workflow/validation");
|
|
12
14
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
15
|
+
const prompts_1 = require("../../prompts");
|
|
16
|
+
const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
|
|
13
17
|
const workflowFile_1 = require("../../utils/workflowFile");
|
|
14
|
-
const DEFAULT_WORKFLOW_NAME = 'workflow.yml';
|
|
15
|
-
const HELLO_WORLD_TEMPLATE = `name: Hello World
|
|
16
|
-
|
|
17
|
-
on:
|
|
18
|
-
push:
|
|
19
|
-
branches: ['*']
|
|
20
|
-
|
|
21
|
-
jobs:
|
|
22
|
-
hello_world:
|
|
23
|
-
steps:
|
|
24
|
-
- uses: eas/checkout
|
|
25
|
-
- run: echo "Hello, World"
|
|
26
|
-
`;
|
|
27
18
|
class WorkflowCreate extends EasCommand_1.default {
|
|
28
19
|
static description = 'create a new workflow configuration YAML file';
|
|
29
20
|
static args = [
|
|
@@ -34,65 +25,148 @@ class WorkflowCreate extends EasCommand_1.default {
|
|
|
34
25
|
},
|
|
35
26
|
];
|
|
36
27
|
static flags = {
|
|
37
|
-
|
|
28
|
+
'skip-validation': core_1.Flags.boolean({
|
|
29
|
+
description: 'If set, the workflow file will not be validated before being created',
|
|
30
|
+
default: false,
|
|
31
|
+
}),
|
|
38
32
|
};
|
|
39
33
|
static contextDefinition = {
|
|
34
|
+
...this.ContextOptions.DynamicProjectConfig,
|
|
40
35
|
...this.ContextOptions.ProjectDir,
|
|
36
|
+
...this.ContextOptions.LoggedIn,
|
|
41
37
|
};
|
|
42
38
|
async runAsync() {
|
|
43
39
|
const { args: { name: argFileName }, flags, } = await this.parse(WorkflowCreate);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
40
|
+
try {
|
|
41
|
+
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, projectDir, } = await this.getContextAsync(WorkflowCreate, {
|
|
42
|
+
nonInteractive: false,
|
|
43
|
+
withServerSideEnvironment: null,
|
|
44
|
+
});
|
|
45
|
+
const { exp: originalExpoConfig, projectId } = await getDynamicPrivateProjectConfigAsync();
|
|
46
|
+
let expoConfig = originalExpoConfig;
|
|
47
|
+
let workflowStarter;
|
|
48
|
+
while (!workflowStarter) {
|
|
49
|
+
workflowStarter = await chooseTemplateAsync();
|
|
50
|
+
switch (workflowStarter.name) {
|
|
51
|
+
case creation_1.WorkflowStarterName.BUILD:
|
|
52
|
+
case creation_1.WorkflowStarterName.DEPLOY:
|
|
53
|
+
case creation_1.WorkflowStarterName.UPDATE: {
|
|
54
|
+
const shouldProceed = await (0, buildProfileUtils_1.runBuildConfigureIfNeededAsync)({
|
|
55
|
+
projectDir,
|
|
56
|
+
expoConfig,
|
|
57
|
+
});
|
|
58
|
+
if (!shouldProceed) {
|
|
59
|
+
workflowStarter = undefined;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
58
63
|
}
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
default:
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
switch (workflowStarter.name) {
|
|
68
|
+
case creation_1.WorkflowStarterName.DEPLOY:
|
|
69
|
+
case creation_1.WorkflowStarterName.UPDATE: {
|
|
70
|
+
const shouldProceed = await (0, buildProfileUtils_1.runUpdateConfigureIfNeededAsync)({
|
|
71
|
+
projectDir,
|
|
72
|
+
expoConfig,
|
|
73
|
+
});
|
|
74
|
+
if (!shouldProceed) {
|
|
75
|
+
workflowStarter = undefined;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Need to refetch the Expo config because it may have changed
|
|
79
|
+
expoConfig = (await getDynamicPrivateProjectConfigAsync()).exp;
|
|
80
|
+
break;
|
|
61
81
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
default:
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const { fileName, filePath } = await chooseFileNameAsync(argFileName, projectDir, workflowStarter);
|
|
87
|
+
// Customize the template if needed
|
|
88
|
+
workflowStarter = await (0, creation_1.customizeTemplateIfNeededAsync)(workflowStarter, projectDir, expoConfig);
|
|
89
|
+
log_1.default.debug(`Creating workflow file ${fileName} from template ${workflowStarter.name}`);
|
|
90
|
+
const yamlString = [
|
|
91
|
+
workflowStarter.header,
|
|
92
|
+
(0, validation_1.workflowContentsFromParsedYaml)(workflowStarter.template),
|
|
93
|
+
].join('\n');
|
|
94
|
+
if (!flags['skip-validation']) {
|
|
95
|
+
await (0, validation_1.validateWorkflowFileAsync)({ yamlConfig: yamlString, filePath: fileName }, projectDir, graphqlClient, projectId);
|
|
96
|
+
}
|
|
97
|
+
await ensureWorkflowsDirectoryExistsAsync({ projectDir });
|
|
98
|
+
filePath && (await promises_1.default.writeFile(filePath, yamlString));
|
|
99
|
+
log_1.default.withTick(`Created ${chalk_1.default.bold(filePath)}`);
|
|
100
|
+
log_1.default.addNewLineIfNone();
|
|
101
|
+
log_1.default.log((0, creation_1.howToRunWorkflow)(fileName, workflowStarter));
|
|
102
|
+
// Next steps
|
|
103
|
+
if (workflowStarter.nextSteps && workflowStarter.nextSteps.length > 0) {
|
|
104
|
+
log_1.default.addNewLineIfNone();
|
|
105
|
+
log_1.default.log('Next steps:');
|
|
106
|
+
log_1.default.addNewLineIfNone();
|
|
107
|
+
log_1.default.log((0, formatFields_1.default)(workflowStarter.nextSteps.map((step, index) => ({
|
|
108
|
+
label: `${index + 1}.`,
|
|
109
|
+
value: step,
|
|
110
|
+
}))));
|
|
67
111
|
}
|
|
68
|
-
fileName = response.fileName;
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
await this.ensureWorkflowsDirectoryExistsAsync({ projectDir });
|
|
72
|
-
await this.createWorkflowFileAsync({ fileName, projectDir });
|
|
73
112
|
}
|
|
74
113
|
catch (error) {
|
|
114
|
+
(0, validation_1.logWorkflowValidationErrors)(error);
|
|
75
115
|
log_1.default.error('Failed to create workflow file.');
|
|
76
|
-
throw error;
|
|
77
116
|
}
|
|
78
117
|
}
|
|
79
|
-
|
|
118
|
+
}
|
|
119
|
+
exports.WorkflowCreate = WorkflowCreate;
|
|
120
|
+
async function ensureWorkflowsDirectoryExistsAsync({ projectDir, }) {
|
|
121
|
+
try {
|
|
122
|
+
await promises_1.default.access(path_1.default.join(projectDir, '.eas', 'workflows'));
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
await promises_1.default.mkdir(path_1.default.join(projectDir, '.eas', 'workflows'), { recursive: true });
|
|
126
|
+
log_1.default.withTick(`Created directory ${chalk_1.default.bold(path_1.default.join(projectDir, '.eas', 'workflows'))}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function chooseTemplateAsync() {
|
|
130
|
+
const workflowStarter = (await (0, prompts_1.promptAsync)({
|
|
131
|
+
type: 'select',
|
|
132
|
+
name: 'starter',
|
|
133
|
+
message: 'Select a workflow template:',
|
|
134
|
+
choices: creation_1.workflowStarters.map(starter => ({
|
|
135
|
+
title: starter.displayName,
|
|
136
|
+
value: starter,
|
|
137
|
+
})),
|
|
138
|
+
})).starter;
|
|
139
|
+
return workflowStarter;
|
|
140
|
+
}
|
|
141
|
+
async function chooseFileNameAsync(initialValue, projectDir, workflowStarter) {
|
|
142
|
+
let fileName = initialValue;
|
|
143
|
+
let filePath = '';
|
|
144
|
+
while ((fileName?.length ?? 0) === 0) {
|
|
145
|
+
fileName = (await (0, prompts_1.promptAsync)({
|
|
146
|
+
type: 'text',
|
|
147
|
+
name: 'fileName',
|
|
148
|
+
message: 'What would you like to name your workflow file?',
|
|
149
|
+
initial: workflowStarter.defaultFileName,
|
|
150
|
+
})).fileName;
|
|
151
|
+
if (!fileName) {
|
|
152
|
+
fileName = undefined;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
80
155
|
try {
|
|
81
|
-
|
|
156
|
+
workflowFile_1.WorkflowFile.validateYamlExtension(fileName);
|
|
82
157
|
}
|
|
83
|
-
catch {
|
|
84
|
-
|
|
85
|
-
|
|
158
|
+
catch (error) {
|
|
159
|
+
log_1.default.error(error instanceof Error ? error.message : 'Invalid YAML file name extension');
|
|
160
|
+
fileName = undefined;
|
|
161
|
+
continue;
|
|
86
162
|
}
|
|
87
|
-
|
|
88
|
-
async createWorkflowFileAsync({ fileName, projectDir, }) {
|
|
89
|
-
workflowFile_1.WorkflowFile.validateYamlExtension(fileName);
|
|
90
|
-
const filePath = path_1.default.join(projectDir, '.eas', 'workflows', fileName);
|
|
163
|
+
filePath = path_1.default.join(projectDir, '.eas', 'workflows', fileName);
|
|
91
164
|
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
92
|
-
|
|
165
|
+
log_1.default.error(`Workflow file already exists: ${filePath}`);
|
|
166
|
+
log_1.default.error('Please choose a different file name.');
|
|
167
|
+
log_1.default.newLine();
|
|
168
|
+
fileName = undefined;
|
|
93
169
|
}
|
|
94
|
-
await promises_1.default.writeFile(filePath, HELLO_WORLD_TEMPLATE);
|
|
95
|
-
log_1.default.withTick(`Created ${chalk_1.default.bold(filePath)}`);
|
|
96
170
|
}
|
|
171
|
+
return { fileName: fileName ?? '', filePath };
|
|
97
172
|
}
|
|
98
|
-
exports.WorkflowCreate = WorkflowCreate;
|
|
@@ -166,6 +166,7 @@ export type Account = {
|
|
|
166
166
|
displayName?: Maybe<Scalars['String']['output']>;
|
|
167
167
|
/** Environment secrets for an account */
|
|
168
168
|
environmentSecrets: Array<EnvironmentSecret>;
|
|
169
|
+
environmentVariableEnvironments: Array<Scalars['EnvironmentVariableEnvironment']['output']>;
|
|
169
170
|
/** Environment variables for an account */
|
|
170
171
|
environmentVariables: Array<EnvironmentVariable>;
|
|
171
172
|
/** Environment variables for an account with decrypted secret values */
|
|
@@ -1139,6 +1140,7 @@ export type App = Project & {
|
|
|
1139
1140
|
devDomainName?: Maybe<AppDevDomainName>;
|
|
1140
1141
|
/** Environment secrets for an app */
|
|
1141
1142
|
environmentSecrets: Array<EnvironmentSecret>;
|
|
1143
|
+
environmentVariableEnvironments: Array<Scalars['EnvironmentVariableEnvironment']['output']>;
|
|
1142
1144
|
/** Environment variables for an app */
|
|
1143
1145
|
environmentVariables: Array<EnvironmentVariable>;
|
|
1144
1146
|
/** Environment variables for an app with decrypted secret values */
|
|
@@ -12704,6 +12706,20 @@ export type AppByIdWorkflowsQuery = {
|
|
|
12704
12706
|
fileName: string;
|
|
12705
12707
|
createdAt: any;
|
|
12706
12708
|
updatedAt: any;
|
|
12709
|
+
revisionsPaginated: {
|
|
12710
|
+
__typename?: 'WorkflowRevisionsConnection';
|
|
12711
|
+
edges: Array<{
|
|
12712
|
+
__typename?: 'WorkflowRevisionEdge';
|
|
12713
|
+
node: {
|
|
12714
|
+
__typename?: 'WorkflowRevision';
|
|
12715
|
+
id: string;
|
|
12716
|
+
blobSha: string;
|
|
12717
|
+
commitSha?: string | null;
|
|
12718
|
+
createdAt: any;
|
|
12719
|
+
yamlConfig: string;
|
|
12720
|
+
};
|
|
12721
|
+
}>;
|
|
12722
|
+
};
|
|
12707
12723
|
}>;
|
|
12708
12724
|
};
|
|
12709
12725
|
};
|
|
@@ -15670,6 +15686,20 @@ export type WorkflowFragment = {
|
|
|
15670
15686
|
fileName: string;
|
|
15671
15687
|
createdAt: any;
|
|
15672
15688
|
updatedAt: any;
|
|
15689
|
+
revisionsPaginated: {
|
|
15690
|
+
__typename?: 'WorkflowRevisionsConnection';
|
|
15691
|
+
edges: Array<{
|
|
15692
|
+
__typename?: 'WorkflowRevisionEdge';
|
|
15693
|
+
node: {
|
|
15694
|
+
__typename?: 'WorkflowRevision';
|
|
15695
|
+
id: string;
|
|
15696
|
+
blobSha: string;
|
|
15697
|
+
commitSha?: string | null;
|
|
15698
|
+
createdAt: any;
|
|
15699
|
+
yamlConfig: string;
|
|
15700
|
+
};
|
|
15701
|
+
}>;
|
|
15702
|
+
};
|
|
15673
15703
|
};
|
|
15674
15704
|
export type WorkflowJobFragment = {
|
|
15675
15705
|
__typename?: 'WorkflowJob';
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "16.
|
|
2
|
+
"version": "16.22.0",
|
|
3
3
|
"commands": {
|
|
4
4
|
"analytics": {
|
|
5
5
|
"id": "analytics",
|
|
@@ -4153,10 +4153,10 @@
|
|
|
4153
4153
|
"pluginType": "core",
|
|
4154
4154
|
"aliases": [],
|
|
4155
4155
|
"flags": {
|
|
4156
|
-
"
|
|
4157
|
-
"name": "
|
|
4156
|
+
"skip-validation": {
|
|
4157
|
+
"name": "skip-validation",
|
|
4158
4158
|
"type": "boolean",
|
|
4159
|
-
"description": "
|
|
4159
|
+
"description": "If set, the workflow file will not be validated before being created",
|
|
4160
4160
|
"allowNo": false
|
|
4161
4161
|
}
|
|
4162
4162
|
},
|
|
@@ -4168,7 +4168,10 @@
|
|
|
4168
4168
|
}
|
|
4169
4169
|
},
|
|
4170
4170
|
"contextDefinition": {
|
|
4171
|
-
"
|
|
4171
|
+
"getDynamicPublicProjectConfigAsync": {},
|
|
4172
|
+
"getDynamicPrivateProjectConfigAsync": {},
|
|
4173
|
+
"projectDir": {},
|
|
4174
|
+
"loggedIn": {}
|
|
4172
4175
|
}
|
|
4173
4176
|
},
|
|
4174
4177
|
"workflow:list": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eas-cli",
|
|
3
3
|
"description": "EAS command line tool",
|
|
4
|
-
"version": "16.
|
|
4
|
+
"version": "16.22.0",
|
|
5
5
|
"author": "Expo <support@expo.dev>",
|
|
6
6
|
"bin": {
|
|
7
7
|
"eas": "./bin/run"
|
|
@@ -241,5 +241,5 @@
|
|
|
241
241
|
"node": "20.11.0",
|
|
242
242
|
"yarn": "1.22.21"
|
|
243
243
|
},
|
|
244
|
-
"gitHead": "
|
|
244
|
+
"gitHead": "72cff1df1a5db334d2b12461532f483a7a35e2fa"
|
|
245
245
|
}
|