eas-cli 0.34.0 → 0.36.1

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 (125) hide show
  1. package/README.md +27 -27
  2. package/build/analytics/common.d.ts +8 -0
  3. package/build/analytics/common.js +19 -0
  4. package/build/analytics/events.d.ts +43 -0
  5. package/build/analytics/events.js +51 -0
  6. package/build/{analytics.d.ts → analytics/rudderstackClient.d.ts} +0 -0
  7. package/build/{analytics.js → analytics/rudderstackClient.js} +2 -2
  8. package/build/api.js +3 -3
  9. package/build/build/build.js +18 -27
  10. package/build/build/context.d.ts +1 -1
  11. package/build/build/context.js +2 -2
  12. package/build/build/ios/credentials.js +3 -3
  13. package/build/build/local.js +18 -27
  14. package/build/build/types.d.ts +0 -1
  15. package/build/build/utils/devClient.js +6 -3
  16. package/build/build/utils/formatBuild.js +1 -9
  17. package/build/build/utils/url.js +1 -1
  18. package/build/commandUtils/EasCommand.js +4 -4
  19. package/build/commands/build/index.js +14 -5
  20. package/build/commands/secret/delete.js +1 -1
  21. package/build/credentials/android/AndroidCredentialsProvider.js +2 -2
  22. package/build/credentials/android/actions/RemoveFcm.js +4 -4
  23. package/build/credentials/android/actions/{SetupBuildCredentials.d.ts → SetUpBuildCredentials.d.ts} +1 -1
  24. package/build/credentials/android/actions/{SetupBuildCredentials.js → SetUpBuildCredentials.js} +3 -3
  25. package/build/credentials/android/actions/{SetupBuildCredentialsFromCredentialsJson.d.ts → SetUpBuildCredentialsFromCredentialsJson.d.ts} +1 -1
  26. package/build/credentials/android/actions/{SetupBuildCredentialsFromCredentialsJson.js → SetUpBuildCredentialsFromCredentialsJson.js} +3 -3
  27. package/build/credentials/android/actions/{SetupGoogleServiceAccountKey.d.ts → SetUpGoogleServiceAccountKey.d.ts} +1 -1
  28. package/build/credentials/android/actions/{SetupGoogleServiceAccountKey.js → SetUpGoogleServiceAccountKey.js} +3 -3
  29. package/build/credentials/android/utils/keystore.js +67 -32
  30. package/build/credentials/errors.d.ts +4 -0
  31. package/build/credentials/errors.js +8 -1
  32. package/build/credentials/ios/IosCredentialsProvider.js +4 -4
  33. package/build/credentials/ios/actions/AscApiKeyUtils.d.ts +17 -1
  34. package/build/credentials/ios/actions/AscApiKeyUtils.js +158 -24
  35. package/build/credentials/ios/actions/AssignAscApiKey.d.ts +9 -0
  36. package/build/credentials/ios/actions/AssignAscApiKey.js +29 -0
  37. package/build/credentials/ios/actions/CreateAscApiKey.d.ts +9 -0
  38. package/build/credentials/ios/actions/CreateAscApiKey.js +21 -0
  39. package/build/credentials/ios/actions/DistributionCertificateUtils.js +1 -1
  40. package/build/credentials/ios/actions/PushKeyUtils.js +1 -1
  41. package/build/credentials/ios/actions/RemoveAscApiKey.d.ts +14 -0
  42. package/build/credentials/ios/actions/RemoveAscApiKey.js +55 -0
  43. package/build/credentials/ios/actions/{SetupAdhocProvisioningProfile.d.ts → SetUpAdhocProvisioningProfile.d.ts} +1 -1
  44. package/build/credentials/ios/actions/{SetupAdhocProvisioningProfile.js → SetUpAdhocProvisioningProfile.js} +5 -5
  45. package/build/credentials/ios/actions/SetUpAscApiKey.d.ts +21 -0
  46. package/build/credentials/ios/actions/SetUpAscApiKey.js +114 -0
  47. package/build/credentials/ios/actions/{SetupBuildCredentials.d.ts → SetUpBuildCredentials.d.ts} +1 -1
  48. package/build/credentials/ios/actions/{SetupBuildCredentials.js → SetUpBuildCredentials.js} +5 -5
  49. package/build/credentials/ios/actions/{SetupBuildCredentialsFromCredentialsJson.d.ts → SetUpBuildCredentialsFromCredentialsJson.d.ts} +1 -1
  50. package/build/credentials/ios/actions/{SetupBuildCredentialsFromCredentialsJson.js → SetUpBuildCredentialsFromCredentialsJson.js} +5 -5
  51. package/build/credentials/ios/actions/{SetupDistributionCertificate.d.ts → SetUpDistributionCertificate.d.ts} +1 -1
  52. package/build/credentials/ios/actions/{SetupDistributionCertificate.js → SetUpDistributionCertificate.js} +3 -3
  53. package/build/credentials/ios/actions/{SetupInternalProvisioningProfile.d.ts → SetUpInternalProvisioningProfile.d.ts} +1 -1
  54. package/build/credentials/ios/actions/{SetupInternalProvisioningProfile.js → SetUpInternalProvisioningProfile.js} +7 -7
  55. package/build/credentials/ios/actions/{SetupProvisioningProfile.d.ts → SetUpProvisioningProfile.d.ts} +1 -1
  56. package/build/credentials/ios/actions/{SetupProvisioningProfile.js → SetUpProvisioningProfile.js} +5 -5
  57. package/build/credentials/ios/actions/{SetupPushKey.d.ts → SetUpPushKey.d.ts} +1 -1
  58. package/build/credentials/ios/actions/{SetupPushKey.js → SetUpPushKey.js} +3 -3
  59. package/build/credentials/ios/actions/SetUpSubmissionCredentials.d.ts +10 -0
  60. package/build/credentials/ios/actions/SetUpSubmissionCredentials.js +53 -0
  61. package/build/credentials/ios/actions/{SetupTargetBuildCredentials.d.ts → SetUpTargetBuildCredentials.d.ts} +1 -1
  62. package/build/credentials/ios/actions/{SetupTargetBuildCredentials.js → SetUpTargetBuildCredentials.js} +10 -10
  63. package/build/credentials/ios/actions/{SetupTargetBuildCredentialsFromCredentialsJson.d.ts → SetUpTargetBuildCredentialsFromCredentialsJson.d.ts} +1 -1
  64. package/build/credentials/ios/actions/{SetupTargetBuildCredentialsFromCredentialsJson.js → SetUpTargetBuildCredentialsFromCredentialsJson.js} +3 -3
  65. package/build/credentials/ios/api/GraphqlClient.d.ts +8 -2
  66. package/build/credentials/ios/api/GraphqlClient.js +74 -2
  67. package/build/credentials/ios/api/graphql/mutations/AppStoreConnectApiKeyMutation.d.ts +5 -0
  68. package/build/credentials/ios/api/graphql/mutations/AppStoreConnectApiKeyMutation.js +54 -0
  69. package/build/credentials/ios/api/graphql/mutations/IosAppCredentialsMutation.d.ts +1 -0
  70. package/build/credentials/ios/api/graphql/mutations/IosAppCredentialsMutation.js +25 -0
  71. package/build/credentials/ios/api/graphql/queries/AppStoreConnectApiKeyQuery.d.ts +4 -0
  72. package/build/credentials/ios/api/graphql/queries/AppStoreConnectApiKeyQuery.js +33 -0
  73. package/build/credentials/ios/appstore/AppStoreApi.d.ts +1 -1
  74. package/build/credentials/ios/appstore/Credentials.types.d.ts +1 -0
  75. package/build/credentials/ios/appstore/ascApiKey.d.ts +1 -1
  76. package/build/credentials/ios/appstore/ascApiKey.js +11 -1
  77. package/build/credentials/ios/appstore/entitlements.d.ts +2 -2
  78. package/build/credentials/ios/appstore/entitlements.js +20 -10
  79. package/build/credentials/ios/credentials.d.ts +2 -1
  80. package/build/credentials/ios/credentials.js +7 -2
  81. package/build/credentials/ios/utils/printCredentials.js +30 -1
  82. package/build/credentials/ios/validators/validateAscApiKey.d.ts +5 -0
  83. package/build/credentials/ios/validators/validateAscApiKey.js +21 -0
  84. package/build/credentials/manager/Actions.d.ts +20 -15
  85. package/build/credentials/manager/Actions.js +20 -15
  86. package/build/credentials/manager/AndroidActions.js +6 -6
  87. package/build/credentials/manager/IosActions.d.ts +1 -0
  88. package/build/credentials/manager/IosActions.js +40 -5
  89. package/build/credentials/manager/ManageAndroid.js +6 -6
  90. package/build/credentials/manager/ManageIos.js +56 -17
  91. package/build/credentials/utils/promptForCredentials.d.ts +2 -1
  92. package/build/credentials/utils/promptForCredentials.js +3 -2
  93. package/build/graphql/client.js +1 -1
  94. package/build/graphql/generated.d.ts +233 -82
  95. package/build/graphql/mutations/KeystoreGenerationUrlMutation.d.ts +3 -0
  96. package/build/graphql/mutations/KeystoreGenerationUrlMutation.js +23 -0
  97. package/build/graphql/types/Build.js +1 -6
  98. package/build/graphql/types/credentials/AppStoreConnectApiKey.d.ts +1 -0
  99. package/build/graphql/types/credentials/AppStoreConnectApiKey.js +23 -0
  100. package/build/graphql/types/credentials/IosAppCredentials.js +6 -0
  101. package/build/submit/ArchiveSource.js +2 -1
  102. package/build/submit/BaseSubmitter.d.ts +20 -4
  103. package/build/submit/BaseSubmitter.js +34 -1
  104. package/build/submit/android/AndroidSubmitter.d.ts +12 -6
  105. package/build/submit/android/AndroidSubmitter.js +31 -20
  106. package/build/submit/android/ServiceAccountSource.js +2 -2
  107. package/build/submit/context.d.ts +2 -0
  108. package/build/submit/context.js +14 -0
  109. package/build/submit/ios/AppSpecificPasswordSource.d.ts +9 -6
  110. package/build/submit/ios/AppSpecificPasswordSource.js +42 -20
  111. package/build/submit/ios/AscApiKeySource.d.ts +9 -3
  112. package/build/submit/ios/AscApiKeySource.js +10 -10
  113. package/build/submit/ios/CredentialsServiceSource.d.ts +15 -0
  114. package/build/submit/ios/CredentialsServiceSource.js +52 -0
  115. package/build/submit/ios/IosSubmitCommand.d.ts +1 -2
  116. package/build/submit/ios/IosSubmitCommand.js +24 -53
  117. package/build/submit/ios/IosSubmitter.d.ts +20 -7
  118. package/build/submit/ios/IosSubmitter.js +79 -43
  119. package/build/submit/submit.js +13 -4
  120. package/build/submit/utils/errors.js +2 -0
  121. package/build/user/User.js +1 -1
  122. package/oclif.manifest.json +1 -1
  123. package/package.json +6 -6
  124. package/build/build/utils/analytics.d.ts +0 -22
  125. package/build/build/utils/analytics.js +0 -28
