eas-cli 16.0.1 → 16.2.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 (32) hide show
  1. package/README.md +117 -81
  2. package/build/build/android/prepareJob.js +1 -0
  3. package/build/build/ios/prepareJob.js +1 -0
  4. package/build/build/utils/url.d.ts +1 -0
  5. package/build/build/utils/url.js +5 -1
  6. package/build/commandUtils/EasCommand.js +6 -1
  7. package/build/commandUtils/builds.d.ts +1 -0
  8. package/build/commandUtils/builds.js +3 -0
  9. package/build/commandUtils/context/ServerSideEnvironmentVariablesContextField.d.ts +1 -2
  10. package/build/commands/deploy/index.js +20 -2
  11. package/build/commands/fingerprint/compare.d.ts +3 -11
  12. package/build/commands/fingerprint/compare.js +50 -15
  13. package/build/commands/fingerprint/generate.d.ts +6 -3
  14. package/build/commands/fingerprint/generate.js +50 -9
  15. package/build/commands/update/delete.js +13 -6
  16. package/build/commands/update/index.d.ts +1 -0
  17. package/build/commands/update/index.js +90 -59
  18. package/build/fingerprint/cli.js +11 -2
  19. package/build/fingerprint/utils.d.ts +3 -1
  20. package/build/fingerprint/utils.js +2 -2
  21. package/build/graphql/generated.d.ts +213 -9
  22. package/build/graphql/generated.js +15 -1
  23. package/build/graphql/queries/BackgroundJobReceiptQuery.d.ts +5 -0
  24. package/build/graphql/queries/BackgroundJobReceiptQuery.js +27 -0
  25. package/build/graphql/types/BackgroundJobReceipt.d.ts +1 -0
  26. package/build/graphql/types/BackgroundJobReceipt.js +20 -0
  27. package/build/project/publish.d.ts +17 -1
  28. package/build/project/publish.js +22 -1
  29. package/build/utils/pollForBackgroundJobReceiptAsync.d.ts +29 -0
  30. package/build/utils/pollForBackgroundJobReceiptAsync.js +92 -0
  31. package/oclif.manifest.json +49 -6
  32. package/package.json +6 -5
@@ -5,6 +5,7 @@ const eas_build_job_1 = require("@expo/eas-build-job");
5
5
  const core_1 = require("@oclif/core");
6
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
7
  const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
8
+ const api_1 = require("../../api");
8
9
  const queries_1 = require("../../branch/queries");
9
10
  const graphql_1 = require("../../build/graphql");
10
11
  const repository_1 = require("../../build/utils/repository");
@@ -15,6 +16,7 @@ const pagination_1 = require("../../commandUtils/pagination");
15
16
  const fetch_1 = tslib_1.__importDefault(require("../../fetch"));
16
17
  const generated_1 = require("../../graphql/generated");
17
18
  const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
19
+ const AppQuery_1 = require("../../graphql/queries/AppQuery");
18
20
  const log_1 = tslib_1.__importStar(require("../../log"));
19
21
  const ora_1 = require("../../ora");
20
22
  const platform_1 = require("../../platform");
@@ -374,74 +376,103 @@ class UpdatePublish extends EasCommand_1.default {
374
376
  }
375
377
  if (jsonFlag) {
376
378
  (0, json_1.printJsonOnlyOutput)((0, utils_1.getUpdateJsonInfosForUpdates)(newUpdates));
379
+ return;
377
380
  }
