eas-cli 0.34.1 → 0.35.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 (90) hide show
  1. package/README.md +27 -27
  2. package/build/api.js +3 -3
  3. package/build/build/utils/formatBuild.js +1 -9
  4. package/build/build/utils/url.js +1 -1
  5. package/build/commands/build/index.js +12 -3
  6. package/build/commands/secret/delete.js +1 -1
  7. package/build/credentials/android/AndroidCredentialsProvider.js +2 -2
  8. package/build/credentials/android/actions/{SetupBuildCredentials.d.ts → SetUpBuildCredentials.d.ts} +1 -1
  9. package/build/credentials/android/actions/{SetupBuildCredentials.js → SetUpBuildCredentials.js} +3 -3
  10. package/build/credentials/android/actions/{SetupBuildCredentialsFromCredentialsJson.d.ts → SetUpBuildCredentialsFromCredentialsJson.d.ts} +1 -1
  11. package/build/credentials/android/actions/{SetupBuildCredentialsFromCredentialsJson.js → SetUpBuildCredentialsFromCredentialsJson.js} +3 -3
  12. package/build/credentials/android/actions/{SetupGoogleServiceAccountKey.d.ts → SetUpGoogleServiceAccountKey.d.ts} +1 -1
  13. package/build/credentials/android/actions/{SetupGoogleServiceAccountKey.js → SetUpGoogleServiceAccountKey.js} +3 -3
  14. package/build/credentials/errors.d.ts +4 -0
  15. package/build/credentials/errors.js +8 -1
  16. package/build/credentials/ios/IosCredentialsProvider.js +4 -4
  17. package/build/credentials/ios/actions/AscApiKeyUtils.d.ts +17 -1
  18. package/build/credentials/ios/actions/AscApiKeyUtils.js +156 -23
  19. package/build/credentials/ios/actions/AssignAscApiKey.d.ts +9 -0
  20. package/build/credentials/ios/actions/AssignAscApiKey.js +29 -0
  21. package/build/credentials/ios/actions/CreateAscApiKey.d.ts +9 -0
  22. package/build/credentials/ios/actions/CreateAscApiKey.js +21 -0
  23. package/build/credentials/ios/actions/DistributionCertificateUtils.js +1 -1
  24. package/build/credentials/ios/actions/PushKeyUtils.js +1 -1
  25. package/build/credentials/ios/actions/RemoveAscApiKey.d.ts +14 -0
  26. package/build/credentials/ios/actions/RemoveAscApiKey.js +55 -0
  27. package/build/credentials/ios/actions/{SetupAdhocProvisioningProfile.d.ts → SetUpAdhocProvisioningProfile.d.ts} +1 -1
  28. package/build/credentials/ios/actions/{SetupAdhocProvisioningProfile.js → SetUpAdhocProvisioningProfile.js} +5 -5
  29. package/build/credentials/ios/actions/SetUpAscApiKey.d.ts +21 -0
  30. package/build/credentials/ios/actions/SetUpAscApiKey.js +114 -0
  31. package/build/credentials/ios/actions/{SetupBuildCredentials.d.ts → SetUpBuildCredentials.d.ts} +1 -1
  32. package/build/credentials/ios/actions/{SetupBuildCredentials.js → SetUpBuildCredentials.js} +5 -5
  33. package/build/credentials/ios/actions/{SetupBuildCredentialsFromCredentialsJson.d.ts → SetUpBuildCredentialsFromCredentialsJson.d.ts} +1 -1
  34. package/build/credentials/ios/actions/{SetupBuildCredentialsFromCredentialsJson.js → SetUpBuildCredentialsFromCredentialsJson.js} +5 -5
  35. package/build/credentials/ios/actions/{SetupDistributionCertificate.d.ts → SetUpDistributionCertificate.d.ts} +1 -1
  36. package/build/credentials/ios/actions/{SetupDistributionCertificate.js → SetUpDistributionCertificate.js} +3 -3
  37. package/build/credentials/ios/actions/{SetupInternalProvisioningProfile.d.ts → SetUpInternalProvisioningProfile.d.ts} +1 -1
  38. package/build/credentials/ios/actions/{SetupInternalProvisioningProfile.js → SetUpInternalProvisioningProfile.js} +7 -7
  39. package/build/credentials/ios/actions/{SetupProvisioningProfile.d.ts → SetUpProvisioningProfile.d.ts} +1 -1
  40. package/build/credentials/ios/actions/{SetupProvisioningProfile.js → SetUpProvisioningProfile.js} +5 -5
  41. package/build/credentials/ios/actions/{SetupPushKey.d.ts → SetUpPushKey.d.ts} +1 -1
  42. package/build/credentials/ios/actions/{SetupPushKey.js → SetUpPushKey.js} +3 -3
  43. package/build/credentials/ios/actions/SetUpSubmissionCredentials.d.ts +10 -0
  44. package/build/credentials/ios/actions/SetUpSubmissionCredentials.js +53 -0
  45. package/build/credentials/ios/actions/{SetupTargetBuildCredentials.d.ts → SetUpTargetBuildCredentials.d.ts} +1 -1
  46. package/build/credentials/ios/actions/{SetupTargetBuildCredentials.js → SetUpTargetBuildCredentials.js} +10 -10
  47. package/build/credentials/ios/actions/{SetupTargetBuildCredentialsFromCredentialsJson.d.ts → SetUpTargetBuildCredentialsFromCredentialsJson.d.ts} +1 -1
  48. package/build/credentials/ios/actions/{SetupTargetBuildCredentialsFromCredentialsJson.js → SetUpTargetBuildCredentialsFromCredentialsJson.js} +3 -3
  49. package/build/credentials/ios/api/GraphqlClient.d.ts +8 -2
  50. package/build/credentials/ios/api/GraphqlClient.js +74 -2
  51. package/build/credentials/ios/api/graphql/mutations/AppStoreConnectApiKeyMutation.d.ts +5 -0
  52. package/build/credentials/ios/api/graphql/mutations/AppStoreConnectApiKeyMutation.js +54 -0
  53. package/build/credentials/ios/api/graphql/mutations/IosAppCredentialsMutation.d.ts +1 -0
  54. package/build/credentials/ios/api/graphql/mutations/IosAppCredentialsMutation.js +25 -0
  55. package/build/credentials/ios/api/graphql/queries/AppStoreConnectApiKeyQuery.d.ts +4 -0
  56. package/build/credentials/ios/api/graphql/queries/AppStoreConnectApiKeyQuery.js +33 -0
  57. package/build/credentials/ios/appstore/AppStoreApi.d.ts +1 -1
  58. package/build/credentials/ios/appstore/Credentials.types.d.ts +1 -0
  59. package/build/credentials/ios/appstore/ascApiKey.d.ts +1 -1
  60. package/build/credentials/ios/appstore/ascApiKey.js +22 -12
  61. package/build/credentials/ios/credentials.d.ts +2 -1
  62. package/build/credentials/ios/credentials.js +8 -3
  63. package/build/credentials/ios/validators/validateAscApiKey.d.ts +5 -0
  64. package/build/credentials/ios/validators/validateAscApiKey.js +21 -0
  65. package/build/credentials/manager/Actions.d.ts +20 -15
  66. package/build/credentials/manager/Actions.js +20 -15
  67. package/build/credentials/manager/AndroidActions.js +3 -3
  68. package/build/credentials/manager/IosActions.d.ts +1 -0
  69. package/build/credentials/manager/IosActions.js +40 -5
  70. package/build/credentials/manager/ManageAndroid.js +6 -6
  71. package/build/credentials/manager/ManageIos.js +53 -14
  72. package/build/credentials/utils/promptForCredentials.d.ts +2 -1
  73. package/build/credentials/utils/promptForCredentials.js +3 -2
  74. package/build/graphql/client.js +1 -1
  75. package/build/graphql/generated.d.ts +64 -2
  76. package/build/graphql/types/Build.js +1 -6
  77. package/build/submit/ArchiveSource.js +2 -1
  78. package/build/submit/android/ServiceAccountSource.js +2 -2
  79. package/build/submit/ios/AppSpecificPasswordSource.d.ts +2 -6
  80. package/build/submit/ios/AppSpecificPasswordSource.js +0 -18
  81. package/build/submit/ios/AscApiKeySource.d.ts +9 -3
  82. package/build/submit/ios/AscApiKeySource.js +10 -10
  83. package/build/submit/ios/CredentialsServiceSource.d.ts +14 -0
  84. package/build/submit/ios/CredentialsServiceSource.js +46 -0
  85. package/build/submit/ios/IosSubmitCommand.js +22 -14
  86. package/build/submit/ios/IosSubmitter.d.ts +3 -0
  87. package/build/submit/ios/IosSubmitter.js +29 -19
  88. package/build/submit/utils/errors.js +2 -0
  89. package/oclif.manifest.json +1 -1
  90. package/package.json +4 -4
