eas-cli 16.1.0 → 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.
@@ -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;
@@ -167,6 +167,7 @@ export type Account = {
167
167
  googleServiceAccountKeys: Array<GoogleServiceAccountKey>;
168
168
  /** Android credentials for account */
169
169
  googleServiceAccountKeysPaginated: AccountGoogleServiceAccountKeysConnection;
170
+ hasBuilds: Scalars['Boolean']['output'];
170
171
  id: Scalars['ID']['output'];
171
172
  isCurrent: Scalars['Boolean']['output'];
172
173
  isDisabled: Scalars['Boolean']['output'];
@@ -2709,6 +2710,7 @@ export declare enum BuildPriority {
2709
2710
  export type BuildPublicData = {
2710
2711
  __typename?: 'BuildPublicData';
2711
2712
  artifacts: PublicArtifacts;
2713
+ buildMode?: Maybe<BuildMode>;
2712
2714
  distribution?: Maybe<DistributionType>;
2713
2715
  id: Scalars['ID']['output'];
2714
2716
  isForIosSimulator: Scalars['Boolean']['output'];
@@ -4373,6 +4375,7 @@ export type IosSubmissionConfigInput = {
4373
4375
  ascApiKey?: InputMaybe<AscApiKeyInput>;
4374
4376
  ascApiKeyId?: InputMaybe<Scalars['String']['input']>;
4375
4377
  ascAppIdentifier: Scalars['String']['input'];
4378
+ groups?: InputMaybe<Array<Scalars['String']['input']>>;
4376
4379
  isVerboseFastlaneEnabled?: InputMaybe<Scalars['Boolean']['input']>;
4377
4380
  };
4378
4381
  /** Represents a Turtle Job Run */
@@ -6061,6 +6064,8 @@ export type UpdateMutation = {
6061
6064
  __typename?: 'UpdateMutation';
6062
6065
  /** Delete an EAS update group */
6063
6066
  deleteUpdateGroup: DeleteUpdateGroupResult;
6067
+ /** Delete an EAS update group in the background */
6068
+ scheduleUpdateGroupDeletion: BackgroundJobReceipt;
6064
6069
  /** Set code signing info for an update */
6065
6070
  setCodeSigningInfo: Update;
6066
6071
  /** Set rollout percentage for an update */
@@ -6069,6 +6074,9 @@ export type UpdateMutation = {
6069
6074
  export type UpdateMutationDeleteUpdateGroupArgs = {
6070
6075
  group: Scalars['ID']['input'];
6071
6076
  };
6077
+ export type UpdateMutationScheduleUpdateGroupDeletionArgs = {
6078
+ group: Scalars['ID']['input'];
6079
+ };
6072
6080
  export type UpdateMutationSetCodeSigningInfoArgs = {
6073
6081
  codeSigningInfo: CodeSigningInfoInput;
6074
6082
  updateId: Scalars['ID']['input'];
@@ -7571,16 +7579,26 @@ export type AppInfoQuery = {
7571
7579
  };
7572
7580
  };
7573
7581
  };
7574
- export type DeleteUpdateGroupMutationVariables = Exact<{
7582
+ export type ScheduleUpdateGroupDeletionMutationVariables = Exact<{
7575
7583
  group: Scalars['ID']['input'];
7576
7584
  }>;
7577
- export type DeleteUpdateGroupMutation = {
7585
+ export type ScheduleUpdateGroupDeletionMutation = {
7578
7586
  __typename?: 'RootMutation';
7579
7587
  update: {
7580
7588
  __typename?: 'UpdateMutation';
7581
- deleteUpdateGroup: {
7582
- __typename?: 'DeleteUpdateGroupResult';
7583
- group: string;
7589
+ scheduleUpdateGroupDeletion: {
7590
+ __typename?: 'BackgroundJobReceipt';
7591
+ id: string;
7592
+ state: BackgroundJobState;
7593
+ tries: number;
7594
+ willRetry: boolean;
7595
+ resultId?: string | null;
7596
+ resultType: BackgroundJobResultType;
7597
+ resultData?: any | null;
7598
+ errorCode?: string | null;
7599
+ errorMessage?: string | null;
7600
+ createdAt: any;
7601
+ updatedAt: any;
7584
7602
  };
7585
7603
  };
7586
7604
  };
@@ -12331,6 +12349,29 @@ export type LatestAppVersionQuery = {
12331
12349
  };
12332
12350
  };
12333
12351
  };
12352
+ export type BackgroundJobReceiptByIdQueryVariables = Exact<{
12353
+ id: Scalars['ID']['input'];
12354
+ }>;
12355
+ export type BackgroundJobReceiptByIdQuery = {
12356
+ __typename?: 'RootQuery';
12357
+ backgroundJobReceipt: {
12358
+ __typename?: 'BackgroundJobReceiptQuery';
12359
+ byId: {
12360
+ __typename?: 'BackgroundJobReceipt';
12361
+ id: string;
12362
+ state: BackgroundJobState;
12363
+ tries: number;
12364
+ willRetry: boolean;
12365
+ resultId?: string | null;
12366
+ resultType: BackgroundJobResultType;
12367
+ resultData?: any | null;
12368
+ errorCode?: string | null;
12369
+ errorMessage?: string | null;
12370
+ createdAt: any;
12371
+ updatedAt: any;
12372
+ };
12373
+ };
12374
+ };
12334
12375
  export type ViewBranchQueryVariables = Exact<{
12335
12376
  appId: Scalars['String']['input'];
12336
12377
  name: Scalars['String']['input'];
@@ -14175,6 +14216,20 @@ export type AppFragment = {
14175
14216
  };
14176
14217
  } | null;
14177
14218
  };
14219
+ export type BackgroundJobReceiptDataFragment = {
14220
+ __typename?: 'BackgroundJobReceipt';
14221
+ id: string;
14222
+ state: BackgroundJobState;
14223
+ tries: number;
14224
+ willRetry: boolean;
14225
+ resultId?: string | null;
14226
+ resultType: BackgroundJobResultType;
14227
+ resultData?: any | null;
14228
+ errorCode?: string | null;
14229
+ errorMessage?: string | null;
14230
+ createdAt: any;
14231
+ updatedAt: any;
14232
+ };
14178
14233
  export type BuildFragment = {
14179
14234
  __typename?: 'Build';
14180
14235
  id: string;
@@ -0,0 +1,5 @@
1
+ import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
2
+ import { BackgroundJobReceiptByIdQuery } from '../generated';
3
+ export declare const BackgroundJobReceiptQuery: {
4
+ byIdAsync(graphqlClient: ExpoGraphqlClient, backgroundJobReceiptId: string): Promise<BackgroundJobReceiptByIdQuery['backgroundJobReceipt']['byId'] | null>;
5
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BackgroundJobReceiptQuery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
6
+ const client_1 = require("../client");
7
+ const BackgroundJobReceipt_1 = require("../types/BackgroundJobReceipt");
8
+ exports.BackgroundJobReceiptQuery = {
9
+ async byIdAsync(graphqlClient, backgroundJobReceiptId) {
10
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
11
+ .query((0, graphql_tag_1.default) `
12
+ query BackgroundJobReceiptById($id: ID!) {
13
+ backgroundJobReceipt {
14
+ byId(id: $id) {
15
+ id
16
+ ...BackgroundJobReceiptData
17
+ }
18
+ }
19
+ }
20
+ ${BackgroundJobReceipt_1.BackgroundJobReceiptNode}
21
+ `, { id: backgroundJobReceiptId }, {
22
+ additionalTypenames: ['BackgroundJobReceipt'],
23
+ })
24
+ .toPromise());
25
+ return data.backgroundJobReceipt.byId ?? null;
26
+ },
27
+ };
@@ -0,0 +1 @@
1
+ export declare const BackgroundJobReceiptNode: import("graphql").DocumentNode;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BackgroundJobReceiptNode = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
6
+ exports.BackgroundJobReceiptNode = (0, graphql_tag_1.default) `
7
+ fragment BackgroundJobReceiptData on BackgroundJobReceipt {
8
+ id
9
+ state
10
+ tries
11
+ willRetry
12
+ resultId
13
+ resultType
14
+ resultData
15
+ errorCode
16
+ errorMessage
17
+ createdAt
18
+ updatedAt
19
+ }
20
+ `;
@@ -4,7 +4,7 @@ import { Env, FingerprintSource, Platform, Workflow } from '@expo/eas-build-job'
4
4
  import Joi from 'joi';
5
5
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
6
6
  import { PaginatedQueryOptions } from '../commandUtils/pagination';
7
- import { AppPlatform, PartialManifestAsset, UpdateRolloutInfoGroup } from '../graphql/generated';
7
+ import { AppPlatform, BuildFragment, PartialManifestAsset, UpdateRolloutInfoGroup } from '../graphql/generated';
8
8
  import { RequestedPlatform } from '../platform';
9
9
  import { UpdateJsonInfo } from '../update/utils';
10
10
  import { Client } from '../vcs/vcs';
@@ -188,6 +188,22 @@ export declare function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWit
188
188
  expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
189
189
  fingerprintInfoGroup: FingerprintInfoGroup;
190
190
  })[]>;
191
+ export declare function findCompatibleBuildsAsync(graphqlClient: ExpoGraphqlClient, appId: string, runtimeToPlatformsAndFingerprintInfoMapping: {
192
+ runtimeVersion: string;
193
+ platforms: UpdatePublishPlatform[];
194
+ fingerprintInfoGroup: FingerprintInfoGroup;
195
+ }): Promise<{
196
+ runtimeVersion: string;
197
+ platforms: UpdatePublishPlatform[];
198
+ fingerprintInfoGroupWithCompatibleBuilds: {
199
+ android?: (FingerprintInfo & {
200
+ build?: BuildFragment;
201
+ }) | undefined;
202
+ ios?: (FingerprintInfo & {
203
+ build?: BuildFragment;
204
+ }) | undefined;
205
+ };
206
+ }>;
191
207
  export declare const platformDisplayNames: Record<UpdatePublishPlatform, string>;
192
208
  export declare const updatePublishPlatformToAppPlatform: Record<UpdatePublishPlatform, AppPlatform>;
193
209
  export declare function getRuntimeToUpdateRolloutInfoGroupMappingAsync(graphqlClient: ExpoGraphqlClient, { appId, branchName, rolloutPercentage, runtimeToPlatformsAndFingerprintInfoMapping, }: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRuntimeToUpdateRolloutInfoGroupMappingAsync = exports.updatePublishPlatformToAppPlatform = exports.platformDisplayNames = exports.maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync = exports.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects = exports.getRuntimeVersionInfoObjectsAsync = exports.defaultPublishPlatforms = exports.getUpdateMessageForCommandAsync = exports.getBranchNameForCommandAsync = exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.getOriginalPathFromAssetMap = exports.getAssetHashFromPath = exports.loadAssetMapAsync = exports.filterCollectedAssetsByRequestedPlatforms = exports.generateEasMetadataAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
3
+ exports.getRuntimeToUpdateRolloutInfoGroupMappingAsync = exports.updatePublishPlatformToAppPlatform = exports.platformDisplayNames = exports.findCompatibleBuildsAsync = exports.maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync = exports.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects = exports.getRuntimeVersionInfoObjectsAsync = exports.defaultPublishPlatforms = exports.getUpdateMessageForCommandAsync = exports.getBranchNameForCommandAsync = exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.getOriginalPathFromAssetMap = exports.getAssetHashFromPath = exports.loadAssetMapAsync = exports.filterCollectedAssetsByRequestedPlatforms = exports.generateEasMetadataAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const config_plugins_1 = require("@expo/config-plugins");
6
6
  const eas_build_job_1 = require("@expo/eas-build-job");
@@ -19,6 +19,7 @@ const projectUtils_1 = require("./projectUtils");
19
19
  const resolveRuntimeVersionAsync_1 = require("./resolveRuntimeVersionAsync");
20
20
  const queries_1 = require("../branch/queries");
21
21
  const utils_1 = require("../branch/utils");
22
+ const builds_1 = require("../commandUtils/builds");
22
23
  const cli_1 = require("../fingerprint/cli");
23
24
  const generated_1 = require("../graphql/generated");
24
25
  const PublishMutation_1 = require("../graphql/mutations/PublishMutation");
@@ -601,6 +602,26 @@ async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoU
601
602
  return [...runtimesWithComputedFingerprint, ...runtimesWithPreviouslyComputedFingerprints];
602
603
  }
603
604
  exports.maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync = maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync;
605
+ async function findCompatibleBuildsAsync(graphqlClient, appId, runtimeToPlatformsAndFingerprintInfoMapping) {
606
+ const { fingerprintInfoGroup } = runtimeToPlatformsAndFingerprintInfoMapping;
607
+ const entriesPromises = Object.entries(fingerprintInfoGroup).map(async ([platform, fingerprintInfo]) => {
608
+ const build = (await (0, builds_1.fetchBuildsAsync)({
609
+ graphqlClient,
610
+ projectId: appId,
611
+ filters: {
612
+ fingerprintHash: fingerprintInfo.fingerprintHash,
613
+ },
614
+ }))[0];
615
+ return [platform, { ...fingerprintInfo, build }];
616
+ });
617
+ const entries = await Promise.all(entriesPromises);
618
+ const fingerprintInfoGroupWithCompatibleBuilds = Object.fromEntries(entries);
619
+ return {
620
+ ...runtimeToPlatformsAndFingerprintInfoMapping,
621
+ fingerprintInfoGroupWithCompatibleBuilds,
622
+ };
623
+ }
624
+ exports.findCompatibleBuildsAsync = findCompatibleBuildsAsync;
604
625
  exports.platformDisplayNames = {
605
626
  android: 'Android',
606
627
  ios: 'iOS',
@@ -0,0 +1,29 @@
1
+ import { CombinedError } from '@urql/core';
2
+ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
3
+ import { BackgroundJobReceiptDataFragment } from '../graphql/generated';
4
+ export declare enum BackgroundJobReceiptPollErrorType {
5
+ NULL_RECEIPT = 0,
6
+ JOB_FAILED_NO_WILL_RETRY = 1,
7
+ TIMEOUT = 2
8
+ }
9
+ export type BackgroundJobReceiptPollErrorData = {
10
+ errorType: BackgroundJobReceiptPollErrorType.NULL_RECEIPT;
11
+ } | {
12
+ errorType: BackgroundJobReceiptPollErrorType.JOB_FAILED_NO_WILL_RETRY;
13
+ receiptErrorMessage: string | undefined | null;
14
+ } | {
15
+ errorType: BackgroundJobReceiptPollErrorType.TIMEOUT;
16
+ };
17
+ export declare class BackgroundJobReceiptPollError extends Error {
18
+ readonly errorData: BackgroundJobReceiptPollErrorData;
19
+ constructor(errorData: BackgroundJobReceiptPollErrorData);
20
+ static createErrorMessage(errorData: BackgroundJobReceiptPollErrorData): string;
21
+ }
22
+ export type BackgroundJobPollErrorCondition = (error: CombinedError) => {
23
+ errorIndicatesSuccess: boolean;
24
+ };
25
+ export declare function pollForBackgroundJobReceiptAsync(graphqlClient: ExpoGraphqlClient, backgroundJobReceipt: BackgroundJobReceiptDataFragment): Promise<BackgroundJobReceiptDataFragment>;
26
+ export declare function pollForBackgroundJobReceiptAsync(graphqlClient: ExpoGraphqlClient, backgroundJobReceipt: BackgroundJobReceiptDataFragment, options?: {
27
+ onBackgroundJobReceiptPollError?: BackgroundJobPollErrorCondition;
28
+ pollInterval?: number;
29
+ }): Promise<BackgroundJobReceiptDataFragment | null>;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pollForBackgroundJobReceiptAsync = exports.BackgroundJobReceiptPollError = exports.BackgroundJobReceiptPollErrorType = void 0;
4
+ const core_1 = require("@urql/core");
5
+ const set_interval_async_1 = require("set-interval-async");
6
+ const generated_1 = require("../graphql/generated");
7
+ const BackgroundJobReceiptQuery_1 = require("../graphql/queries/BackgroundJobReceiptQuery");
8
+ var BackgroundJobReceiptPollErrorType;
9
+ (function (BackgroundJobReceiptPollErrorType) {
10
+ BackgroundJobReceiptPollErrorType[BackgroundJobReceiptPollErrorType["NULL_RECEIPT"] = 0] = "NULL_RECEIPT";
11
+ BackgroundJobReceiptPollErrorType[BackgroundJobReceiptPollErrorType["JOB_FAILED_NO_WILL_RETRY"] = 1] = "JOB_FAILED_NO_WILL_RETRY";
12
+ BackgroundJobReceiptPollErrorType[BackgroundJobReceiptPollErrorType["TIMEOUT"] = 2] = "TIMEOUT";
13
+ })(BackgroundJobReceiptPollErrorType || (exports.BackgroundJobReceiptPollErrorType = BackgroundJobReceiptPollErrorType = {}));
14
+ class BackgroundJobReceiptPollError extends Error {
15
+ errorData;
16
+ constructor(errorData) {
17
+ super(BackgroundJobReceiptPollError.createErrorMessage(errorData));
18
+ this.errorData = errorData;
19
+ }
20
+ static createErrorMessage(errorData) {
21
+ switch (errorData.errorType) {
22
+ case BackgroundJobReceiptPollErrorType.NULL_RECEIPT:
23
+ return 'Background job receipt was null.';
24
+ case BackgroundJobReceiptPollErrorType.JOB_FAILED_NO_WILL_RETRY:
25
+ return `Background job failed with error: ${errorData.receiptErrorMessage}`;
26
+ case BackgroundJobReceiptPollErrorType.TIMEOUT:
27
+ return 'Background job timed out.';
28
+ }
29
+ }
30
+ }
31
+ exports.BackgroundJobReceiptPollError = BackgroundJobReceiptPollError;
32
+ async function fetchBackgroundJobReceiptAsync(graphqlClient, receiptId) {
33
+ try {
34
+ return [await BackgroundJobReceiptQuery_1.BackgroundJobReceiptQuery.byIdAsync(graphqlClient, receiptId), null];
35
+ }
36
+ catch (error) {
37
+ if (error instanceof core_1.CombinedError) {
38
+ return [null, error];
39
+ }
40
+ throw error;
41
+ }
42
+ }
43
+ async function pollForBackgroundJobReceiptAsync(graphqlClient, backgroundJobReceipt, options) {
44
+ return await new Promise((resolve, reject) => {
45
+ let numChecks = 0;
46
+ const intervalHandle = (0, set_interval_async_1.setIntervalAsync)(async function pollForDeletionFinishedAsync() {
47
+ function failBackgroundDeletion(error) {
48
+ void (0, set_interval_async_1.clearIntervalAsync)(intervalHandle);
49
+ reject(error);
50
+ }
51
+ const [receipt, error] = await fetchBackgroundJobReceiptAsync(graphqlClient, backgroundJobReceipt.id);
52
+ if (!receipt) {
53
+ if (error instanceof core_1.CombinedError) {
54
+ const errorResult = options?.onBackgroundJobReceiptPollError?.(error);
55
+ if (errorResult?.errorIndicatesSuccess) {
56
+ void (0, set_interval_async_1.clearIntervalAsync)(intervalHandle);
57
+ resolve(null);
58
+ return;
59
+ }
60
+ }
61
+ failBackgroundDeletion(new BackgroundJobReceiptPollError({
62
+ errorType: BackgroundJobReceiptPollErrorType.NULL_RECEIPT,
63
+ }));
64
+ return;
65
+ }
66
+ // job failed and will not retry
67
+ if (receipt.state === generated_1.BackgroundJobState.Failure && !receipt.willRetry) {
68
+ failBackgroundDeletion(new BackgroundJobReceiptPollError({
69
+ errorType: BackgroundJobReceiptPollErrorType.JOB_FAILED_NO_WILL_RETRY,
70
+ receiptErrorMessage: receipt.errorMessage,
71
+ }));
72
+ return;
73
+ }
74
+ // all else fails, stop polling after 90 checks. This should only happen if there's an
75
+ // issue with receipts not setting `willRetry` to false when they fail within a reasonable
76
+ // amount of time.
77
+ if (numChecks > 90) {
78
+ failBackgroundDeletion(new BackgroundJobReceiptPollError({
79
+ errorType: BackgroundJobReceiptPollErrorType.TIMEOUT,
80
+ }));
81
+ return;
82
+ }
83
+ if (receipt.state === generated_1.BackgroundJobState.Success) {
84
+ void (0, set_interval_async_1.clearIntervalAsync)(intervalHandle);
85
+ resolve(receipt);
86
+ return;
87
+ }
88
+ numChecks++;
89
+ }, options?.pollInterval ?? 1000);
90
+ });
91
+ }
92
+ exports.pollForBackgroundJobReceiptAsync = pollForBackgroundJobReceiptAsync;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "16.1.0",
2
+ "version": "16.2.0",
3
3
  "commands": {
4
4
  "analytics": {
5
5
  "id": "analytics",
@@ -2781,6 +2781,7 @@
2781
2781
  "$ eas fingerprint:compare <FINGERPRINT-HASH> \t # Compare fingerprint against local directory",
2782
2782
  "$ eas fingerprint:compare <FINGERPRINT-HASH-1> <FINGERPRINT-HASH-2> \t # Compare provided fingerprints",
2783
2783
  "$ eas fingerprint:compare --build-id <BUILD-ID> \t # Compare fingerprint from build against local directory",
2784
+ "$ eas fingerprint:compare --build-id <BUILD-ID> --environment production \t # Compare fingerprint from build against local directory with the \"production\" environment",
2784
2785
  "$ eas fingerprint:compare --build-id <BUILD-ID-1> --build-id <BUILD-ID-2>\t # Compare fingerprint from a build against another build",
2785
2786
  "$ eas fingerprint:compare --build-id <BUILD-ID> --update-id <UPDATE-ID>\t # Compare fingerprint from build against fingerprint from update",
2786
2787
  "$ eas fingerprint:compare <FINGERPRINT-HASH> --update-id <UPDATE-ID> \t # Compare fingerprint from update against provided fingerprint"
@@ -2810,6 +2811,18 @@
2810
2811
  "description": "Open the fingerprint comparison in the browser",
2811
2812
  "allowNo": false
2812
2813
  },
2814
+ "environment": {
2815
+ "name": "environment",
2816
+ "type": "option",
2817
+ "description": "If generating a fingerprint from the local directory, use the specified environment.",
2818
+ "helpValue": "(development|preview|production)",
2819
+ "multiple": false,
2820
+ "options": [
2821
+ "development",
2822
+ "preview",
2823
+ "production"
2824
+ ]
2825
+ },
2813
2826
  "json": {
2814
2827
  "name": "json",
2815
2828
  "type": "boolean",
@@ -2842,7 +2855,8 @@
2842
2855
  "projectId": {},
2843
2856
  "loggedIn": {},
2844
2857
  "privateProjectConfig": {},
2845
- "vcsClient": {}
2858
+ "vcsClient": {},
2859
+ "getServerSideEnvironmentVariablesAsync": {}
2846
2860
  }
2847
2861
  },
2848
2862
  "fingerprint:generate": {
@@ -2852,11 +2866,11 @@
2852
2866
  "pluginName": "eas-cli",
2853
2867
  "pluginAlias": "eas-cli",
2854
2868
  "pluginType": "core",
2855
- "hidden": true,
2856
2869
  "aliases": [],
2857
2870
  "examples": [
2858
2871
  "$ eas fingerprint:generate \t # Generate fingerprint in interactive mode",
2859
- "$ eas fingerprint:generate --profile preview \t # Generate a fingerprint using the \"preview\" build profile",
2872
+ "$ eas fingerprint:generate --build-profile preview \t # Generate a fingerprint using the \"preview\" build profile",
2873
+ "$ eas fingerprint:generate --environment preview \t # Generate a fingerprint using the \"preview\" environment",
2860
2874
  "$ eas fingerprint:generate --json --non-interactive --platform android \t # Output fingerprint json to stdout"
2861
2875
  ],
2862
2876
  "flags": {
@@ -2881,6 +2895,19 @@
2881
2895
  "development",
2882
2896
  "preview",
2883
2897
  "production"
2898
+ ],
2899
+ "exclusive": [
2900
+ "build-profile"
2901
+ ]
2902
+ },
2903
+ "build-profile": {
2904
+ "name": "build-profile",
2905
+ "type": "option",
2906
+ "char": "e",
2907
+ "description": "Name of the build profile from eas.json.",
2908
+ "multiple": false,
2909
+ "exclusive": [
2910
+ "environment"
2884
2911
  ]
2885
2912
  },
2886
2913
  "json": {
@@ -2905,7 +2932,9 @@
2905
2932
  "loggedIn": {},
2906
2933
  "privateProjectConfig": {},
2907
2934
  "vcsClient": {},
2908
- "getServerSideEnvironmentVariablesAsync": {}
2935
+ "getServerSideEnvironmentVariablesAsync": {},
2936
+ "getDynamicPublicProjectConfigAsync": {},
2937
+ "getDynamicPrivateProjectConfigAsync": {}
2909
2938
  }
2910
2939
  },
2911
2940
  "metadata:lint": {