@@ -117,13 +117,5 @@ function formatGraphQLBuild(build) {
117
117
  exports.formatGraphQLBuild = formatGraphQLBuild;
118
118
  const getActorName = (build) => {
119
119
  var _a;
120
- if (!build.initiatingActor) {
121
- return 'unknown';
122
- }
123
- else if (build.initiatingActor.__typename === 'User') {
124
- return build.initiatingActor.username;
125
- }
126
- else {
127
- return (_a = build.initiatingActor.firstName) !== null && _a !== void 0 ? _a : 'unknown';
128
- }
120
+ return ((_a = build.initiatingActor) === null || _a === void 0 ? void 0 : _a.displayName) || 'unknown';
129
121
  };
@@ -26,7 +26,7 @@ exports.getArtifactUrl = getArtifactUrl;
26
26
  function getInternalDistributionInstallUrl(build) {
27
27
  var _a;
28
28
  if (build.platform === generated_1.AppPlatform.Ios) {
29
- return `itms-services://?action=download-manifest;url=${(0, api_1.getExpoApiBaseUrl)()}/--/api/v2/projects/${build.project.id}/builds/${build.id}/manifest.plist`;
29
+ return `itms-services://?action=download-manifest;url=${(0, api_1.getExpoApiBaseUrl)()}/v2/projects/${build.project.id}/builds/${build.id}/manifest.plist`;
30
30
  }
31
31
  (0, assert_1.default)((_a = build.artifacts) === null || _a === void 0 ? void 0 : _a.buildUrl, 'buildUrl is missing');
32
32
  return build.artifacts.buildUrl;
@@ -4,7 +4,7 @@ const tslib_1 = require("tslib");
4
4
  const eas_json_1 = require("@expo/eas-json");
5
5
  const command_1 = require("@oclif/command");
6
6
  const semver_1 = (0, tslib_1.__importDefault)(require("semver"));
7
- const analytics_1 = require("../analytics");
7
+ const rudderstackClient_1 = require("../analytics/rudderstackClient");
8
8
  const log_1 = (0, tslib_1.__importDefault)(require("../log"));
9
9
  const projectUtils_1 = require("../project/projectUtils");
10
10
  const User_1 = require("../user/User");
@@ -25,7 +25,7 @@ class EasCommand extends command_1.Command {
25
25
  async run() {
26
26
  var _a;
27
27
  eas_json_1.EasJsonReader.setLog(log_1.default);
28
- await (0, analytics_1.initAsync)();
28
+ await (0, rudderstackClient_1.initAsync)();
29
29
  await this.applyCliConfigAsync();
30
30
  if (this.requiresAuthentication) {
31
31
  const { flags } = this.parse();
@@ -35,7 +35,7 @@ class EasCommand extends command_1.Command {
35
35
  else {
36
36
  await (0, User_1.getUserAsync)();
37
37
  }
38
- (0, analytics_1.logEvent)(analytics_1.AnalyticsEvent.ACTION, {
38
+ (0, rudderstackClient_1.logEvent)(rudderstackClient_1.AnalyticsEvent.ACTION, {
39
39
  // id is assigned by oclif in constructor based on the filepath:
40
40
  // commands/submit === submit, commands/build/list === build:list
41
41
  action: `eas ${this.id}`,
@@ -44,7 +44,7 @@ class EasCommand extends command_1.Command {
44
44
  }
45
45
  // eslint-disable-next-line async-protect/async-suffix
46
46
  async finally(err) {
47
- await (0, analytics_1.flushAsync)();
47
+ await (0, rudderstackClient_1.flushAsync)();
48
48
  return super.finally(err);
49
49
  }
50
50
  async applyCliConfigAsync() {
@@ -154,7 +154,7 @@ class Build extends EasCommand_1.default {
154
154
  wait: flags['wait'],
155
155
  clearCache: flags['clear-cache'],
156
156
  json: flags['json'],
157
- autoSubmit: flags['auto-submit'],
157
+ autoSubmit: flags['auto-submit'] || flags['auto-submit-with-profile'] !== undefined,
158
158
  submitProfile: (_a = flags['auto-submit-with-profile']) !== null && _a !== void 0 ? _a : profile,
159
159
  };
160
160
  }
@@ -276,7 +276,8 @@ Build.flags = {
276
276
  }),
277
277
  };
278
278
  async function handleDeprecatedEasJsonAsync(projectDir, nonInteractive) {
279
- if (!(await fs_extra_1.default.pathExists(eas_json_1.EasJsonReader.formatEasJsonPath(projectDir)))) {
279
+ const easJsonPath = eas_json_1.EasJsonReader.formatEasJsonPath(projectDir);
280
+ if (!(await fs_extra_1.default.pathExists(easJsonPath))) {
280
281
  return;
281
282
  }
282
283
  const easJsonReader = new eas_json_1.EasJsonReader(projectDir);
@@ -291,19 +292,27 @@ async function handleDeprecatedEasJsonAsync(projectDir, nonInteractive) {
291
292
  return;
292
293
  }
293
294
  log_1.default.log(`${chalk_1.default.bold('eas-cli@>=0.34.0 no longer requires that you commit changes to Git before starting a build.')} ${(0, log_1.learnMore)('https://expo.fyi/eas-vcs-workflow')}`);
294
- log_1.default.log(`If you want to continue using the Git integration, you can opt in with ${chalk_1.default.bold('cli.requireCommit')} in ${chalk_1.default.bold('eas.json')} or with the following prompt`);
295
+ log_1.default.log(`If you want to continue using the Git integration, you can opt in with ${chalk_1.default.bold('cli.requireCommit')} in ${chalk_1.default.bold('eas.json')} or with the following prompt.`);
295
296
  log_1.default.newLine();
296
297
  const mode = await (0, prompts_1.selectAsync)('Select your preferred Git integration', [
297
298
  { title: 'Require changes to be committed in Git (old default)', value: 'requireCommit' },
298
299
  { title: 'Allow builds with dirty Git working tree (new default)', value: 'noCommit' },
299
300
  ]);
301
+ if (mode === 'requireCommit') {
302
+ (0, vcs_1.setVcsClient)(new git_1.default());
303
+ await (0, repository_1.ensureRepoIsCleanAsync)(nonInteractive);
304
+ }
300
305
  rawEasJson.cli =
301
306
  mode === 'requireCommit'
302
307
  ? { version: `>= ${easCli_1.easCliVersion}`, requireCommit: true }
303
308
  : { version: `>= ${easCli_1.easCliVersion}` };
304
- await fs_extra_1.default.writeJSON(eas_json_1.EasJsonReader.formatEasJsonPath(projectDir), rawEasJson, { spaces: 2 });
309
+ await fs_extra_1.default.writeJSON(easJsonPath, rawEasJson, { spaces: 2 });
310
+ log_1.default.withTick('Updated eas.json');
305
311
  if (mode === 'requireCommit') {
306
- (0, vcs_1.setVcsClient)(new git_1.default());
312
+ await (0, vcs_1.getVcsClient)().trackFileAsync(easJsonPath);
313
+ await (0, repository_1.reviewAndCommitChangesAsync)('Set cli.requireCommit to true in eas.json', {
314
+ nonInteractive,
315
+ });
307
316
  }
308
317
  }
309
318
  exports.handleDeprecatedEasJsonAsync = handleDeprecatedEasJsonAsync;
@@ -59,7 +59,7 @@ class EnvironmentSecretDelete extends EasCommand_1.default {
59
59
  }
60
60
  exports.default = EnvironmentSecretDelete;
61
61
  EnvironmentSecretDelete.description = `Delete an environment secret by ID.
62
- Unsure where to find the secret's ID? Run ${chalk_1.default.bold('eas secrets:list')}`;
62
+ Unsure where to find the secret's ID? Run ${chalk_1.default.bold('eas secret:list')}`;
63
63
  EnvironmentSecretDelete.flags = {
64
64
  id: command_1.flags.string({
65
65
  description: 'ID of the secret to delete',
@@ -5,7 +5,7 @@ const eas_build_job_1 = require("@expo/eas-build-job");
5
5
  const eas_json_1 = require("@expo/eas-json");
6
6
  const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
7
7
  const credentialsJsonReader = (0, tslib_1.__importStar)(require("../credentialsJson/read"));
8
- const SetupBuildCredentials_1 = require("./actions/SetupBuildCredentials");
8
+ const SetUpBuildCredentials_1 = require("./actions/SetUpBuildCredentials");
9
9
  class AndroidCredentialsProvider {
10
10
  constructor(ctx, options) {
11
11
  this.ctx = ctx;
@@ -21,7 +21,7 @@ class AndroidCredentialsProvider {
21
21
  }
22
22
  }
23
23
  async getRemoteAsync() {
24
- const setupBuildCredentialsAction = new SetupBuildCredentials_1.SetupBuildCredentials({ app: this.options.app });
24
+ const setupBuildCredentialsAction = new SetUpBuildCredentials_1.SetUpBuildCredentials({ app: this.options.app });
25
25
  const buildCredentials = await setupBuildCredentialsAction.runAsync(this.ctx);
26
26
  return this.toAndroidCredentials(buildCredentials);
27
27
  }
@@ -11,23 +11,23 @@ class RemoveFcm {
11
11
  }
12
12
  async runAsync(ctx) {
13
13
  if (ctx.nonInteractive) {
14
- throw new Error("Deleting an FCM Api Key is a destructive operation. Start the CLI without the '--non-interactive' flag to delete the credentials.");
14
+ throw new Error("Deleting an FCM API Key is a destructive operation. Start the CLI without the '--non-interactive' flag to delete the credentials.");
15
15
  }
16
16
  const appCredentials = await ctx.android.getAndroidAppCredentialsWithCommonFieldsAsync(this.app);
17
17
  const fcm = appCredentials === null || appCredentials === void 0 ? void 0 : appCredentials.androidFcm;
18
18
  if (!fcm) {
19
- log_1.default.warn(`There is no valid FCM Api Key defined for ${(0, GraphqlClient_1.formatProjectFullName)(this.app)}, ${this.app.androidApplicationIdentifier}`);
19
+ log_1.default.warn(`There is no valid FCM API Key defined for ${(0, GraphqlClient_1.formatProjectFullName)(this.app)}, ${this.app.androidApplicationIdentifier}`);
20
20
  return;
21
21
  }
22
22
  const confirm = await (0, prompts_1.confirmAsync)({
23
- message: 'Permanently delete the FCM Api Key from Expo servers?',
23
+ message: 'Permanently delete the FCM API Key from Expo servers?',
24
24
  initial: false,
25
25
  });
26
26
  if (!confirm) {
27
27
  return;
28
28
  }
29
29
  await ctx.android.deleteFcmAsync(fcm);
30
- log_1.default.succeed('FCM Api Key removed');
30
+ log_1.default.succeed('FCM API Key removed');
31
31
  }
32
32
  }
33
33
  exports.RemoveFcm = RemoveFcm;
@@ -9,7 +9,7 @@ interface Options {
9
9
  * Sets up Build Credentials for Android
10
10
  * @name: sets up build credentials for the specified configuration. If no name is specified, the default configuration is setup
11
11
  */
12
- export declare class SetupBuildCredentials {
12
+ export declare class SetUpBuildCredentials {
13
13
  private options;
14
14
  constructor(options: Options);
15
15
  runAsync(ctx: CredentialsContext): Promise<AndroidAppBuildCredentialsFragment>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SetupBuildCredentials = void 0;
3
+ exports.SetUpBuildCredentials = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
6
6
  const log_1 = (0, tslib_1.__importDefault)(require("../../../log"));
@@ -12,7 +12,7 @@ const CreateKeystore_1 = require("./CreateKeystore");
12
12
  * Sets up Build Credentials for Android
13
13
  * @name: sets up build credentials for the specified configuration. If no name is specified, the default configuration is setup
14
14
  */
15
- class SetupBuildCredentials {
15
+ class SetUpBuildCredentials {
16
16
  constructor(options) {
17
17
  this.options = options;
18
18
  }
@@ -74,4 +74,4 @@ class SetupBuildCredentials {
74
74
  return null;
75
75
  }
76
76
  }
77
- exports.SetupBuildCredentials = SetupBuildCredentials;
77
+ exports.SetUpBuildCredentials = SetUpBuildCredentials;
@@ -1,7 +1,7 @@
1
1
  import { AndroidAppBuildCredentialsFragment } from '../../../graphql/generated';
2
2
  import { CredentialsContext } from '../../context';
3
3
  import { AppLookupParams } from '../api/GraphqlClient';
4
- export declare class SetupBuildCredentialsFromCredentialsJson {
4
+ export declare class SetUpBuildCredentialsFromCredentialsJson {
5
5
  private app;
6
6
  constructor(app: AppLookupParams);
7
7
  runAsync(ctx: CredentialsContext): Promise<AndroidAppBuildCredentialsFragment | null>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SetupBuildCredentialsFromCredentialsJson = void 0;
3
+ exports.SetUpBuildCredentialsFromCredentialsJson = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const generated_1 = require("../../../graphql/generated");
6
6
  const log_1 = (0, tslib_1.__importDefault)(require("../../../log"));
@@ -9,7 +9,7 @@ const read_1 = require("../../credentialsJson/read");
9
9
  const SelectAndroidBuildCredentials_1 = require("../../manager/SelectAndroidBuildCredentials");
10
10
  const keystoreNew_1 = require("../utils/keystoreNew");
11
11
  const DownloadKeystore_1 = require("./DownloadKeystore");
12
- class SetupBuildCredentialsFromCredentialsJson {
12
+ class SetUpBuildCredentialsFromCredentialsJson {
13
13
  constructor(app) {
14
14
  this.app = app;
15
15
  }
@@ -65,4 +65,4 @@ class SetupBuildCredentialsFromCredentialsJson {
65
65
  return buildCredentials;
66
66
  }
67
67
  }
68
- exports.SetupBuildCredentialsFromCredentialsJson = SetupBuildCredentialsFromCredentialsJson;
68
+ exports.SetUpBuildCredentialsFromCredentialsJson = SetUpBuildCredentialsFromCredentialsJson;
@@ -1,7 +1,7 @@
1
1
  import { CommonAndroidAppCredentialsFragment } from '../../../graphql/generated';
2
2
  import { CredentialsContext } from '../../context';
3
3
  import { AppLookupParams } from '../api/GraphqlClient';
4
- export declare class SetupGoogleServiceAccountKey {
4
+ export declare class SetUpGoogleServiceAccountKey {
5
5
  private app;
6
6
  constructor(app: AppLookupParams);
7
7
  runAsync(ctx: CredentialsContext): Promise<CommonAndroidAppCredentialsFragment>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SetupGoogleServiceAccountKey = void 0;
3
+ exports.SetUpGoogleServiceAccountKey = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
6
6
  const log_1 = (0, tslib_1.__importDefault)(require("../../../log"));
@@ -9,7 +9,7 @@ const errors_1 = require("../../errors");
9
9
  const AssignGoogleServiceAccountKey_1 = require("./AssignGoogleServiceAccountKey");
10
10
  const CreateGoogleServiceAccountKey_1 = require("./CreateGoogleServiceAccountKey");
11
11
  const UseExistingGoogleServiceAccountKey_1 = require("./UseExistingGoogleServiceAccountKey");
12
- class SetupGoogleServiceAccountKey {
12
+ class SetUpGoogleServiceAccountKey {
13
13
  constructor(app) {
14
14
  this.app = app;
15
15
  }
@@ -56,4 +56,4 @@ class SetupGoogleServiceAccountKey {
56
56
  return ((_a = (await new UseExistingGoogleServiceAccountKey_1.UseExistingGoogleServiceAccountKey(this.app.account).runAsync(ctx))) !== null && _a !== void 0 ? _a : (await this.createOrUseExistingKeyAsync(ctx)));
57
57
  }
58
58
  }
59
- exports.SetupGoogleServiceAccountKey = SetupGoogleServiceAccountKey;
59
+ exports.SetUpGoogleServiceAccountKey = SetUpGoogleServiceAccountKey;
@@ -3,32 +3,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateRandomKeystoreAsync = exports.keytoolCommandExistsAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const spawn_async_1 = (0, tslib_1.__importDefault)(require("@expo/spawn-async"));
6
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
7
  const crypto_1 = (0, tslib_1.__importDefault)(require("crypto"));
7
8
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
9
+ // (dsokal) We actually want to use node-fetch but the change is in progress.
10
+ // See https://github.com/expo/eas-cli/issues/32 for context.
11
+ // eslint-disable-next-line no-restricted-imports
12
+ const node_fetch_1 = (0, tslib_1.__importDefault)(require("node-fetch"));
8
13
  const path_1 = (0, tslib_1.__importDefault)(require("path"));
9
14
  const uuid_1 = require("uuid");
10
- const analytics_1 = (0, tslib_1.__importStar)(require("../../../build/utils/analytics"));
15
+ const events_1 = require("../../../analytics/events");
11
16
  const generated_1 = require("../../../graphql/generated");
17
+ const KeystoreGenerationUrlMutation_1 = require("../../../graphql/mutations/KeystoreGenerationUrlMutation");
12
18
  const log_1 = (0, tslib_1.__importDefault)(require("../../../log"));
19
+ const ora_1 = require("../../../ora");
13
20
  const paths_1 = require("../../../utils/paths");
14
21
  async function keytoolCommandExistsAsync() {
15
22
  try {
16
23
  await (0, spawn_async_1.default)('keytool');
24
+ return true;
17
25
  }
18
26
  catch (error) {
19
27
  return false;
20
28
  }
21
- return true;
22
29
  }
23
30
  exports.keytoolCommandExistsAsync = keytoolCommandExistsAsync;
24
- async function ensureKeytoolCommandExistsAsync() {
25
- if (!(await keytoolCommandExistsAsync())) {
26
- log_1.default.error('keytool is required to run this command, make sure you have it installed?');
27
- log_1.default.warn('keytool is a part of OpenJDK: https://openjdk.java.net/');
28
- log_1.default.warn('Also make sure that keytool is in your PATH after installation.');
29
- throw new Error('keytool not found');
30
- }
31
- }
32
31
  var KeystoreCreateStep;
33
32
  (function (KeystoreCreateStep) {
34
33
  KeystoreCreateStep["Attempt"] = "attempt";
@@ -44,17 +43,38 @@ async function generateRandomKeystoreAsync(projectId) {
44
43
  return await createKeystoreAsync(keystoreData, projectId);
45
44
  }
46
45
  exports.generateRandomKeystoreAsync = generateRandomKeystoreAsync;
47
- async function createKeystoreAsync(credentials, projectId) {
48
- analytics_1.default.logEvent(analytics_1.Event.ANDROID_KEYSTORE_CREATE, {
46
+ async function createKeystoreAsync(keystoreParams, projectId) {
47
+ events_1.Analytics.logEvent(events_1.BuildEvent.ANDROID_KEYSTORE_CREATE, {
49
48
  project_id: projectId,
50
49
  step: KeystoreCreateStep.Attempt,
51
50
  type: generated_1.AndroidKeystoreType.Jks,
52
51
  });
53
52
  try {
54
- await ensureKeytoolCommandExistsAsync();
53
+ let keystore;
54
+ let localAttempt = false;
55
+ if (await keytoolCommandExistsAsync()) {
56
+ try {
57
+ localAttempt = true;
58
+ keystore = await createKeystoreLocallyAsync(keystoreParams);
59
+ }
60
+ catch {
61
+ log_1.default.error('Failed to generate keystore locally. Falling back to cloud generation.');
62
+ }
63
+ }
64
+ if (!keystore) {
65
+ keystore = await createKeystoreInCloudAsync(keystoreParams, {
66
+ showKeytoolDetectionMsg: !localAttempt,
67
+ });
68
+ }
69
+ events_1.Analytics.logEvent(events_1.BuildEvent.ANDROID_KEYSTORE_CREATE, {
70
+ project_id: projectId,
71
+ step: KeystoreCreateStep.Success,
72
+ type: generated_1.AndroidKeystoreType.Jks,
73
+ });
74
+ return keystore;
55
75
  }
56
76
  catch (error) {
57
- analytics_1.default.logEvent(analytics_1.Event.ANDROID_KEYSTORE_CREATE, {
77
+ events_1.Analytics.logEvent(events_1.BuildEvent.ANDROID_KEYSTORE_CREATE, {
58
78
  project_id: projectId,
59
79
  step: KeystoreCreateStep.Fail,
60
80
  reason: error.message,
@@ -62,6 +82,8 @@ async function createKeystoreAsync(credentials, projectId) {
62
82
  });
63
83
  throw error;
64
84
  }
85
+ }
86
+ async function createKeystoreLocallyAsync(keystoreParams) {
65
87
  await fs_extra_1.default.mkdirp((0, paths_1.getTmpDirectory)());
66
88
  const keystorePath = path_1.default.join((0, paths_1.getTmpDirectory)(), `${(0, uuid_1.v4)()}-keystore.jks`);
67
89
  try {
@@ -71,13 +93,13 @@ async function createKeystoreAsync(credentials, projectId) {
71
93
  '-storetype',
72
94
  'JKS',
73
95
  '-storepass',
74
- credentials.keystorePassword,
96
+ keystoreParams.keystorePassword,
75
97
  '-keypass',
76
- credentials.keyPassword,
98
+ keystoreParams.keyPassword,
77
99
  '-keystore',
78
100
  keystorePath,
79
101
  '-alias',
80
- credentials.keyAlias,
102
+ keystoreParams.keyAlias,
81
103
  '-keyalg',
82
104
  'RSA',
83
105
  '-keysize',
@@ -87,27 +109,40 @@ async function createKeystoreAsync(credentials, projectId) {
87
109
  '-dname',
88
110
  `CN=,OU=,O=,L=,S=,C=US`,
89
111
  ]);
90
- analytics_1.default.logEvent(analytics_1.Event.ANDROID_KEYSTORE_CREATE, {
91
- project_id: projectId,
92
- step: KeystoreCreateStep.Success,
93
- type: generated_1.AndroidKeystoreType.Jks,
94
- });
95
112
  return {
96
- ...credentials,
113
+ ...keystoreParams,
97
114
  keystore: await fs_extra_1.default.readFile(keystorePath, 'base64'),
98
115
  type: generated_1.AndroidKeystoreType.Jks,
99
116
  };
100
117
  }
101
- catch (error) {
102
- analytics_1.default.logEvent(analytics_1.Event.ANDROID_KEYSTORE_CREATE, {
103
- project_id: projectId,
104
- step: KeystoreCreateStep.Fail,
105
- reason: error.message,
106
- type: generated_1.AndroidKeystoreType.Jks,
107
- });
108
- throw error;
109
- }
110
118
  finally {
111
119
  await fs_extra_1.default.remove(keystorePath);
112
120
  }
113
121
  }
122
+ async function createKeystoreInCloudAsync(keystoreParams, { showKeytoolDetectionMsg = true } = {}) {
123
+ if (showKeytoolDetectionMsg) {
124
+ log_1.default.log(`Detected that you do not have ${chalk_1.default.bold('keytool')} installed locally.`);
125
+ }
126
+ const spinner = (0, ora_1.ora)('Generating keystore in the cloud...').start();
127
+ try {
128
+ const url = await KeystoreGenerationUrlMutation_1.KeystoreGenerationUrlMutation.createKeystoreGenerationUrlAsync();
129
+ const response = await (0, node_fetch_1.default)(url, {
130
+ method: 'POST',
131
+ body: JSON.stringify(keystoreParams),
132
+ headers: { 'Content-Type': 'application/json' },
133
+ });
134
+ const result = await response.json();
135
+ spinner.succeed();
136
+ return {
137
+ type: generated_1.AndroidKeystoreType.Jks,
138
+ keystore: result.keystoreBase64,
139
+ keystorePassword: result.keystorePassword,
140
+ keyAlias: result.keyAlias,
141
+ keyPassword: result.keyPassword,
142
+ };
143
+ }
144
+ catch (err) {
145
+ spinner.fail();
146
+ throw err;
147
+ }
148
+ }
@@ -4,3 +4,7 @@ export declare class MissingCredentialsNonInteractiveError extends Error {
4
4
  export declare class MissingCredentialsError extends Error {
5
5
  constructor(message?: string);
6
6
  }
7
+ export declare class UnsupportedCredentialsChoiceError extends Error {
8
+ choice: string;
9
+ constructor(message: string, choice: string);
10
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MissingCredentialsError = exports.MissingCredentialsNonInteractiveError = void 0;
3
+ exports.UnsupportedCredentialsChoiceError = exports.MissingCredentialsError = exports.MissingCredentialsNonInteractiveError = void 0;
4
4
  class MissingCredentialsNonInteractiveError extends Error {
5
5
  constructor(message) {
6
6
  super(message !== null && message !== void 0 ? message : 'Credentials are not set up. Please run this command again in interactive mode.');
@@ -13,3 +13,10 @@ class MissingCredentialsError extends Error {
13
13
  }
14
14
  }
15
15
  exports.MissingCredentialsError = MissingCredentialsError;
16
+ class UnsupportedCredentialsChoiceError extends Error {
17
+ constructor(message, choice) {
18
+ super(message);
19
+ this.choice = choice;
20
+ }
21
+ }
22
+ exports.UnsupportedCredentialsChoiceError = UnsupportedCredentialsChoiceError;
@@ -9,8 +9,8 @@ const prompts_1 = require("../../prompts");
9
9
  const credentialsJsonReader = (0, tslib_1.__importStar)(require("../credentialsJson/read"));
10
10
  const utils_1 = require("../credentialsJson/utils");
11
11
  const BuildCredentialsUtils_1 = require("./actions/BuildCredentialsUtils");
12
- const SetupBuildCredentials_1 = require("./actions/SetupBuildCredentials");
13
- const SetupPushKey_1 = require("./actions/SetupPushKey");
12
+ const SetUpBuildCredentials_1 = require("./actions/SetUpBuildCredentials");
13
+ const SetUpPushKey_1 = require("./actions/SetUpPushKey");
14
14
  const provisioningProfile_1 = require("./utils/provisioningProfile");
15
15
  class IosCredentialsProvider {
16
16
  constructor(ctx, options) {
@@ -39,7 +39,7 @@ class IosCredentialsProvider {
39
39
  return iosCredentials;
40
40
  }
41
41
  async getRemoteAsync() {
42
- return await new SetupBuildCredentials_1.SetupBuildCredentials({
42
+ return await new SetUpBuildCredentials_1.SetUpBuildCredentials({
43
43
  app: this.options.app,
44
44
  targets: this.options.targets,
45
45
  distribution: this.options.distribution,
@@ -58,7 +58,7 @@ class IosCredentialsProvider {
58
58
  bundleIdentifier: applicationTarget.bundleIdentifier,
59
59
  parentBundleIdentifier: applicationTarget.parentBundleIdentifier,
60
60
  };
61
- const setupPushKeyAction = new SetupPushKey_1.SetupPushKey(appLookupParams);
61
+ const setupPushKeyAction = new SetUpPushKey_1.SetUpPushKey(appLookupParams);
62
62
  const isPushKeySetup = await setupPushKeyAction.isPushKeySetupAsync(ctx);
63
63
  if (isPushKeySetup) {
64
64
  log_1.default.succeed(`Push Notifications setup for ${app.projectName}: ${applicationTarget.bundleIdentifier}`);
@@ -1,5 +1,21 @@
1
+ import { AppStoreConnectApiKeyFragment } from '../../../graphql/generated';
2
+ import { Account } from '../../../user/Account';
3
+ import { CredentialsContext } from '../../context';
1
4
  import { AscApiKey } from '../appstore/Credentials.types';
2
5
  import { AscApiKeyPath, MinimalAscApiKey } from '../credentials';
3
- export declare function promptForAscApiKeyAsync(): Promise<AscApiKeyPath>;
6
+ export declare enum AppStoreApiKeyPurpose {
7
+ SUBMISSION_SERVICE = "EAS Submit"
8
+ }
9
+ export declare function promptForAscApiKeyPathAsync(ctx: CredentialsContext): Promise<AscApiKeyPath>;
4
10
  export declare function promptForIssuerIdAsync(): Promise<string>;
5
11
  export declare function getMinimalAscApiKeyAsync(ascApiKey: AscApiKey): Promise<MinimalAscApiKey>;
12
+ export declare function provideOrGenerateAscApiKeyAsync(ctx: CredentialsContext, purpose: AppStoreApiKeyPurpose): Promise<MinimalAscApiKey>;
13
+ export declare function getAscApiKeyName(purpose: AppStoreApiKeyPurpose): string;
14
+ export declare function getAscApiKeysFromAccountAsync(ctx: CredentialsContext, account: Account, { filterDifferentAppleTeam }?: {
15
+ filterDifferentAppleTeam?: boolean;
16
+ }): Promise<AppStoreConnectApiKeyFragment[]>;
17
+ export declare function selectAscApiKeysFromAccountAsync(ctx: CredentialsContext, account: Account, { filterDifferentAppleTeam }?: {
18
+ filterDifferentAppleTeam?: boolean;
19
+ }): Promise<AppStoreConnectApiKeyFragment | null>;
20
+ export declare function sortAscApiKeysByUpdatedAtDesc(keys: AppStoreConnectApiKeyFragment[]): AppStoreConnectApiKeyFragment[];
21
+ export declare function formatAscApiKey(ascApiKey: AppStoreConnectApiKeyFragment): string;