@@ -3416,6 +3416,35 @@ export declare type GoogleServiceAccountKeyByAccountQuery = ({
3416
3416
  });
3417
3417
  });
3418
3418
  });
3419
+ export declare type CreateAppStoreConnectApiKeyMutationVariables = Exact<{
3420
+ appStoreConnectApiKeyInput: AppStoreConnectApiKeyInput;
3421
+ accountId: Scalars['ID'];
3422
+ }>;
3423
+ export declare type CreateAppStoreConnectApiKeyMutation = ({
3424
+ __typename?: 'RootMutation';
3425
+ } & {
3426
+ appStoreConnectApiKey: ({
3427
+ __typename?: 'AppStoreConnectApiKeyMutation';
3428
+ } & {
3429
+ createAppStoreConnectApiKey: ({
3430
+ __typename?: 'AppStoreConnectApiKey';
3431
+ } & Pick<AppStoreConnectApiKey, 'id'> & AppStoreConnectApiKeyFragment);
3432
+ });
3433
+ });
3434
+ export declare type DeleteAppStoreConnectApiKeyMutationVariables = Exact<{
3435
+ appStoreConnectApiKeyId: Scalars['ID'];
3436
+ }>;
3437
+ export declare type DeleteAppStoreConnectApiKeyMutation = ({
3438
+ __typename?: 'RootMutation';
3439
+ } & {
3440
+ appStoreConnectApiKey: ({
3441
+ __typename?: 'AppStoreConnectApiKeyMutation';
3442
+ } & {
3443
+ deleteAppStoreConnectApiKey: ({
3444
+ __typename?: 'deleteAppStoreConnectApiKeyResult';
3445
+ } & Pick<DeleteAppStoreConnectApiKeyResult, 'id'>);
3446
+ });
3447
+ });
3419
3448
  export declare type CreateAppleAppIdentifierMutationVariables = Exact<{
3420
3449
  appleAppIdentifierInput: AppleAppIdentifierInput;
3421
3450
  accountId: Scalars['ID'];
@@ -3671,6 +3700,21 @@ export declare type SetPushKeyMutation = ({
3671
3700
  } & Pick<IosAppCredentials, 'id'> & CommonIosAppCredentialsFragment);
3672
3701
  });
