eas-cli 16.21.0 → 16.23.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 (56) hide show
  1. package/README.md +210 -209
  2. package/build/build/android/graphql.js +1 -2
  3. package/build/build/evaluateConfigWithEnvVarsAsync.js +5 -11
  4. package/build/build/ios/graphql.js +1 -2
  5. package/build/build/utils/environment.d.ts +1 -4
  6. package/build/build/utils/environment.js +7 -24
  7. package/build/commandUtils/EasCommand.d.ts +1 -2
  8. package/build/commandUtils/context/ContextField.d.ts +1 -2
  9. package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.d.ts +1 -2
  10. package/build/commandUtils/context/contextUtils/loadServerSideEnvironmentVariablesAsync.js +3 -8
  11. package/build/commandUtils/flags.d.ts +3 -5
  12. package/build/commandUtils/flags.js +8 -22
  13. package/build/commandUtils/workflow/buildProfileUtils.d.ts +36 -0
  14. package/build/commandUtils/workflow/buildProfileUtils.js +210 -0
  15. package/build/commandUtils/workflow/creation.d.ts +20 -0
  16. package/build/commandUtils/workflow/creation.js +462 -0
  17. package/build/commandUtils/workflow/validation.d.ts +4 -0
  18. package/build/commandUtils/workflow/validation.js +8 -4
  19. package/build/commands/build/resign.d.ts +2 -3
  20. package/build/commands/deploy/index.d.ts +1 -2
  21. package/build/commands/env/create.d.ts +1 -2
  22. package/build/commands/env/create.js +12 -14
  23. package/build/commands/env/delete.d.ts +1 -2
  24. package/build/commands/env/delete.js +2 -6
  25. package/build/commands/env/exec.js +6 -7
  26. package/build/commands/env/get.d.ts +1 -2
  27. package/build/commands/env/get.js +4 -6
  28. package/build/commands/env/list.d.ts +1 -2
  29. package/build/commands/env/list.js +8 -6
  30. package/build/commands/env/pull.d.ts +1 -1
  31. package/build/commands/env/pull.js +8 -8
  32. package/build/commands/env/push.d.ts +6 -4
  33. package/build/commands/env/push.js +42 -30
  34. package/build/commands/env/update.d.ts +2 -3
  35. package/build/commands/env/update.js +7 -8
  36. package/build/commands/fingerprint/compare.d.ts +1 -2
  37. package/build/commands/fingerprint/compare.js +1 -1
  38. package/build/commands/fingerprint/generate.d.ts +1 -2
  39. package/build/commands/fingerprint/generate.js +1 -1
  40. package/build/commands/update/configure.d.ts +1 -1
  41. package/build/commands/update/configure.js +1 -1
  42. package/build/commands/update/index.d.ts +1 -2
  43. package/build/commands/update/index.js +1 -1
  44. package/build/commands/workflow/create.d.ts +4 -3
  45. package/build/commands/workflow/create.js +130 -56
  46. package/build/graphql/generated.d.ts +44 -0
  47. package/build/graphql/queries/EnvironmentVariablesQuery.d.ts +6 -6
  48. package/build/graphql/queries/EnvironmentVariablesQuery.js +15 -0
  49. package/build/graphql/types/Workflow.js +11 -0
  50. package/build/utils/prompts.d.ts +8 -5
  51. package/build/utils/prompts.js +69 -10
  52. package/build/utils/variableUtils.d.ts +1 -3
  53. package/build/utils/variableUtils.js +1 -6
  54. package/build/worker/assets.d.ts +1 -2
  55. package/oclif.manifest.json +43 -114
  56. package/package.json +4 -4