378
- else {
379
- if (new Set(newUpdates.map(update => update.group)).size > 1) {
380
- log_1.default.addNewLineIfNone();
381
- log_1.default.log('👉 Since multiple runtime versions are defined, multiple update groups have been published.');
381
+ if (new Set(newUpdates.map(update => update.group)).size > 1) {
382
+ log_1.default.addNewLineIfNone();
383
+ log_1.default.log('👉 Since multiple runtime versions are defined, multiple update groups have been published.');
384
+ }
385
+ log_1.default.addNewLineIfNone();
386
+ const runtimeToCompatibleBuilds = await Promise.all(runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(obj => (0, publish_1.findCompatibleBuildsAsync)(graphqlClient, projectId, obj)));
387
+ for (const runtime of (0, uniqBy_1.default)(runtimeToPlatformsAndFingerprintInfoMapping, version => version.runtimeVersion)) {
388
+ const newUpdatesForRuntimeVersion = newUpdates.filter(update => update.runtimeVersion === runtime.runtimeVersion);
389
+ if (newUpdatesForRuntimeVersion.length === 0) {
390
+ throw new Error(`Publish response is missing updates with runtime ${runtime.runtimeVersion}.`);
382
391
  }
392
+ const platforms = newUpdatesForRuntimeVersion.map(update => update.platform);
393
+ const newAndroidUpdate = newUpdatesForRuntimeVersion.find(update => update.platform === 'android');
394
+ const newIosUpdate = newUpdatesForRuntimeVersion.find(update => update.platform === 'ios');
395
+ const updateGroupId = newUpdatesForRuntimeVersion[0].group;
396
+ const projectName = exp.slug;
397
+ const accountName = (await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId)).name;
398
+ const updateGroupUrl = (0, url_1.getUpdateGroupUrl)(accountName, projectName, updateGroupId);
399
+ const updateGroupLink = (0, log_1.link)(updateGroupUrl, { dim: false });
400
+ log_1.default.log((0, formatFields_1.default)([
401
+ { label: 'Branch', value: branchName },
402
+ { label: 'Runtime version', value: runtime.runtimeVersion },
403
+ { label: 'Platform', value: platforms.join(', ') },
404
+ { label: 'Update group ID', value: updateGroupId },
405
+ ...(newAndroidUpdate ? [{ label: 'Android update ID', value: newAndroidUpdate.id }] : []),
406
+ ...(newIosUpdate ? [{ label: 'iOS update ID', value: newIosUpdate.id }] : []),
407
+ ...(newAndroidUpdate?.rolloutControlUpdate
408
+ ? [
409
+ {
410
+ label: 'Android Rollout',
411
+ value: `${newAndroidUpdate.rolloutPercentage}% (Base update ID: ${newAndroidUpdate.rolloutControlUpdate.id})`,
412
+ },
413
+ ]
414
+ : []),
415
+ ...(newIosUpdate?.rolloutControlUpdate
416
+ ? [
417
+ {
418
+ label: 'iOS Rollout',
419
+ value: `${newIosUpdate.rolloutPercentage}% (Base update ID: ${newIosUpdate.rolloutControlUpdate.id})`,
420
+ },
421
+ ]
422
+ : []),
423
+ { label: 'Message', value: updateMessage ?? '' },
424
+ ...(gitCommitHash
425
+ ? [
426
+ {
427
+ label: 'Commit',
428
+ value: `${gitCommitHash}${isGitWorkingTreeDirty ? '*' : ''}`,
429
+ },
430
+ ]
431
+ : []),
432
+ { label: 'EAS Dashboard', value: updateGroupLink },
433
+ ]));
383
434
  log_1.default.addNewLineIfNone();
384
- for (const runtime of (0, uniqBy_1.default)(runtimeToPlatformsAndFingerprintInfoMapping, version => version.runtimeVersion)) {
385
- const newUpdatesForRuntimeVersion = newUpdates.filter(update => update.runtimeVersion === runtime.runtimeVersion);
386
- if (newUpdatesForRuntimeVersion.length === 0) {
387
- throw new Error(`Publish response is missing updates with runtime ${runtime.runtimeVersion}.`);
388
- }
389
- const platforms = newUpdatesForRuntimeVersion.map(update => update.platform);
390
- const newAndroidUpdate = newUpdatesForRuntimeVersion.find(update => update.platform === 'android');
391
- const newIosUpdate = newUpdatesForRuntimeVersion.find(update => update.platform === 'ios');
392
- const updateGroupId = newUpdatesForRuntimeVersion[0].group;
393
- const projectName = exp.slug;
394
- const accountName = (await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId)).name;
395
- const updateGroupUrl = (0, url_1.getUpdateGroupUrl)(accountName, projectName, updateGroupId);
396
- const updateGroupLink = (0, log_1.link)(updateGroupUrl, { dim: false });
397
- log_1.default.log((0, formatFields_1.default)([
398
- { label: 'Branch', value: branchName },
399
- { label: 'Runtime version', value: runtime.runtimeVersion },
400
- { label: 'Platform', value: platforms.join(', ') },
401
- { label: 'Update group ID', value: updateGroupId },
402
- ...(newAndroidUpdate
403
- ? [{ label: 'Android update ID', value: newAndroidUpdate.id }]
404
- : []),
405
- ...(newIosUpdate ? [{ label: 'iOS update ID', value: newIosUpdate.id }] : []),
406
- ...(newAndroidUpdate?.rolloutControlUpdate
407
- ? [
408
- {
409
- label: 'Android Rollout',
410
- value: `${newAndroidUpdate.rolloutPercentage}% (Base update ID: ${newAndroidUpdate.rolloutControlUpdate.id})`,
411
- },
412
- ]
413
- : []),
414
- ...(newIosUpdate?.rolloutControlUpdate
415
- ? [
416
- {
417
- label: 'iOS Rollout',
418
- value: `${newIosUpdate.rolloutPercentage}% (Base update ID: ${newIosUpdate.rolloutControlUpdate.id})`,
419
- },
420
- ]
421
- : []),
422
- { label: 'Message', value: updateMessage ?? '' },
423
- ...(gitCommitHash
424
- ? [
435
+ if ((0, publish_1.isUploadedAssetCountAboveWarningThreshold)(uploadedAssetCount, assetLimitPerUpdateGroup)) {
436
+ log_1.default.warn(`This update group contains ${uploadedAssetCount} assets and is nearing the server cap of ${assetLimitPerUpdateGroup}.\n` +
437
+ `${(0, log_1.learnMore)('https://docs.expo.dev/eas-update/optimize-assets/', {
438
+ learnMoreMessage: 'Consider optimizing your usage of assets',
439
+ dim: false,
440
+ })}.`);
441
+ log_1.default.addNewLineIfNone();
442
+ }
443
+ const fingerprintsWithoutCompatibleBuilds = runtimeToCompatibleBuilds.find(({ runtimeVersion }) => runtimeVersion === runtime.runtimeVersion)?.fingerprintInfoGroupWithCompatibleBuilds;
444
+ if (fingerprintsWithoutCompatibleBuilds) {
445
+ const missingBuilds = Object.entries(fingerprintsWithoutCompatibleBuilds).filter(([_platform, fingerprintInfo]) => !fingerprintInfo.build);
446
+ if (missingBuilds.length > 0) {
447
+ const project = await AppQuery_1.AppQuery.byIdAsync(graphqlClient, projectId);
448
+ log_1.default.warn('No compatible builds found for the following fingerprints:');
449
+ for (const [platform, fingerprintInfo] of missingBuilds) {
450
+ const fingerprintUrl = new URL(`/accounts/${project.ownerAccount.name}/projects/${project.slug}/fingerprints/${fingerprintInfo.fingerprintHash}`, (0, api_1.getExpoWebsiteBaseUrl)());
451
+ log_1.default.warn((0, formatFields_1.default)([
425
452
  {
426
- label: 'Commit',
427
- value: `${gitCommitHash}${isGitWorkingTreeDirty ? '*' : ''}`,
453
+ label: `${this.prettyPlatform(platform)} fingerprint`,
454
+ value: fingerprintInfo.fingerprintHash,
428
455
  },
429
- ]
430
- : []),
431
- { label: 'EAS Dashboard', value: updateGroupLink },
432
- ]));
433
- log_1.default.addNewLineIfNone();
434
- if ((0, publish_1.isUploadedAssetCountAboveWarningThreshold)(uploadedAssetCount, assetLimitPerUpdateGroup)) {
435
- log_1.default.warn(`This update group contains ${uploadedAssetCount} assets and is nearing the server cap of ${assetLimitPerUpdateGroup}.\n` +
436
- `${(0, log_1.learnMore)('https://docs.expo.dev/eas-update/optimize-assets/', {
437
- learnMoreMessage: 'Consider optimizing your usage of assets',
438
- dim: false,
439
- })}.`);
440
- log_1.default.addNewLineIfNone();
456
+ { label: 'URL', value: fingerprintUrl.toString() },
457
+ ], {
458
+ labelFormat: label => ` ${chalk_1.default.dim(label)}:`,
459
+ }));
460
+ log_1.default.addNewLineIfNone();
461
+ }
441
462
  }
442
463
  }
443
464
  }
444
465
  }
466
+ prettyPlatform(updatePlatform) {
467
+ switch (updatePlatform) {
468
+ case 'android':
469
+ return 'Android';
470
+ case 'ios':
471
+ return 'iOS';
472
+ default:
473
+ return updatePlatform;
474
+ }
475
+ }
445
476
  sanitizeFlags(flags) {
446
477
  const nonInteractive = flags['non-interactive'] ?? false;
447
478
  const { auto, branch: branchName, channel: channelName, message: updateMessage } = flags;
@@ -69,8 +69,17 @@ async function createFingerprintWithoutLoggingAsync(projectDir, fingerprintPath,
69
69
  if (options.debug) {
70
70
  fingerprintOptions.debug = true;
71
71
  }
72
- // eslint-disable-next-line @typescript-eslint/return-await
73
- return await Fingerprint.createFingerprintAsync(projectDir, fingerprintOptions);
72
+ return await withTemporaryEnvAsync(options.env ?? {}, () => Fingerprint.createFingerprintAsync(projectDir, fingerprintOptions));
73
+ }
74
+ async function withTemporaryEnvAsync(envVars, fn) {
75
+ const originalEnv = { ...process.env };
76
+ Object.assign(process.env, envVars);
77
+ try {
78
+ return await fn();
79
+ }
80
+ finally {
81
+ process.env = originalEnv;
82
+ }
74
83
  }
75
84
  /**
76
85
  * Computes project fingerprints based on provided options and returns a map of fingerprint data keyed by a string.
@@ -3,7 +3,9 @@ import { Fingerprint } from './types';
3
3
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
4
4
  import { AppPlatform } from '../graphql/generated';
5
5
  import { Client } from '../vcs/vcs';
6
- export declare function getFingerprintInfoFromLocalProjectForPlatformsAsync(graphqlClient: ExpoGraphqlClient, projectDir: string, projectId: string, vcsClient: Client, platforms: AppPlatform[]): Promise<Fingerprint>;
6
+ export declare function getFingerprintInfoFromLocalProjectForPlatformsAsync(graphqlClient: ExpoGraphqlClient, projectDir: string, projectId: string, vcsClient: Client, platforms: AppPlatform[], { env }?: {
7
+ env?: Record<string, string>;
8
+ }): Promise<Fingerprint>;
7
9
  export declare function appPlatformToPlatform(platform: AppPlatform): Platform;
8
10
  export declare function appPlatformToString(platform: AppPlatform): string;
9
11
  export declare function stringToAppPlatform(platform: string): AppPlatform;
@@ -9,14 +9,14 @@ const FingerprintMutation_1 = require("../graphql/mutations/FingerprintMutation"
9
9
  const log_1 = tslib_1.__importDefault(require("../log"));
10
10
  const maybeUploadFingerprintAsync_1 = require("../project/maybeUploadFingerprintAsync");
11
11
  const workflow_1 = require("../project/workflow");
12
- async function getFingerprintInfoFromLocalProjectForPlatformsAsync(graphqlClient, projectDir, projectId, vcsClient, platforms) {
12
+ async function getFingerprintInfoFromLocalProjectForPlatformsAsync(graphqlClient, projectDir, projectId, vcsClient, platforms, { env } = {}) {
13
13
  const workflows = await (0, workflow_1.resolveWorkflowPerPlatformAsync)(projectDir, vcsClient);
14
14
  const optionsFromWorkflow = getFingerprintOptionsFromWorkflow(platforms, workflows);
15
15
  const projectFingerprint = await (0, cli_1.createFingerprintAsync)(projectDir, {
16
16
  ...optionsFromWorkflow,
17
17
  platforms: platforms.map(appPlatformToString),
18
18
  debug: true,
19
- env: undefined,
19
+ env,
20
20
  });
21
21
  if (!projectFingerprint) {
22
22
  throw new Error('Project fingerprints can only be computed for projects with SDK 52 or higher');