3673
3702
  });
3703
+ export declare type SetAppStoreConnectApiKeyForSubmissionsMutationVariables = Exact<{
3704
+ iosAppCredentialsId: Scalars['ID'];
3705
+ ascApiKeyId: Scalars['ID'];
3706
+ }>;
3707
+ export declare type SetAppStoreConnectApiKeyForSubmissionsMutation = ({
3708
+ __typename?: 'RootMutation';
3709
+ } & {
3710
+ iosAppCredentials: ({
3711
+ __typename?: 'IosAppCredentialsMutation';
3712
+ } & {
3713
+ setAppStoreConnectApiKeyForSubmissions: ({
3714
+ __typename?: 'IosAppCredentials';
3715
+ } & Pick<IosAppCredentials, 'id'> & CommonIosAppCredentialsFragment);
3716
+ });
3717
+ });
3674
3718
  export declare type AppByFullNameQueryVariables = Exact<{
3675
3719
  fullName: Scalars['String'];
3676
3720
  }>;
@@ -3685,6 +3729,24 @@ export declare type AppByFullNameQuery = ({
3685
3729
  } & Pick<App, 'id'> & AppFragment);
3686
3730
  })>;
3687
3731
  });
3732
+ export declare type AppStoreConnectApiKeyByAccountQueryVariables = Exact<{
3733
+ accountName: Scalars['String'];
3734
+ }>;
3735
+ export declare type AppStoreConnectApiKeyByAccountQuery = ({
3736
+ __typename?: 'RootQuery';
3737
+ } & {
3738
+ account: ({
3739
+ __typename?: 'AccountQuery';
3740
+ } & {
3741
+ byName: ({
3742
+ __typename?: 'Account';
3743
+ } & Pick<Account, 'id'> & {
3744
+ appStoreConnectApiKeys: Array<({
3745
+ __typename?: 'AppStoreConnectApiKey';
3746
+ } & Pick<AppStoreConnectApiKey, 'id'> & AppStoreConnectApiKeyFragment)>;
3747
+ });
3748
+ });
3749
+ });
3688
3750
  export declare type AppleAppIdentifierByBundleIdQueryVariables = Exact<{
3689
3751
  accountName: Scalars['String'];
3690
3752
  bundleIdentifier: Scalars['String'];
@@ -4410,9 +4472,9 @@ export declare type BuildFragment = ({
4410
4472
  } & Pick<BuildArtifacts, 'buildUrl' | 'xcodeBuildLogsUrl'>)>;
4411
4473
  initiatingActor?: Maybe<({
4412
4474
  __typename: 'User';
4413
- } & Pick<User, 'username' | 'id'>) | ({
4475
+ } & Pick<User, 'id' | 'displayName'>) | ({
4414
4476
  __typename: 'Robot';
4415
- } & Pick<Robot, 'firstName' | 'id'>)>;
4477
+ } & Pick<Robot, 'id' | 'displayName'>)>;
4416
4478
  project: ({
4417
4479
  __typename: 'Snack';
4418
4480
  } & Pick<Snack, 'id' | 'name'>) | ({
@@ -20,12 +20,7 @@ exports.BuildFragmentNode = (0, graphql_tag_1.default) `
20
20
  initiatingActor {
21
21
  __typename
22
22
  id
23
- ... on User {
24
- username
25
- }
26
- ... on Robot {
27
- firstName
28
- }
23
+ displayName
29
24
  }
30
25
  project {
31
26
  __typename
@@ -188,7 +188,7 @@ async function handleBuildListSourceAsync(source) {
188
188
  }
189
189
  }
190
190
  function formatBuildChoice(build, expiryDate) {
191
- const { id, platform, updatedAt, appVersion, sdkVersion, runtimeVersion, buildProfile, appBuildVersion, releaseChannel, } = build;
191
+ const { id, platform, updatedAt, appVersion, sdkVersion, runtimeVersion, buildProfile, appBuildVersion, releaseChannel, initiatingActor, } = build;
192
192
  const formatValue = (field) => field ? chalk_1.default.bold(field) : chalk_1.default.dim('Unknown');
193
193
  const buildDate = new Date(updatedAt);
194
194
  const maybeRuntimeVersion = runtimeVersion ? `Runtime: ${formatValue(runtimeVersion)}` : null;
@@ -204,6 +204,7 @@ function formatBuildChoice(build, expiryDate) {
204
204
  .filter(it => it != null)
205
205
  .join(', '),
206
206
  `\tProfile: ${formatValue(buildProfile)}, Release channel: ${formatValue(releaseChannel)}`,
207
+ `\tAuthored by: ${formatValue(initiatingActor === null || initiatingActor === void 0 ? void 0 : initiatingActor.displayName)}`,
207
208
  ].join('\n');
208
209
  return {
209
210
  title,
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
6
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
7
7
  const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
8
- const SetupGoogleServiceAccountKey_1 = require("../../credentials/android/actions/SetupGoogleServiceAccountKey");
8
+ const SetUpGoogleServiceAccountKey_1 = require("../../credentials/android/actions/SetUpGoogleServiceAccountKey");
9
9
  const googleServiceAccountKey_1 = require("../../credentials/android/utils/googleServiceAccountKey");
10
10
  const log_1 = (0, tslib_1.__importStar)(require("../../log"));
11
11
  const prompts_1 = require("../../prompts");
@@ -56,7 +56,7 @@ async function getServiceAccountFromCredentialsServiceAsync(ctx, androidApplicat
56
56
  projectName: ctx.projectName,
57
57
  androidApplicationIdentifier,
58
58
  };
59
- const setupGoogleServiceAccountKeyAction = new SetupGoogleServiceAccountKey_1.SetupGoogleServiceAccountKey(appLookupParams);
59
+ const setupGoogleServiceAccountKeyAction = new SetUpGoogleServiceAccountKey_1.SetUpGoogleServiceAccountKey(appLookupParams);
60
60
  const androidAppCredentials = await setupGoogleServiceAccountKeyAction.runAsync(ctx.credentialsCtx);
61
61
  const googleServiceAccountKey = (0, nullthrows_1.default)(androidAppCredentials.googleServiceAccountKeyForSubmissions, 'Credentials Service must provide a valid GoogleServiceAccountKey');
62
62
  return {
@@ -1,6 +1,5 @@
1
1
  export declare enum AppSpecificPasswordSourceType {
2
- userDefined = 0,
3
- prompt = 1
2
+ userDefined = 0
4
3
  }
5
4
  interface AppSpecificPasswordSourceBase {
6
5
  sourceType: AppSpecificPasswordSourceType;
@@ -9,9 +8,6 @@ interface AppSpecificPasswordUserDefinedSource extends AppSpecificPasswordSource
9
8
  sourceType: AppSpecificPasswordSourceType.userDefined;
10
9
  appSpecificPassword: string;
11
10
  }
12
- interface AppSpecificPasswordPromptSource extends AppSpecificPasswordSourceBase {
13
- sourceType: AppSpecificPasswordSourceType.prompt;
14
- }
15
- export declare type AppSpecificPasswordSource = AppSpecificPasswordUserDefinedSource | AppSpecificPasswordPromptSource;
11
+ export declare type AppSpecificPasswordSource = AppSpecificPasswordUserDefinedSource;
16
12
  export declare function getAppSpecificPasswordAsync(source: AppSpecificPasswordSource): Promise<string>;
17
13
  export {};
@@ -1,33 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAppSpecificPasswordAsync = exports.AppSpecificPasswordSourceType = void 0;
4
- const tslib_1 = require("tslib");
5
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
- const wrap_ansi_1 = (0, tslib_1.__importDefault)(require("wrap-ansi"));
7
- const log_1 = (0, tslib_1.__importStar)(require("../../log"));
8
- const prompts_1 = require("../../prompts");
9
4
  var AppSpecificPasswordSourceType;
10
5
  (function (AppSpecificPasswordSourceType) {
11
6
  AppSpecificPasswordSourceType[AppSpecificPasswordSourceType["userDefined"] = 0] = "userDefined";
12
- AppSpecificPasswordSourceType[AppSpecificPasswordSourceType["prompt"] = 1] = "prompt";
13
7
  })(AppSpecificPasswordSourceType = exports.AppSpecificPasswordSourceType || (exports.AppSpecificPasswordSourceType = {}));
14
8
  async function getAppSpecificPasswordAsync(source) {
15
9
  var _a;
16
10
  if (source.sourceType === AppSpecificPasswordSourceType.userDefined) {
17
11
  return source.appSpecificPassword;
18
12
  }
19
- else if (source.sourceType === AppSpecificPasswordSourceType.prompt) {
20
- log_1.default.addNewLineIfNone();
21
- log_1.default.log((0, wrap_ansi_1.default)(`Please enter your Apple app-specific password. You can also provide it by using the ${chalk_1.default.bold('EXPO_APPLE_APP_SPECIFIC_PASSWORD')} environment variable.`, process.stdout.columns || 80));
22
- log_1.default.log((0, log_1.learnMore)('https://expo.fyi/apple-app-specific-password'));
23
- const { appSpecificPassword } = await (0, prompts_1.promptAsync)({
24
- name: 'appSpecificPassword',
25
- message: 'Your Apple app-specific password:',
26
- type: 'password',
27
- validate: (val) => val !== '' || 'Apple app-specific password cannot be empty!',
28
- });
29
- return appSpecificPassword;
30
- }
31
13
  else {
32
14
  // exhaustive -- should never happen
33
15
  throw new Error(`Unknown app specific password source type "${(_a = source) === null || _a === void 0 ? void 0 : _a.sourceType}"`);
@@ -1,4 +1,6 @@
1
+ import { Platform } from '@expo/eas-build-job';
1
2
  import { AscApiKeyPath, MinimalAscApiKey } from '../../credentials/ios/credentials';
3
+ import { SubmissionContext } from '../context';
2
4
  export declare enum AscApiKeySourceType {
3
5
  path = 0,
4
6
  prompt = 1
@@ -18,11 +20,15 @@ declare type AscApiKeySummary = {
18
20
  source: 'local' | 'EAS servers';
19
21
  path?: string;
20
22
  keyId: string;
23
+ name?: string;
24
+ };
25
+ export declare type AscApiKeyFromExpoServers = {
26
+ ascApiKeyId: string;
21
27
  };
22
28
  export declare type AscApiKeyResult = {
23
- result: MinimalAscApiKey;
29
+ result: MinimalAscApiKey | AscApiKeyFromExpoServers;
24
30
  summary: AscApiKeySummary;
25
31
  };
26
- export declare function getAscApiKeyLocallyAsync(source: AscApiKeySource): Promise<AscApiKeyResult>;
27
- export declare function getAscApiKeyPathAsync(source: AscApiKeySource): Promise<AscApiKeyPath>;
32
+ export declare function getAscApiKeyLocallyAsync(ctx: SubmissionContext<Platform.IOS>, source: AscApiKeySource): Promise<AscApiKeyResult>;
33
+ export declare function getAscApiKeyPathAsync(ctx: SubmissionContext<Platform.IOS>, source: AscApiKeySource): Promise<AscApiKeyPath>;
28
34
  export {};
@@ -11,8 +11,8 @@ var AscApiKeySourceType;
11
11
  AscApiKeySourceType[AscApiKeySourceType["path"] = 0] = "path";
12
12
  AscApiKeySourceType[AscApiKeySourceType["prompt"] = 1] = "prompt";
13
13
  })(AscApiKeySourceType = exports.AscApiKeySourceType || (exports.AscApiKeySourceType = {}));
14
- async function getAscApiKeyLocallyAsync(source) {
15
- const ascApiKeyPath = await getAscApiKeyPathAsync(source);
14
+ async function getAscApiKeyLocallyAsync(ctx, source) {
15
+ const ascApiKeyPath = await getAscApiKeyPathAsync(ctx, source);
16
16
  const { keyP8Path, keyId, issuerId } = ascApiKeyPath;
17
17
  const keyP8 = await fs_extra_1.default.readFile(keyP8Path, 'utf-8');
18
18
  return {
@@ -25,26 +25,26 @@ async function getAscApiKeyLocallyAsync(source) {
25
25
  };
26
26
  }
27
27
  exports.getAscApiKeyLocallyAsync = getAscApiKeyLocallyAsync;
28
- async function getAscApiKeyPathAsync(source) {
28
+ async function getAscApiKeyPathAsync(ctx, source) {
29
29
  switch (source.sourceType) {
30
30
  case AscApiKeySourceType.path:
31
- return await handlePathSourceAsync(source);
31
+ return await handlePathSourceAsync(ctx, source);
32
32
  case AscApiKeySourceType.prompt:
33
- return await handlePromptSourceAsync(source);
33
+ return await handlePromptSourceAsync(ctx, source);
34
34
  }
35
35
  }
36
36
  exports.getAscApiKeyPathAsync = getAscApiKeyPathAsync;
37
- async function handlePathSourceAsync(source) {
37
+ async function handlePathSourceAsync(ctx, source) {
38
38
  const { keyP8Path } = source.path;
39
39
  if (!(await (0, files_1.isExistingFileAsync)(keyP8Path))) {
40
40
  log_1.default.warn(`File ${keyP8Path} doesn't exist.`);
41
- return await getAscApiKeyPathAsync({ sourceType: AscApiKeySourceType.prompt });
41
+ return await getAscApiKeyPathAsync(ctx, { sourceType: AscApiKeySourceType.prompt });
42
42
  }
43
43
  return source.path;
44
44
  }