@@ -0,0 +1,462 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.customizeTemplateIfNeededAsync = exports.ensureProductionBuildProfileExistsAsync = exports.addBuildJobsToDevelopmentBuildTemplateAsync = exports.workflowStarters = exports.howToRunWorkflow = exports.WorkflowStarterName = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const eas_build_job_1 = require("@expo/eas-build-job");
6
+ const buildProfileUtils_1 = require("./buildProfileUtils");
7
+ const log_1 = tslib_1.__importStar(require("../../log"));
8
+ const prompts_1 = require("../../prompts");
9
+ const easCli_1 = require("../../utils/easCli");
10
+ var WorkflowStarterName;
11
+ (function (WorkflowStarterName) {
12
+ WorkflowStarterName["BUILD"] = "build";
13
+ WorkflowStarterName["UPDATE"] = "update";
14
+ WorkflowStarterName["CUSTOM"] = "custom";
15
+ WorkflowStarterName["DEPLOY"] = "deploy";
16
+ })(WorkflowStarterName || (exports.WorkflowStarterName = WorkflowStarterName = {}));
17
+ const createdByEASCLI = `# Created by EAS CLI v${easCli_1.easCliVersion}`;
18
+ const CUSTOM_TEMPLATE = {
19
+ name: 'Custom workflow',
20
+ on: {
21
+ push: {
22
+ branches: ['main'],
23
+ },
24
+ },
25
+ jobs: {
26
+ custom_build: {
27
+ name: 'Custom job',
28
+ steps: [
29
+ {
30
+ uses: 'eas/checkout',
31
+ },
32
+ {
33
+ name: 'Hello World',
34
+ id: 'hello_world',
35
+ run: '# Custom script\necho "Hello, World"\n',
36
+ },
37
+ ],
38
+ },
39
+ },
40
+ };
41
+ const CUSTOM_TEMPLATE_HEADER = `
42
+ # Custom job
43
+ #
44
+ # This workflow shows how to write custom jobs.
45
+ # It contains a predefined workflow step and a shell command to print "Hello, World!".
46
+ #
47
+ # Key features:
48
+ # - Triggers on pushes to the main branch.
49
+ # (Requires linked GitHub account: https://expo.dev/accounts/[account]/settings/github)
50
+ # - Can be triggered manually with eas workflow:run custom.yml
51
+ # - Runs eas/checkout then a custom "echo" command
52
+ #
53
+ # For detailed documentation on workflow syntax and available step types, visit:
54
+ # https://docs.expo.dev/eas/workflows/syntax/#jobsjob_idstepsstepuses
55
+ #
56
+ ${createdByEASCLI}
57
+ #
58
+ `;
59
+ const BUILD_TEMPLATE = {
60
+ name: 'Create development builds',
61
+ on: {
62
+ push: {
63
+ branches: ['main'],
64
+ },
65
+ },
66
+ jobs: {},
67
+ };
68
+ const BUILD_TEMPLATE_HEADER = `
69
+ # Create development builds
70
+ #
71
+ # This workflow shows how to create development builds.
72
+ #
73
+ # Key features:
74
+ # - Can be triggered manually with eas workflow:run create-development-builds.yml
75
+ # - Runs the pre-packaged build job to create Android and iOS development builds
76
+ # for Android emulators, Android and iOS devices, and iOS simulators
77
+ #
78
+ # For a detailed guide on using this workflow, visit:
79
+ # https://docs.expo.dev/develop/development-builds/introduction/
80
+ #
81
+ ${createdByEASCLI}
82
+ #
83
+ `;
84
+ const PUBLISH_UPDATE_TEMPLATE = {
85
+ name: 'Publish preview update',
86
+ on: {
87
+ push: {
88
+ branches: ['*'],
89
+ },
90
+ },
91
+ jobs: {
92
+ publish_preview_update: {
93
+ name: 'Publish preview update',
94
+ type: 'update',
95
+ params: {
96
+ branch: '${{ github.ref_name || "test" }}',
97
+ },
98
+ },
99
+ },
100
+ };
101
+ const PUBLISH_UPDATE_TEMPLATE_HEADER = `
102
+ # Publish preview update
103
+ #
104
+ # This workflow shows how to publish preview updates.
105
+ # Learn more: https://docs.expo.dev/review/share-previews-with-your-team/
106
+ #
107
+ # Key features:
108
+ # - Triggers on pushes to all branches
109
+ # (Requires linked GitHub account: https://expo.dev/accounts/[account]/settings/github)
110
+ # - Can be triggered manually with eas workflow:run publish-preview-update.yml
111
+ # - Runs the pre-packaged update job
112
+ #
113
+ # For a detailed guide on using this workflow, visit:
114
+ # https://docs.expo.dev/eas/workflows/examples/publish-preview-update/
115
+ #
116
+ ${createdByEASCLI}
117
+ #
118
+ `;
119
+ const DEPLOY_TEMPLATE = {
120
+ name: 'Deploy to production',
121
+ on: {
122
+ push: {
123
+ branches: ['main'],
124
+ },
125
+ },
126
+ jobs: {
127
+ fingerprint: {
128
+ name: 'Fingerprint',
129
+ type: 'fingerprint',
130
+ },
131
+ get_android_build: {
132
+ name: 'Check for existing android build',
133
+ needs: ['fingerprint'],
134
+ type: 'get-build',
135
+ params: {
136
+ fingerprint_hash: '${{ needs.fingerprint.outputs.android_fingerprint_hash }}',
137
+ profile: 'production',
138
+ },
139
+ },
140
+ get_ios_build: {
141
+ name: 'Check for existing ios build',
142
+ needs: ['fingerprint'],
143
+ type: 'get-build',
144
+ params: {
145
+ fingerprint_hash: '${{ needs.fingerprint.outputs.ios_fingerprint_hash }}',
146
+ profile: 'production',
147
+ },
148
+ },
149
+ build_android: {
150
+ name: 'Build Android',
151
+ needs: ['get_android_build'],
152
+ if: '${{ !needs.get_android_build.outputs.build_id }}',
153
+ type: 'build',
154
+ params: {
155
+ platform: 'android',
156
+ profile: 'production',
157
+ },
158
+ },
159
+ build_ios: {
160
+ name: 'Build iOS',
161
+ needs: ['get_ios_build'],
162
+ if: '${{ !needs.get_ios_build.outputs.build_id }}',
163
+ type: 'build',
164
+ params: {
165
+ platform: 'ios',
166
+ profile: 'production',
167
+ },
168
+ },
169
+ submit_android_build: {
170
+ name: 'Submit Android Build',
171
+ needs: ['build_android'],
172
+ type: 'submit',
173
+ params: {
174
+ build_id: '${{ needs.build_android.outputs.build_id }}',
175
+ },
176
+ },
177
+ submit_ios_build: {
178
+ name: 'Submit iOS Build',
179
+ needs: ['build_ios'],
180
+ type: 'submit',
181
+ params: {
182
+ build_id: '${{ needs.build_ios.outputs.build_id }}',
183
+ },
184
+ },
185
+ publish_android_update: {
186
+ name: 'Publish Android update',
187
+ needs: ['get_android_build'],
188
+ if: '${{ needs.get_android_build.outputs.build_id }}',
189
+ type: 'update',
190
+ params: {
191
+ branch: 'production',
192
+ platform: 'android',
193
+ },
194
+ },
195
+ publish_ios_update: {
196
+ name: 'Publish iOS update',
197
+ needs: ['get_ios_build'],
198
+ if: '${{ needs.get_ios_build.outputs.build_id }}',
199
+ type: 'update',
200
+ params: {
201
+ branch: 'production',
202
+ platform: 'ios',
203
+ },
204
+ },
205
+ },
206
+ };
207
+ const DEPLOY_TEMPLATE_HEADER = `
208
+ # Deploy to production
209
+ #
210
+ # This workflow shows how to build and submit to app stores.
211
+ #
212
+ # Key features:
213
+ # - Triggers on pushes to "main" (Requires linked GitHub account: https://expo.dev/accounts/[account]/settings/github)
214
+ # - Can be triggered manually with eas workflow:run deploy-to-production.yml
215
+ # - Creates builds and submits them to app stores when native changes are detected, otherwise sends an over-the-air update.
216
+ #
217
+ # For a detailed guide on using this workflow, visit:
218
+ # https://docs.expo.dev/eas/workflows/examples/deploy-to-production/
219
+ `;
220
+ function nextStepForDeviceBuildProfile(buildProfileName) {
221
+ return `A build job in this workflow uses the build profile "${buildProfileName}"
222
+ to build your app for real devices, and may require credentials.
223
+ You can configure your credentials with the command "eas credentials".
224
+ For more information, please see ${(0, log_1.link)('https://docs.expo.dev/app-signing/app-credentials/')}.
225
+ `
226
+ .trim()
227
+ .trimStart();
228
+ }
229
+ function nextStepForAppSubmission() {
230
+ return `This workflow includes a job to submit your app to app stores.
231
+ You will need to configure your App Store/Play Store credentials
232
+ before you can run this workflow.
233
+ Please see ${(0, log_1.link)('https://docs.expo.dev/deploy/submit-to-app-stores/')}.
234
+ `
235
+ .trim()
236
+ .trimStart();
237
+ }
238
+ function howToRunWorkflow(workflowFileName, workflowStarter) {
239
+ const lines = [
240
+ `To run this workflow manually, use the command "eas workflow:run .eas/workflows/${workflowFileName}".`,
241
+ ];
242
+ if (workflowStarter.template?.on?.push?.branches?.length > 0) {
243
+ const branches = workflowStarter.template.on.push.branches;
244
+ if (branches.length === 1 && branches[0] === '*') {
245
+ lines.push('This workflow is also configured to run automatically when code is pushed to any branch.');
246
+ }
247
+ else if (branches.length === 1) {
248
+ lines.push(`This workflow is also configured to run automatically when code is pushed to the "${branches[0]}" branch.`);
249
+ }
250
+ else {
251
+ lines.push(`This workflow is also configured to run automatically when code is pushed to the following branches: ${branches.join(', ')}.`);
252
+ }
253
+ }
254
+ return lines.join('\n');
255
+ }
256
+ exports.howToRunWorkflow = howToRunWorkflow;
257
+ exports.workflowStarters = [
258
+ {
259
+ displayName: 'Custom',
260
+ name: WorkflowStarterName.CUSTOM,
261
+ defaultFileName: 'custom.yml',
262
+ template: CUSTOM_TEMPLATE,
263
+ header: CUSTOM_TEMPLATE_HEADER,
264
+ },
265
+ {
266
+ displayName: 'Create development builds',
267
+ name: WorkflowStarterName.BUILD,
268
+ defaultFileName: 'create-development-builds.yml',
269
+ template: BUILD_TEMPLATE,
270
+ header: BUILD_TEMPLATE_HEADER,
271
+ },
272
+ {
273
+ displayName: 'Publish updates',
274
+ name: WorkflowStarterName.UPDATE,
275
+ defaultFileName: 'publish-updates.yml',
276
+ template: PUBLISH_UPDATE_TEMPLATE,
277
+ header: PUBLISH_UPDATE_TEMPLATE_HEADER,
278
+ },
279
+ {
280
+ displayName: 'Deploy to production',
281
+ name: WorkflowStarterName.DEPLOY,
282
+ defaultFileName: 'deploy-to-production.yml',
283
+ template: DEPLOY_TEMPLATE,
284
+ header: DEPLOY_TEMPLATE_HEADER,
285
+ },
286
+ ];
287
+ async function addBuildJobsToDevelopmentBuildTemplateAsync(projectDir, workflowStarter) {
288
+ const buildProfiles = await (0, buildProfileUtils_1.buildProfilesFromProjectAsync)(projectDir);
289
+ // android_development_build
290
+ const nextSteps = new Set();
291
+ let androidDevelopmentBuildProfileName = null;
292
+ for (const profileName of buildProfiles.keys()) {
293
+ const profile = buildProfiles.get(profileName)?.android;
294
+ if (!profile) {
295
+ continue;
296
+ }
297
+ if ((0, buildProfileUtils_1.isBuildProfileForDevelopment)(profile, eas_build_job_1.Platform.ANDROID)) {
298
+ androidDevelopmentBuildProfileName = profileName;
299
+ break;
300
+ }
301
+ }
302
+ if (!androidDevelopmentBuildProfileName) {
303
+ log_1.default.warn('This workflow requires an Android development build profile in your eas.json, but none were found.');
304
+ const add = await (0, prompts_1.confirmAsync)({
305
+ message: 'Do you want to add an Android development build profile?',
306
+ initial: false,
307
+ });
308
+ if (add) {
309
+ let androidDevelopmentBuildProfileName = 'android_development';
310
+ while (buildProfiles.has(androidDevelopmentBuildProfileName)) {
311
+ androidDevelopmentBuildProfileName = `${androidDevelopmentBuildProfileName}_1`;
312
+ }
313
+ await (0, buildProfileUtils_1.addAndroidDevelopmentBuildProfileToEasJsonAsync)(projectDir, androidDevelopmentBuildProfileName);
314
+ }
315
+ else {
316
+ log_1.default.log('Skipping Android development build job...');
317
+ }
318
+ }
319
+ if (androidDevelopmentBuildProfileName) {
320
+ log_1.default.log(`Using Android development build profile: ${androidDevelopmentBuildProfileName}`);
321
+ workflowStarter.template.jobs.android_development_build = {
322
+ name: `Build ${androidDevelopmentBuildProfileName} for android`,
323
+ type: 'build',
324
+ params: {
325
+ profile: androidDevelopmentBuildProfileName,
326
+ platform: 'android',
327
+ },
328
+ };
329
+ nextSteps.add(nextStepForDeviceBuildProfile(androidDevelopmentBuildProfileName));
330
+ }
331
+ // ios_simulator_development_build
332
+ let iosSimulatorDevelopmentBuildProfileName = null;
333
+ for (const profileName of buildProfiles.keys()) {
334
+ const profile = buildProfiles.get(profileName)?.ios;
335
+ if (!profile) {
336
+ continue;
337
+ }
338
+ if ((0, buildProfileUtils_1.isBuildProfileForDevelopment)(profile, eas_build_job_1.Platform.IOS) &&
339
+ (0, buildProfileUtils_1.isIosBuildProfileForSimulator)(profile)) {
340
+ iosSimulatorDevelopmentBuildProfileName = profileName;
341
+ break;
342
+ }
343
+ }
344
+ if (!iosSimulatorDevelopmentBuildProfileName) {
345
+ log_1.default.warn('This workflow requires an iOS simulator development build profile in your eas.json, but none were found.');
346
+ const add = await (0, prompts_1.confirmAsync)({
347
+ message: 'Do you want to add an iOS simulator development build profile?',
348
+ initial: false,
349
+ });
350
+ if (add) {
351
+ let iosSimulatorDevelopmentBuildProfileName = 'ios_simulator_development';
352
+ while (buildProfiles.has(iosSimulatorDevelopmentBuildProfileName)) {
353
+ iosSimulatorDevelopmentBuildProfileName = `${iosSimulatorDevelopmentBuildProfileName}_1`;
354
+ }
355
+ await (0, buildProfileUtils_1.addIosDevelopmentBuildProfileToEasJsonAsync)(projectDir, iosSimulatorDevelopmentBuildProfileName, true);
356
+ }
357
+ else {
358
+ log_1.default.log('Skipping iOS simulator development build job...');
359
+ }
360
+ }
361
+ if (iosSimulatorDevelopmentBuildProfileName) {
362
+ log_1.default.log(`Using iOS simulator development build profile: ${iosSimulatorDevelopmentBuildProfileName}`);
363
+ workflowStarter.template.jobs.ios_simulator_development_build = {
364
+ name: `Build ${iosSimulatorDevelopmentBuildProfileName} for iOS simulator`,
365
+ type: 'build',
366
+ params: {
367
+ profile: iosSimulatorDevelopmentBuildProfileName,
368
+ platform: 'ios',
369
+ },
370
+ };
371
+ }
372
+ // ios_device_development_build
373
+ let iosDeviceDevelopmentBuildProfileName = null;
374
+ for (const profileName of buildProfiles.keys()) {
375
+ const profile = buildProfiles.get(profileName)?.ios;
376
+ if (!profile) {
377
+ continue;
378
+ }
379
+ if ((0, buildProfileUtils_1.isBuildProfileForDevelopment)(profile, eas_build_job_1.Platform.IOS) &&
380
+ !(0, buildProfileUtils_1.isIosBuildProfileForSimulator)(profile)) {
381
+ iosDeviceDevelopmentBuildProfileName = profileName;
382
+ break;
383
+ }
384
+ }
385
+ if (!iosDeviceDevelopmentBuildProfileName) {
386
+ log_1.default.warn('This workflow requires an iOS device development build profile in your eas.json, but none were found.');
387
+ const add = await (0, prompts_1.confirmAsync)({
388
+ message: 'Do you want to add an iOS device development build profile?',
389
+ initial: false,
390
+ });
391
+ if (add) {
392
+ let iosDeviceDevelopmentBuildProfileName = 'ios_device_development';
393
+ while (buildProfiles.has(iosDeviceDevelopmentBuildProfileName)) {
394
+ iosDeviceDevelopmentBuildProfileName = `${iosDeviceDevelopmentBuildProfileName}_1`;
395
+ }
396
+ await (0, buildProfileUtils_1.addIosDevelopmentBuildProfileToEasJsonAsync)(projectDir, iosDeviceDevelopmentBuildProfileName, false);
397
+ }
398
+ else {
399
+ log_1.default.log('Skipping iOS device development build job...');
400
+ }
401
+ }
402
+ if (iosDeviceDevelopmentBuildProfileName) {
403
+ log_1.default.log(`Using iOS device development build profile: ${iosDeviceDevelopmentBuildProfileName}`);
404
+ workflowStarter.template.jobs.ios_development_build = {
405
+ name: `Build ${iosDeviceDevelopmentBuildProfileName} for iOS simulator`,
406
+ type: 'build',
407
+ params: {
408
+ profile: iosDeviceDevelopmentBuildProfileName,
409
+ platform: 'ios',
410
+ },
411
+ };
412
+ nextSteps.add(nextStepForDeviceBuildProfile(iosDeviceDevelopmentBuildProfileName));
413
+ }
414
+ workflowStarter.nextSteps = [...nextSteps];
415
+ return workflowStarter;
416
+ }
417
+ exports.addBuildJobsToDevelopmentBuildTemplateAsync = addBuildJobsToDevelopmentBuildTemplateAsync;
418
+ async function ensureProductionBuildProfileExistsAsync(projectDir, workflowStarter) {
419
+ await (0, buildProfileUtils_1.addProductionBuildProfileToEasJsonIfNeededAsync)(projectDir);
420
+ workflowStarter.nextSteps = [
421
+ nextStepForDeviceBuildProfile('production'),
422
+ nextStepForAppSubmission(),
423
+ ];
424
+ return workflowStarter;
425
+ }
426
+ exports.ensureProductionBuildProfileExistsAsync = ensureProductionBuildProfileExistsAsync;
427
+ async function customizeTemplateIfNeededAsync(workflowStarter, projectDir, expoConfig) {
428
+ // Ensure EAS Build is configured
429
+ switch (workflowStarter.name) {
430
+ case WorkflowStarterName.BUILD:
431
+ case WorkflowStarterName.DEPLOY:
432
+ case WorkflowStarterName.UPDATE:
433
+ if (!(await (0, buildProfileUtils_1.hasBuildConfigureBeenRunAsync)({ projectDir, expoConfig }))) {
434
+ throw new Error('EAS Build is not configured for this project. Please run "eas build:configure" to configure it.');
435
+ }
436
+ break;
437
+ default:
438
+ break;
439
+ }
440
+ // Ensure EAS Update is configured
441
+ switch (workflowStarter.name) {
442
+ case WorkflowStarterName.DEPLOY:
443
+ case WorkflowStarterName.UPDATE:
444
+ if (!(await (0, buildProfileUtils_1.hasUpdateConfigureBeenRunAsync)({ projectDir, expoConfig }))) {
445
+ throw new Error('EAS Update is not configured for this project. Please run "eas update:configure" to configure it.');
446
+ }
447
+ break;
448
+ default:
449
+ break;
450
+ }
451
+ // Customize template
452
+ switch (workflowStarter.name) {
453
+ case WorkflowStarterName.BUILD:
454
+ log_1.default.debug('Adding build jobs to template...');
455
+ return await addBuildJobsToDevelopmentBuildTemplateAsync(projectDir, workflowStarter);
456
+ case WorkflowStarterName.DEPLOY:
457
+ return await ensureProductionBuildProfileExistsAsync(projectDir, workflowStarter);
458
+ default:
459
+ return workflowStarter;
460
+ }
461
+ }
462
+ exports.customizeTemplateIfNeededAsync = customizeTemplateIfNeededAsync;
@@ -4,3 +4,7 @@ export declare function validateWorkflowFileAsync(workflowFileContents: {
4
4
  filePath: string;
5
5
  }, projectDir: string, graphqlClient: ExpoGraphqlClient, projectId: string): Promise<void>;