45
- async function handlePromptSourceAsync(_source) {
46
- const ascApiKeyPath = await (0, AscApiKeyUtils_1.promptForAscApiKeyAsync)();
47
- return await getAscApiKeyPathAsync({
45
+ async function handlePromptSourceAsync(ctx, _source) {
46
+ const ascApiKeyPath = await (0, AscApiKeyUtils_1.promptForAscApiKeyPathAsync)(ctx.credentialsCtx);
47
+ return await getAscApiKeyPathAsync(ctx, {
48
48
  sourceType: AscApiKeySourceType.path,
49
49
  path: ascApiKeyPath,
50
50
  });
@@ -0,0 +1,14 @@
1
+ import { Platform } from '@expo/eas-build-job';
2
+ import { SubmissionContext } from '../context';
3
+ import { AscApiKeyResult } from './AscApiKeySource';
4
+ /**
5
+ * The Credentials Service will either return an ASC Api Key or an App Specific Password
6
+ * When we no longer support the App Specific Password user prompt, refactor this into the AscApiKeySource
7
+ */
8
+ export declare const CREDENTIALS_SERVICE_SOURCE = "CREDENTIALS_SERVICE_SOURCE";
9
+ export declare type CredentialsServiceSource = typeof CREDENTIALS_SERVICE_SOURCE;
10
+ export declare function getFromCredentialsServiceAsync(ctx: SubmissionContext<Platform.IOS>): Promise<{
11
+ appSpecificPassword: string;
12
+ } | {
13
+ ascApiKeyResult: AscApiKeyResult;
14
+ }>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFromCredentialsServiceAsync = exports.CREDENTIALS_SERVICE_SOURCE = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
6
+ const SetUpSubmissionCredentials_1 = require("../../credentials/ios/actions/SetUpSubmissionCredentials");
7
+ const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
8
+ const bundleIdentifier_1 = require("../../project/ios/bundleIdentifier");
9
+ const Account_1 = require("../../user/Account");
10
+ /**
11
+ * The Credentials Service will either return an ASC Api Key or an App Specific Password
12
+ * When we no longer support the App Specific Password user prompt, refactor this into the AscApiKeySource
13
+ */
14
+ exports.CREDENTIALS_SERVICE_SOURCE = 'CREDENTIALS_SERVICE_SOURCE';
15
+ async function getFromCredentialsServiceAsync(ctx) {
16
+ const bundleIdentifier = await (0, bundleIdentifier_1.getBundleIdentifierAsync)(ctx.projectDir, ctx.exp);
17
+ log_1.default.log(`Looking up credentials configuration for ${bundleIdentifier}...`);
18
+ const appLookupParams = {
19
+ account: (0, nullthrows_1.default)((0, Account_1.findAccountByName)(ctx.user.accounts, ctx.accountName), `You do not have access to account: ${ctx.accountName}`),
20
+ projectName: ctx.projectName,
21
+ bundleIdentifier,
22
+ };
23
+ const setupSubmissionCredentialsAction = new SetUpSubmissionCredentials_1.SetUpSubmissionCredentials(appLookupParams);
24
+ const ascOrAsp = await setupSubmissionCredentialsAction.runAsync(ctx.credentialsCtx);
25
+ const isAppSpecificPassword = typeof ascOrAsp === 'string';
26
+ if (isAppSpecificPassword) {
27
+ return { appSpecificPassword: ascOrAsp };
28
+ }
29
+ else {
30
+ const ascKeyForSubmissions = (0, nullthrows_1.default)(ascOrAsp.appStoreConnectApiKeyForSubmissions, `An EAS Submit ASC Api Key could not be found for ${ascOrAsp.appleAppIdentifier.bundleIdentifier}`);
31
+ const { id, keyIdentifier, name } = ascKeyForSubmissions;
32
+ return {
33
+ ascApiKeyResult: {
34
+ result: {
35
+ ascApiKeyId: id,
36
+ },
37
+ summary: {
38
+ source: 'EAS servers',
39
+ keyId: keyIdentifier,
40
+ name: name !== null && name !== void 0 ? name : undefined,
41
+ },
42
+ },
43
+ };
44
+ }
45
+ }
46
+ exports.getFromCredentialsServiceAsync = getFromCredentialsServiceAsync;
@@ -14,6 +14,7 @@ const commons_1 = require("../commons");
14
14
  const AppProduce_1 = require("./AppProduce");
15
15
  const AppSpecificPasswordSource_1 = require("./AppSpecificPasswordSource");
16
16
  const AscApiKeySource_1 = require("./AscApiKeySource");
17
+ const CredentialsServiceSource_1 = require("./CredentialsServiceSource");
17
18
  const IosSubmitter_1 = (0, tslib_1.__importDefault)(require("./IosSubmitter"));
18
19
  class IosSubmitCommand {
19
20
  constructor(ctx) {
@@ -26,15 +27,20 @@ class IosSubmitCommand {
26
27
  return await submitter.submitAsync();
27
28
  }
28
29
  async resolveCredentialSubmissionOptionsAsync() {
29
- // Fall back to app specific password if no ascApiKey defined
30
30
  const ascApiKeySource = this.resolveAscApiKeySource();
31
- const shouldUseAppSpecificPassword = !ascApiKeySource.ok && ascApiKeySource.enforceError() instanceof errors_1.MissingCredentialsError;
32
- if (shouldUseAppSpecificPassword) {
33
- return { appSpecificPasswordSource: this.resolveAppSpecificPasswordSource() };
34
- }
35
- else {
31
+ const shouldSkipAscApiKeySource = !ascApiKeySource.ok && ascApiKeySource.enforceError() instanceof errors_1.MissingCredentialsError;
32
+ if (!shouldSkipAscApiKeySource) {
36
33
  return { ascApiKeySource };
37
34
  }
35
+ const appSpecificPasswordSource = this.resolveAppSpecificPasswordSource();
36
+ const shouldSkipAppSpecificPasswordSource = !appSpecificPasswordSource.ok &&
37
+ appSpecificPasswordSource.enforceError() instanceof errors_1.MissingCredentialsError;
38
+ if (!shouldSkipAppSpecificPasswordSource) {
39
+ return { appSpecificPasswordSource: this.resolveAppSpecificPasswordSource() };
40
+ }
41
+ return {
42
+ credentialsServiceSource: (0, results_1.result)(CredentialsServiceSource_1.CREDENTIALS_SERVICE_SOURCE),
43
+ };
38
44
  }
39
45
  async resolveSubmissionOptionsAsync() {
40
46
  const archiveSource = this.resolveArchiveSource();
@@ -43,12 +49,16 @@ class IosSubmitCommand {
43
49
  ? credentialsSource.appSpecificPasswordSource
44
50
  : null;
45
51
  const maybeAscApiKeySource = 'ascApiKeySource' in credentialsSource ? credentialsSource.ascApiKeySource : null;
52
+ const maybeCredentialsServiceSource = 'credentialsServiceSource' in credentialsSource
53
+ ? credentialsSource.credentialsServiceSource
54
+ : null;
46
55
  const ascAppIdentifier = await this.resolveAscAppIdentifierAsync();
47
56
  const appleIdUsername = await this.resolveAppleIdUsernameAsync();
48
57
  const errored = [
49
58
  archiveSource,
50
59
  ...(maybeAppSpecificPasswordSource ? [maybeAppSpecificPasswordSource] : []),
51
60
  ...(maybeAscApiKeySource ? [maybeAscApiKeySource] : []),
61
+ ...(maybeCredentialsServiceSource ? [maybeCredentialsServiceSource] : []),
52
62
  ascAppIdentifier,
53
63
  appleIdUsername,
54
64
  ].filter(r => !r.ok);
@@ -72,6 +82,11 @@ class IosSubmitCommand {
72
82
  ascApiKeySource: maybeAscApiKeySource.enforceValue(),
73
83
  }
74
84
  : null),
85
+ ...(maybeCredentialsServiceSource
86
+ ? {
87
+ credentialsServiceSource: maybeCredentialsServiceSource.enforceValue(),
88
+ }
89
+ : null),
75
90
  };
76
91
  }
77
92
  resolveAppSpecificPasswordSource() {
@@ -82,14 +97,7 @@ class IosSubmitCommand {
82
97
  appSpecificPassword: envAppSpecificPassword,
83
98
  });
84
99
  }
85
- else if (this.ctx.nonInteractive) {
86
- return (0, results_1.result)(new Error('Set the EXPO_APPLE_APP_SPECIFIC_PASSWORD environment variable.'));
87
- }
88
- else {
89
- return (0, results_1.result)({
90
- sourceType: AppSpecificPasswordSource_1.AppSpecificPasswordSourceType.prompt,
91
- });
92
- }
100
+ return (0, results_1.result)(new errors_1.MissingCredentialsError('The EXPO_APPLE_APP_SPECIFIC_PASSWORD environment variable must be set.'));
93
101
  }
94
102
  resolveAscApiKeySource() {
95
103
  const { ascApiKeyPath, ascApiKeyIssuerId, ascApiKeyId } = this.ctx.profile;
@@ -4,16 +4,19 @@ import { ArchiveSource } from '../ArchiveSource';
4
4
  import BaseSubmitter, { SubmissionInput } from '../BaseSubmitter';
5
5
  import { AppSpecificPasswordSource } from './AppSpecificPasswordSource';
6
6
  import { AscApiKeySource } from './AscApiKeySource';
7
+ import { CredentialsServiceSource } from './CredentialsServiceSource';
7
8
  export interface IosSubmissionOptions extends Pick<IosSubmissionConfigInput, 'appleIdUsername' | 'ascAppIdentifier'> {
8
9
  projectId: string;
9
10
  archiveSource: ArchiveSource;
10
11
  appSpecificPasswordSource?: AppSpecificPasswordSource;
11
12
  ascApiKeySource?: AscApiKeySource;
13
+ credentialsServiceSource?: CredentialsServiceSource;
12
14
  }
13
15
  export default class IosSubmitter extends BaseSubmitter<Platform.IOS, IosSubmissionOptions> {
14
16
  submitAsync(): Promise<SubmissionFragment>;
15
17
  protected createPlatformSubmissionAsync({ projectId, submissionConfig, buildId, }: SubmissionInput<Platform.IOS>): Promise<SubmissionFragment>;
16
18
  private resolveSourceOptionsAsync;
17
19
  private formatSubmissionConfigAsync;
20
+ private formatAscApiKeyResult;
18
21
  private prepareSummaryData;
19
22
  }
@@ -9,6 +9,7 @@ const BaseSubmitter_1 = (0, tslib_1.__importDefault)(require("../BaseSubmitter")
9
9
  const summary_1 = require("../utils/summary");
10
10
  const AppSpecificPasswordSource_1 = require("./AppSpecificPasswordSource");
11
11
  const AscApiKeySource_1 = require("./AscApiKeySource");
12
+ const CredentialsServiceSource_1 = require("./CredentialsServiceSource");
12
13
  class IosSubmitter extends BaseSubmitter_1.default {
13
14
  async submitAsync() {
14
15
  var _a;
@@ -34,12 +35,16 @@ class IosSubmitter extends BaseSubmitter_1.default {
34
35
  ? await (0, AppSpecificPasswordSource_1.getAppSpecificPasswordAsync)(this.options.appSpecificPasswordSource)
35
36
  : null;
36
37
  const maybeAppStoreConnectApiKey = this.options.ascApiKeySource
37
- ? await (0, AscApiKeySource_1.getAscApiKeyLocallyAsync)(this.options.ascApiKeySource)
38
+ ? await (0, AscApiKeySource_1.getAscApiKeyLocallyAsync)(this.ctx, this.options.ascApiKeySource)
39
+ : null;
40
+ const maybeAscOrAspFromCredentialsService = this.options.credentialsServiceSource
41
+ ? await (0, CredentialsServiceSource_1.getFromCredentialsServiceAsync)(this.ctx)
38
42
  : null;
39
43
  return {
40
44
  archive,
41
45
  ...(maybeAppSpecificPassword ? { appSpecificPassword: maybeAppSpecificPassword } : null),
42
46
  ...(maybeAppStoreConnectApiKey ? { ascApiKeyResult: maybeAppStoreConnectApiKey } : null),
47
+ ...(maybeAscOrAspFromCredentialsService ? maybeAscOrAspFromCredentialsService : null),
43
48
  };
44
49
  }
45
50
  async formatSubmissionConfigAsync(options, { archive, appSpecificPassword, ascApiKeyResult }) {
@@ -49,17 +54,20 @@ class IosSubmitter extends BaseSubmitter_1.default {
49
54
  appleIdUsername,
50
55
  archiveUrl: archive.url,
51
56
  appleAppSpecificPassword: appSpecificPassword,
52
- ...((ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result)
53
- ? {
54
- ascApiKey: {
55
- keyP8: ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result.keyP8,
56
- keyIdentifier: ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result.keyId,
57
- issuerIdentifier: ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result.issuerId,
58
- },
59
- }
60
- : null),
57
+ ...((ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result) ? this.formatAscApiKeyResult(ascApiKeyResult.result) : null),
61
58
  };
62
59
  }
60
+ formatAscApiKeyResult(result) {
61
+ return 'ascApiKeyId' in result
62
+ ? { ascApiKeyId: result.ascApiKeyId }
63
+ : {
64
+ ascApiKey: {
65
+ keyP8: result.keyP8,
66
+ keyIdentifier: result.keyId,
67
+ issuerIdentifier: result.issuerId,
68
+ },
69
+ };
70
+ }
63
71
  prepareSummaryData(options, { archive, ascApiKeyResult }) {
64
72
  const { appleIdUsername, ascAppIdentifier, projectId } = options;
65
73
  // structuring order affects table rows order
@@ -67,9 +75,7 @@ class IosSubmitter extends BaseSubmitter_1.default {
67
75
  ascAppIdentifier,
68
76
  appleIdUsername: appleIdUsername !== null && appleIdUsername !== void 0 ? appleIdUsername : undefined,
69
77
  projectId,
70
- ...(ascApiKeyResult
71
- ? { formattedAscApiKey: formatServiceAccountSummary(ascApiKeyResult) }
72
- : null),
78
+ ...(ascApiKeyResult ? { formattedAscApiKey: formatAscApiKeySummary(ascApiKeyResult) } : null),
73
79
  ...(0, summary_1.formatArchiveSourceSummary)(archive),
74
80
  };
75
81
  }
@@ -84,9 +90,17 @@ const SummaryHumanReadableKeys = {
84
90
  formattedBuild: 'Build',
85
91
  formattedAscApiKey: 'App Store Connect Api Key',
86
92
  };
87
- function formatServiceAccountSummary({ summary }) {
88
- const { source, path, keyId } = summary;
93
+ function formatAscApiKeySummary({ summary }) {
94
+ const { source, path, keyId, name } = summary;
89
95
  const fields = [
96
+ {
97
+ label: 'Key Name',
98
+ value: name,
99
+ },
100
+ {
101
+ label: 'Key ID',
102
+ value: keyId,
103
+ },
90
104
  {
91
105
  label: 'Key Source',
92
106
  value: source,
@@ -95,10 +109,6 @@ function formatServiceAccountSummary({ summary }) {
95
109
  label: 'Key Path',
96
110
  value: path,
97
111
  },
98
- {
99
- label: 'Key ID',
100
- value: keyId,
101
- },
102
112
  ];
103
113
  const filteredFields = fields.filter(({ value }) => value !== undefined && value !== null);
104
114
  return ('\n' +
@@ -19,6 +19,7 @@ var SubmissionErrorCode;
19
19
  SubmissionErrorCode["IOS_INVALID_SIGNATURE"] = "SUBMISSION_SERVICE_IOS_INVALID_SIGNATURE";
20
20
  SubmissionErrorCode["IOS_INCORRECT_CREDENTIALS"] = "SUBMISSION_SERVICE_IOS_INVALID_CREDENTIALS";
21
21
  SubmissionErrorCode["IOS_IPAD_INVALID_ORIENTATION"] = "SUBMISSION_SERVICE_IOS_IPAD_INVALID_ORIENTATION";
22
+ SubmissionErrorCode["IOS_APPLE_MAINTENANCE"] = "SUBMISSION_SERVICE_IOS_APPLE_MAINTENANCE";
22
23
  })(SubmissionErrorCode || (SubmissionErrorCode = {}));
23
24
  const SubmissionErrorMessages = {
24
25
  [SubmissionErrorCode.ARCHIVE_DOWNLOAD_NOT_FOUND_ERROR]: "Failed to download the archive file (Response code: 404 Not Found). Please make sure the URL you've provided is correct.",
@@ -50,6 +51,7 @@ const SubmissionErrorMessages = {
50
51
  [SubmissionErrorCode.IOS_IPAD_INVALID_ORIENTATION]: "Your app doesn't support iPad multitasking and has to require full screen.\n" +
51
52
  "If you're submitting a managed Expo project, set the `expo.ios.requireFullScreen` to true in app.json and build the project again.\n" +
52
53
  `${(0, log_1.learnMore)('https://expo.fyi/ipad-requires-fullscreen')}`,
54
+ [SubmissionErrorCode.IOS_APPLE_MAINTENANCE]: 'It looks like Apple servers are undergoing an unscheduled maintenance. Please try again later.',
53
55
  };
54
56
  function printSubmissionError(error) {
55
57
  if (error.errorCode &&