6
6
  export declare function logWorkflowValidationErrors(error: unknown): void;
7
+ export declare function parsedYamlFromWorkflowContents(workflowFileContents: {
8
+ yamlConfig: string;
9
+ }): any;
10
+ export declare function workflowContentsFromParsedYaml(parsedYaml: any): string;
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logWorkflowValidationErrors = exports.validateWorkflowFileAsync = void 0;
3
+ exports.workflowContentsFromParsedYaml = exports.parsedYamlFromWorkflowContents = exports.logWorkflowValidationErrors = exports.validateWorkflowFileAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const eas_json_1 = require("@expo/eas-json");
6
5
  const errors_1 = require("@expo/eas-json/build/errors");
7
6
  const core_1 = require("@urql/core");
8
7
  const fs_1 = require("fs");
9
8
  const path_1 = tslib_1.__importDefault(require("path"));
10
9
  const YAML = tslib_1.__importStar(require("yaml"));
10
+ const buildProfileUtils_1 = require("./buildProfileUtils");
11
11
  const api_1 = require("../../api");
12
12
  const WorkflowRevisionMutation_1 = require("../../graphql/mutations/WorkflowRevisionMutation");
13
13
  const log_1 = tslib_1.__importDefault(require("../../log"));
@@ -82,8 +82,7 @@ async function validateWorkflowBuildJobsAsync(parsedYaml, projectDir) {
82
82
  if (buildJobs.length === 0) {
83
83
  return;
84
84
  }
85
- const easJsonAccessor = eas_json_1.EasJsonAccessor.fromProjectPath(projectDir);
86
- const buildProfileNames = new Set(easJsonAccessor && (await eas_json_1.EasJsonUtils.getBuildProfileNamesAsync(easJsonAccessor)));
85
+ const buildProfileNames = await (0, buildProfileUtils_1.buildProfileNamesFromProjectAsync)(projectDir);
87
86
  const invalidBuildJobs = buildJobs.filter(job => !buildProfileNames.has(job.value.params.profile) &&
88
87
  // If a profile name is interpolated, we can't check if it's valid until the workflow actually runs
89
88
  !buildProfileIsInterpolated(job.value.params.profile));
@@ -127,6 +126,11 @@ function parsedYamlFromWorkflowContents(workflowFileContents) {
127
126
  const parsedYaml = YAML.parse(workflowFileContents.yamlConfig);
128
127
  return parsedYaml;
129
128
  }
129
+ exports.parsedYamlFromWorkflowContents = parsedYamlFromWorkflowContents;
130
+ function workflowContentsFromParsedYaml(parsedYaml) {
131
+ return YAML.stringify(parsedYaml);
132
+ }
133
+ exports.workflowContentsFromParsedYaml = workflowContentsFromParsedYaml;
130
134
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
131
135
  async function fetchWorkflowSchemaAsync() {
132
136
  // EXPO_TESTING_WORKFLOW_SCHEMA_PATH is used only for testing against a different schema
@@ -1,5 +1,4 @@
1
1
  import { Platform } from '@expo/eas-build-job';
2
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
3
2
  import EasCommand from '../../commandUtils/EasCommand';
4
3
  import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
5
4
  import { BuildFragment } from '../../graphql/generated';
@@ -13,7 +12,7 @@ interface BuildResignFlags {
13
12
  sourceProfile?: string;
14
13
  maybeBuildId?: string;
15
14
  wait: boolean;
16
- environment?: EnvironmentVariableEnvironment;
15
+ environment?: string;
17
16
  }
18
17
  interface RawBuildResignFlags {
19
18
  json: boolean;
@@ -25,7 +24,7 @@ interface RawBuildResignFlags {
25
24
  'source-profile': string | undefined;
26
25
  wait: boolean;
27
26
  id: string | undefined;
28
- environment: EnvironmentVariableEnvironment | undefined;
27
+ environment: string | undefined;
29
28
  }
30
29
  export default class BuildResign extends EasCommand {
31
30
  static description: string;
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  export default class WorkerDeploy extends EasCommand {
4
3
  static description: string;
@@ -8,7 +7,7 @@ export default class WorkerDeploy extends EasCommand {
8
7
  static flags: {
9
8
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
9
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
10
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
12
11
  prod: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
12
  alias: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
14
13
  id: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  import { EASEnvironmentVariableScopeFlagValue } from '../../commandUtils/flags';
4
3
  export default class EnvCreate extends EasCommand {
@@ -10,7 +9,7 @@ export default class EnvCreate extends EasCommand {
10
9
  }[];
11
10
  static flags: {
12
11
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
- environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment[] | undefined>;
12
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
14
13
  scope: import("@oclif/core/lib/interfaces").OptionFlag<EASEnvironmentVariableScopeFlagValue>;
15
14
  visibility: import("@oclif/core/lib/interfaces").OptionFlag<"plaintext" | "sensitive" | "secret" | undefined>;
16
15
  name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
@@ -14,13 +14,12 @@ const log_1 = tslib_1.__importDefault(require("../../log"));
14
14
  const projectUtils_1 = require("../../project/projectUtils");
15
15
  const prompts_1 = require("../../prompts");
16
16
  const prompts_2 = require("../../utils/prompts");
17
- const variableUtils_1 = require("../../utils/variableUtils");
18
17
  class EnvCreate extends EasCommand_1.default {
19
18
  static description = 'create an environment variable for the current project or account';
20
19
  static args = [
21
20
  {
22
21
  name: 'environment',
23
- description: "Environment to create the variable in. One of 'production', 'preview', or 'development'.",
22
+ description: "Environment to create the variable in. Default environments are 'production', 'preview', and 'development'.",
24
23
  required: false,
25
24
  },
26
25
  ];
@@ -52,10 +51,10 @@ class EnvCreate extends EasCommand_1.default {
52
51
  async runAsync() {
53
52
  const { args, flags } = await this.parse(EnvCreate);
54
53
  const validatedFlags = this.sanitizeFlags(flags);
55
- const { name, value, scope, 'non-interactive': nonInteractive, environment: environments, visibility, force, type, fileName, } = await this.promptForMissingFlagsAsync(validatedFlags, args);
56
54
  const { projectId, loggedIn: { graphqlClient }, } = await this.getContextAsync(EnvCreate, {
57
- nonInteractive,
55
+ nonInteractive: validatedFlags['non-interactive'],
58
56
  });
57
+ const { name, value, scope, 'non-interactive': nonInteractive, environment: environments, visibility, force, type, fileName, } = await this.promptForMissingFlagsAsync(validatedFlags, args, { graphqlClient, projectId });
59
58
  const [projectDisplayName, ownerAccount] = await Promise.all([
60
59
  (0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId),
61
60
  (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId),
@@ -152,7 +151,7 @@ class EnvCreate extends EasCommand_1.default {
152
151
  throw new Error(`${message} Use --force to overwrite it.`);
153
152
  }
154
153
  }
155
- async promptForMissingFlagsAsync({ name, value, environment: environments, visibility, 'non-interactive': nonInteractive, type, ...rest }, { environment }) {
154
+ async promptForMissingFlagsAsync({ name, value, environment: environments, visibility, 'non-interactive': nonInteractive, type, ...rest }, { environment }, { graphqlClient, projectId }) {
156
155
  if (!name) {
157
156
  name = await (0, prompts_2.promptVariableNameAsync)(nonInteractive);
158
157
  }
@@ -187,16 +186,15 @@ class EnvCreate extends EasCommand_1.default {
187
186
  fileName = path_1.default.basename(environmentFilePath);
188
187
  }
189
188
  value = environmentFilePath ? await fs_extra_1.default.readFile(environmentFilePath, 'base64') : value;
190
- if (environment && !(0, variableUtils_1.isEnvironment)(environment.toLowerCase())) {
191
- throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
192
- }
193
- let newEnvironments = environments
194
- ? environments
195
- : environment
196
- ? [environment.toLowerCase()]
197
- : undefined;
189
+ let newEnvironments = environments ? environments : environment ? [environment] : undefined;
198
190
  if (!newEnvironments) {
199
- newEnvironments = await (0, prompts_2.promptVariableEnvironmentAsync)({ nonInteractive, multiple: true });
191
+ newEnvironments = await (0, prompts_2.promptVariableEnvironmentAsync)({
192
+ nonInteractive,
193
+ multiple: true,
194
+ canEnterCustomEnvironment: true,
195
+ graphqlClient,
196
+ projectId,
197
+ });
200
198
  if (!newEnvironments || newEnvironments.length === 0) {
201
199
  throw new Error('No environments selected');
202
200
  }
@@ -1,4 +1,3 @@
1
- import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  import { EASEnvironmentVariableScopeFlagValue } from '../../commandUtils/flags';
4
3
  export default class EnvDelete extends EasCommand {
@@ -7,7 +6,7 @@ export default class EnvDelete extends EasCommand {
7
6
  'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
7
  scope: import("@oclif/core/lib/interfaces").OptionFlag<EASEnvironmentVariableScopeFlagValue>;
9
8
  'variable-name': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
10
- 'variable-environment': import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
9
+ 'variable-environment': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
11
10
  };
12
11
  static args: {
13
12
  name: string;
@@ -18,7 +18,7 @@ class EnvDelete extends EasCommand_1.default {
18
18
  'variable-name': core_1.Flags.string({
19
19
  description: 'Name of the variable to delete',
20
20
  }),
21
- 'variable-environment': core_1.Flags.enum({
21
+ 'variable-environment': core_1.Flags.string({
22
22
  ...flags_1.EasEnvironmentFlagParameters,
23
23
  description: 'Current environment of the variable to delete',
24
24
  }),
@@ -28,7 +28,7 @@ class EnvDelete extends EasCommand_1.default {
28
28
  static args = [
29
29
  {
30
30
  name: 'environment',
31
- description: "Current environment of the variable to delete. One of 'production', 'preview', or 'development'.",
31
+ description: "Current environment of the variable to delete. Default environments are 'production', 'preview', and 'development'.",
32
32
  required: false,
33
33
  },
34
34
  ];
@@ -108,10 +108,6 @@ class EnvDelete extends EasCommand_1.default {
108
108
  ? generated_1.EnvironmentVariableScope.Shared
109
109
  : generated_1.EnvironmentVariableScope.Project;
110
110
  if (environment) {
111
- environment = environment.toLowerCase();
112
- if (!(0, variableUtils_1.isEnvironment)(environment)) {
113
- throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
114
- }
115
111
  return { ...flags, 'variable-environment': environment, scope };
116
112
  }
117
113
  return { ...flags, scope };