eas-cli 0.31.1 → 0.34.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 (128) hide show
  1. package/README.md +29 -28
  2. package/build/analytics.js +3 -9
  3. package/build/build/android/UpdatesModule.js +4 -15
  4. package/build/build/android/configure.js +3 -3
  5. package/build/build/android/graphql.js +2 -4
  6. package/build/build/android/prepareJob.js +4 -3
  7. package/build/build/build.js +2 -2
  8. package/build/build/configure.js +26 -13
  9. package/build/build/ios/UpdatesModule.js +6 -18
  10. package/build/build/ios/configure.js +1 -1
  11. package/build/build/ios/graphql.js +2 -23
  12. package/build/build/ios/prepareJob.js +4 -6
  13. package/build/build/metadata.js +5 -10
  14. package/build/build/utils/appJson.d.ts +1 -0
  15. package/build/build/utils/appJson.js +13 -4
  16. package/build/build/utils/devClient.d.ts +4 -4
  17. package/build/build/utils/devClient.js +10 -18
  18. package/build/build/utils/repository.js +10 -7
  19. package/build/build/validate.js +4 -4
  20. package/build/commandUtils/EasCommand.d.ts +1 -0
  21. package/build/commandUtils/EasCommand.js +21 -0
  22. package/build/commands/branch/create.js +3 -2
  23. package/build/commands/branch/delete.js +1 -1
  24. package/build/commands/branch/list.js +1 -1
  25. package/build/commands/branch/publish.js +20 -48
  26. package/build/commands/branch/view.js +1 -1
  27. package/build/commands/build/index.d.ts +1 -1
  28. package/build/commands/build/index.js +64 -49
  29. package/build/commands/channel/edit.js +1 -1
  30. package/build/commands/channel/list.js +1 -1
  31. package/build/commands/channel/view.js +1 -1
  32. package/build/commands/diagnostics.js +2 -2
  33. package/build/commands/project/info.js +1 -1
  34. package/build/commands/submit.js +16 -11
  35. package/build/commands/update/view.js +1 -1
  36. package/build/credentials/android/api/graphql/queries/GoogleServiceAccountKeyQuery.js +2 -0
  37. package/build/credentials/context.d.ts +1 -1
  38. package/build/credentials/context.js +5 -5
  39. package/build/credentials/credentialsJson/update.js +5 -4
  40. package/build/credentials/errors.d.ts +3 -0
  41. package/build/credentials/errors.js +7 -1
  42. package/build/credentials/ios/IosCredentialsProvider.js +1 -1
  43. package/build/credentials/ios/actions/AscApiKeyUtils.d.ts +5 -0
  44. package/build/credentials/ios/actions/AscApiKeyUtils.js +63 -0
  45. package/build/credentials/ios/actions/CreateDistributionCertificate.js +1 -1
  46. package/build/credentials/ios/actions/CreatePushKey.js +1 -1
  47. package/build/credentials/ios/actions/DistributionCertificateUtils.d.ts +1 -1
  48. package/build/credentials/ios/actions/DistributionCertificateUtils.js +10 -12
  49. package/build/credentials/ios/actions/PushKeyUtils.d.ts +1 -1
  50. package/build/credentials/ios/actions/PushKeyUtils.js +5 -5
  51. package/build/credentials/ios/actions/SetupTargetBuildCredentials.js +1 -1
  52. package/build/credentials/ios/api/graphql/queries/AppQuery.js +3 -1
  53. package/build/credentials/ios/api/graphql/queries/AppleDeviceQuery.js +6 -2
  54. package/build/credentials/ios/api/graphql/queries/AppleDistributionCertificateQuery.js +7 -1
  55. package/build/credentials/ios/api/graphql/queries/AppleProvisioningProfileQuery.js +5 -1
  56. package/build/credentials/ios/api/graphql/queries/ApplePushKeyQuery.js +2 -0
  57. package/build/credentials/ios/api/graphql/queries/AppleTeamQuery.js +5 -1
  58. package/build/credentials/ios/appstore/AppStoreApi.d.ts +7 -1
  59. package/build/credentials/ios/appstore/AppStoreApi.js +17 -0
  60. package/build/credentials/ios/appstore/Credentials.js +3 -3
  61. package/build/credentials/ios/appstore/Credentials.types.d.ts +13 -0
  62. package/build/credentials/ios/appstore/ascApiKey.d.ts +9 -0
  63. package/build/credentials/ios/appstore/ascApiKey.js +99 -0
  64. package/build/credentials/ios/credentials.d.ts +17 -0
  65. package/build/credentials/ios/credentials.js +16 -1
  66. package/build/credentials/manager/Actions.d.ts +47 -0
  67. package/build/credentials/manager/Actions.js +48 -0
  68. package/build/credentials/manager/AndroidActions.d.ts +6 -0
  69. package/build/credentials/manager/AndroidActions.js +114 -0
  70. package/build/credentials/manager/IosActions.d.ts +6 -0
  71. package/build/credentials/manager/IosActions.js +110 -0
  72. package/build/credentials/manager/ManageAndroid.d.ts +1 -29
  73. package/build/credentials/manager/ManageAndroid.js +26 -159
  74. package/build/credentials/manager/ManageIos.d.ts +1 -29
  75. package/build/credentials/manager/ManageIos.js +28 -155
  76. package/build/graphql/client.d.ts +8 -2
  77. package/build/graphql/generated.d.ts +134 -121
  78. package/build/graphql/generated.js +46 -28
  79. package/build/graphql/queries/BuildQuery.js +4 -1
  80. package/build/graphql/queries/EnvironmentSecretsQuery.js +4 -2
  81. package/build/graphql/queries/ProjectQuery.js +3 -1
  82. package/build/graphql/queries/PublishQuery.js +4 -1
  83. package/build/graphql/queries/SubmissionQuery.js +5 -2
  84. package/build/graphql/queries/UserQuery.js +4 -1
  85. package/build/graphql/queries/WebhookQuery.js +6 -2
  86. package/build/log.d.ts +11 -3
  87. package/build/log.js +23 -22
  88. package/build/project/android/applicationId.d.ts +1 -1
  89. package/build/project/android/applicationId.js +7 -6
  90. package/build/project/ios/bundleIdentifier.d.ts +1 -1
  91. package/build/project/ios/bundleIdentifier.js +7 -6
  92. package/build/project/projectUtils.js +1 -1
  93. package/build/project/publish.js +2 -2
  94. package/build/project/workflow.js +2 -2
  95. package/build/submit/ArchiveSource.d.ts +7 -2
  96. package/build/submit/ArchiveSource.js +94 -11
  97. package/build/submit/ios/AscApiKeySource.d.ts +28 -0
  98. package/build/submit/ios/AscApiKeySource.js +51 -0
  99. package/build/submit/ios/IosSubmitCommand.d.ts +2 -0
  100. package/build/submit/ios/IosSubmitCommand.js +55 -3
  101. package/build/submit/ios/IosSubmitter.d.ts +3 -1
  102. package/build/submit/ios/IosSubmitter.js +49 -5
  103. package/build/submit/submit.js +1 -1
  104. package/build/submit/utils/builds.d.ts +3 -1
  105. package/build/submit/utils/builds.js +6 -6
  106. package/build/user/User.js +1 -0
  107. package/build/utils/easCli.d.ts +1 -0
  108. package/build/utils/easCli.js +5 -0
  109. package/build/utils/{expoCommand.d.ts → expoCli.d.ts} +0 -0
  110. package/build/utils/{expoCommand.js → expoCli.js} +0 -0
  111. package/build/utils/profiles.d.ts +11 -0
  112. package/build/utils/profiles.js +46 -0
  113. package/build/vcs/clients/git.d.ts +26 -0
  114. package/build/vcs/clients/git.js +184 -0
  115. package/build/vcs/clients/gitNoCommit.d.ts +7 -0
  116. package/build/vcs/clients/gitNoCommit.js +27 -0
  117. package/build/vcs/clients/noVcs.d.ts +6 -0
  118. package/build/vcs/clients/noVcs.js +19 -0
  119. package/build/vcs/git.d.ts +10 -17
  120. package/build/vcs/git.js +7 -175
  121. package/build/vcs/index.d.ts +2 -2
  122. package/build/vcs/index.js +15 -6
  123. package/build/vcs/local.d.ts +18 -5
  124. package/build/vcs/local.js +61 -32
  125. package/build/vcs/vcs.d.ts +2 -1
  126. package/build/vcs/vcs.js +8 -4
  127. package/oclif.manifest.json +1 -1
  128. package/package.json +7 -7
@@ -25,7 +25,10 @@ exports.UserQuery = {
25
25
  isExpoAdmin
26
26
  }
27
27
  }
28
- `)
28
+ `,
29
+ /* variables */ undefined, {
30
+ additionalTypenames: ['User'],
31
+ })
29
32
  .toPromise());
30
33
  return data.meActor;
31
34
  },
@@ -23,7 +23,9 @@ exports.WebhookQuery = {
23
23
  }
24
24
  }
25
25
  ${(0, graphql_1.print)(Webhook_1.WebhookFragmentNode)}
26
- `, { appId, webhookFilter })
26
+ `, { appId, webhookFilter }, {
27
+ additionalTypenames: ['Webhook'],
28
+ })
27
29
  .toPromise());
28
30
  return (_b = (_a = data.app) === null || _a === void 0 ? void 0 : _a.byId.webhooks) !== null && _b !== void 0 ? _b : [];
29
31
  },
@@ -39,7 +41,9 @@ exports.WebhookQuery = {
39
41
  }
40
42
  }
41
43
  ${(0, graphql_1.print)(Webhook_1.WebhookFragmentNode)}
42
- `, { webhookId })
44
+ `, { webhookId }, {
45
+ additionalTypenames: ['Webhook'],
46
+ })
43
47
  .toPromise());
44
48
  return data.webhook.byId;
45
49
  },
package/build/log.d.ts CHANGED
@@ -11,17 +11,25 @@ export default class Log {
11
11
  static succeed(message: string): void;
12
12
  static withTick(...args: any[]): void;
13
13
  private static consoleLog;
14
- private static consoleWarn;
15
- private static consoleError;
16
14
  private static withTextColor;
17
15
  private static isLastLineNewLine;
18
16
  private static updateIsLastLineNewLine;
19
17
  }
20
18
  /**
19
+ * Prints a link for given URL, using text if provided, otherwise text is just the URL.
20
+ * Format links as dim (unless disabled) and with an underline.
21
+ *
22
+ * @example https://expo.dev
23
+ */
24
+ export declare function link(url: string, { text, dim }?: {
25
+ text?: string;
26
+ dim?: boolean;
27
+ }): string;
28
+ /**
29
+ * Provide a consistent "Learn more" link experience.
21
30
  * Format links as dim (unless disabled) with an underline.
22
31
  *
23
32
  * @example Learn more: https://expo.dev
24
- * @param url
25
33
  */
26
34
  export declare function learnMore(url: string, { learnMoreMessage: maybeLearnMoreMessage, dim, }?: {
27
35
  learnMoreMessage?: string;
package/build/log.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.learnMore = void 0;
3
+ exports.learnMore = exports.link = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
6
  const figures_1 = (0, tslib_1.__importDefault)(require("figures"));
@@ -20,10 +20,10 @@ class Log {
20
20
  }
21
21
  }
22
22
  static error(...args) {
23
- Log.consoleError(...Log.withTextColor(args, chalk_1.default.red));
23
+ Log.consoleLog(...Log.withTextColor(args, chalk_1.default.red));
24
24
  }
25
25
  static warn(...args) {
26
- Log.consoleWarn(...Log.withTextColor(args, chalk_1.default.yellow));
26
+ Log.consoleLog(...Log.withTextColor(args, chalk_1.default.yellow));
27
27
  }
28
28
  static debug(...args) {
29
29
  if (Log.isDebug) {
@@ -47,16 +47,6 @@ class Log {
47
47
  // eslint-disable-next-line no-console
48
48
  console.log(...args);
49
49
  }
50
- static consoleWarn(...args) {
51
- Log.updateIsLastLineNewLine(args);
52
- // eslint-disable-next-line no-console
53
- console.warn(...args);
54
- }
55
- static consoleError(...args) {
56
- Log.updateIsLastLineNewLine(args);
57
- // eslint-disable-next-line no-console
58
- console.error(...args);
59
- }
60
50
  static withTextColor(args, chalkColor) {
61
51
  return args.map(arg => chalkColor(arg));
62
52
  }
@@ -79,19 +69,30 @@ exports.default = Log;
79
69
  Log.isDebug = (0, getenv_1.boolish)('EXPO_DEBUG', false);
80
70
  Log.isLastLineNewLine = false;
81
71
  /**
82
- * Format links as dim (unless disabled) with an underline.
72
+ * Prints a link for given URL, using text if provided, otherwise text is just the URL.
73
+ * Format links as dim (unless disabled) and with an underline.
83
74
  *
84
- * @example Learn more: https://expo.dev
85
- * @param url
75
+ * @example https://expo.dev
86
76
  */
87
- function learnMore(url, { learnMoreMessage: maybeLearnMoreMessage, dim = true, } = {}) {
77
+ function link(url, { text = url, dim = true } = {}) {
78
+ let output;
88
79
  // Links can be disabled via env variables https://github.com/jamestalmage/supports-hyperlinks/blob/master/index.js
89
80
  if (terminal_link_1.default.isSupported) {
90
- const text = (0, terminal_link_1.default)(maybeLearnMoreMessage !== null && maybeLearnMoreMessage !== void 0 ? maybeLearnMoreMessage : 'Learn more.', url);
91
- return dim ? chalk_1.default.dim(text) : text;
81
+ output = (0, terminal_link_1.default)(text, url);
92
82
  }
93
- const learnMoreMessage = maybeLearnMoreMessage !== null && maybeLearnMoreMessage !== void 0 ? maybeLearnMoreMessage : 'Learn more';
94
- const text = `${learnMoreMessage === '' ? learnMoreMessage : `${learnMoreMessage}: `}${chalk_1.default.underline(url)}`;
95
- return dim ? chalk_1.default.dim(text) : text;
83
+ else {
84
+ output = `${text === url ? '' : text + ': '}${chalk_1.default.underline(url)}`;
85
+ }
86
+ return dim ? chalk_1.default.dim(output) : output;
87
+ }
88
+ exports.link = link;
89
+ /**
90
+ * Provide a consistent "Learn more" link experience.
91
+ * Format links as dim (unless disabled) with an underline.
92
+ *
93
+ * @example Learn more: https://expo.dev
94
+ */
95
+ function learnMore(url, { learnMoreMessage: maybeLearnMoreMessage, dim = true, } = {}) {
96
+ return link(url, { text: maybeLearnMoreMessage !== null && maybeLearnMoreMessage !== void 0 ? maybeLearnMoreMessage : 'Learn more', dim });
96
97
  }
97
98
  exports.learnMore = learnMore;
@@ -2,4 +2,4 @@ import { ExpoConfig } from '@expo/config';
2
2
  import { GradleBuildContext } from './gradle';
3
3
  export declare function ensureApplicationIdIsDefinedForManagedProjectAsync(projectDir: string, exp: ExpoConfig): Promise<string>;
4
4
  export declare function getApplicationIdAsync(projectDir: string, exp: ExpoConfig, gradleContext?: GradleBuildContext): Promise<string>;
5
- export declare function warnIfAndroidPackageDefinedInAppConfigForGenericProject(projectDir: string, exp: ExpoConfig): void;
5
+ export declare function warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject(projectDir: string, exp: ExpoConfig): void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.warnIfAndroidPackageDefinedInAppConfigForGenericProject = exports.getApplicationIdAsync = exports.ensureApplicationIdIsDefinedForManagedProjectAsync = void 0;
3
+ exports.warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject = exports.getApplicationIdAsync = exports.ensureApplicationIdIsDefinedForManagedProjectAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const config_1 = require("@expo/config");
6
6
  const config_plugins_1 = require("@expo/config-plugins");
@@ -9,6 +9,7 @@ const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
9
9
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
10
10
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
11
11
  const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
12
+ const appJson_1 = require("../../build/utils/appJson");
12
13
  const log_1 = (0, tslib_1.__importStar)(require("../../log"));
13
14
  const projectUtils_1 = require("../../project/projectUtils");
14
15
  const prompts_1 = require("../../prompts");
@@ -32,7 +33,7 @@ exports.ensureApplicationIdIsDefinedForManagedProjectAsync = ensureApplicationId
32
33
  async function getApplicationIdAsync(projectDir, exp, gradleContext) {
33
34
  const workflow = await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.ANDROID);
34
35
  if (workflow === eas_build_job_1.Workflow.GENERIC) {
35
- warnIfAndroidPackageDefinedInAppConfigForGenericProject(projectDir, exp);
36
+ warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject(projectDir, exp);
36
37
  const errorMessage = 'Could not read application id from Android project.';
37
38
  if (gradleContext) {
38
39
  const buildGradle = await gradleUtils.getAppBuildGradleAsync(projectDir);
@@ -90,7 +91,7 @@ async function configureApplicationIdAsync(projectDir, exp) {
90
91
  initial: suggestedAndroidApplicationId,
91
92
  validate: value => (isApplicationIdValid(value) ? true : INVALID_APPLICATION_ID_MESSAGE),
92
93
  });
93
- const rawStaticConfig = await fs_extra_1.default.readJSON(paths.staticConfigPath);
94
+ const rawStaticConfig = (0, appJson_1.readAppJson)(paths.staticConfigPath);
94
95
  rawStaticConfig.expo = {
95
96
  ...rawStaticConfig.expo,
96
97
  android: { ...(_a = rawStaticConfig.expo) === null || _a === void 0 ? void 0 : _a.android, package: packageName },
@@ -103,14 +104,14 @@ function isApplicationIdValid(applicationId) {
103
104
  return /^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(applicationId);
104
105
  }
105
106
  let warnPrinted = false;
106
- function warnIfAndroidPackageDefinedInAppConfigForGenericProject(projectDir, exp) {
107
+ function warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject(projectDir, exp) {
107
108
  if (config_plugins_1.AndroidConfig.Package.getPackage(exp) && !warnPrinted) {
108
- log_1.default.warn(`Specifying "android.package" in ${(0, projectUtils_1.getProjectConfigDescription)(projectDir)} is deprecated for generic projects.\n` +
109
+ log_1.default.warn(`Specifying "android.package" in ${(0, projectUtils_1.getProjectConfigDescription)(projectDir)} is deprecated for bare workflow projects.\n` +
109
110
  'EAS Build depends only on the value in the native code. Please remove the deprecated configuration.');
110
111
  warnPrinted = true;
111
112
  }
112
113
  }
113
- exports.warnIfAndroidPackageDefinedInAppConfigForGenericProject = warnIfAndroidPackageDefinedInAppConfigForGenericProject;
114
+ exports.warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject = warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject;
114
115
  async function getSuggestedApplicationIdAsync(exp) {
115
116
  // Attempt to use the ios bundle id first since it's convenient to have them aligned.
116
117
  const maybeBundleId = config_plugins_1.IOSConfig.BundleIdentifier.getBundleIdentifier(exp);
@@ -4,5 +4,5 @@ export declare function getBundleIdentifierAsync(projectDir: string, exp: ExpoCo
4
4
  targetName?: string;
5
5
  buildConfiguration?: string;
6
6
  }): Promise<string>;
7
- export declare function warnIfBundleIdentifierDefinedInAppConfigForGenericProject(projectDir: string, exp: ExpoConfig): void;
7
+ export declare function warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject(projectDir: string, exp: ExpoConfig): void;
8
8
  export declare function isWildcardBundleIdentifier(bundleIdentifier: string): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isWildcardBundleIdentifier = exports.warnIfBundleIdentifierDefinedInAppConfigForGenericProject = exports.getBundleIdentifierAsync = exports.ensureBundleIdentifierIsDefinedForManagedProjectAsync = void 0;
3
+ exports.isWildcardBundleIdentifier = exports.warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject = exports.getBundleIdentifierAsync = exports.ensureBundleIdentifierIsDefinedForManagedProjectAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const config_1 = require("@expo/config");
6
6
  const config_plugins_1 = require("@expo/config-plugins");
@@ -8,6 +8,7 @@ const eas_build_job_1 = require("@expo/eas-build-job");
8
8
  const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
9
9
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
10
10
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
11
+ const appJson_1 = require("../../build/utils/appJson");
11
12
  const log_1 = (0, tslib_1.__importStar)(require("../../log"));
12
13
  const prompts_1 = require("../../prompts");
13
14
  const actions_1 = require("../../user/actions");
@@ -28,7 +29,7 @@ exports.ensureBundleIdentifierIsDefinedForManagedProjectAsync = ensureBundleIden
28
29
  async function getBundleIdentifierAsync(projectDir, exp, { targetName, buildConfiguration } = {}) {
29
30
  const workflow = await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.IOS);
30
31
  if (workflow === eas_build_job_1.Workflow.GENERIC) {
31
- warnIfBundleIdentifierDefinedInAppConfigForGenericProject(projectDir, exp);
32
+ warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject(projectDir, exp);
32
33
  const bundleIdentifier = config_plugins_1.IOSConfig.BundleIdentifier.getBundleIdentifierFromPbxproj(projectDir, {
33
34
  targetName,
34
35
  buildConfiguration,
@@ -77,7 +78,7 @@ async function configureBundleIdentifierAsync(projectDir, exp) {
77
78
  initial: suggestedBundleIdentifier,
78
79
  validate: value => (isBundleIdentifierValid(value) ? true : INVALID_BUNDLE_IDENTIFIER_MESSAGE),
79
80
  });
80
- const rawStaticConfig = await fs_extra_1.default.readJSON(paths.staticConfigPath);
81
+ const rawStaticConfig = (0, appJson_1.readAppJson)(paths.staticConfigPath);
81
82
  rawStaticConfig.expo = {
82
83
  ...rawStaticConfig.expo,
83
84
  ios: { ...(_a = rawStaticConfig.expo) === null || _a === void 0 ? void 0 : _a.ios, bundleIdentifier },
@@ -90,14 +91,14 @@ function isBundleIdentifierValid(bundleIdentifier) {
90
91
  return /^[a-zA-Z0-9-.]+$/.test(bundleIdentifier);
91
92
  }
92
93
  let warnPrinted = false;
93
- function warnIfBundleIdentifierDefinedInAppConfigForGenericProject(projectDir, exp) {
94
+ function warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject(projectDir, exp) {
94
95
  if (config_plugins_1.IOSConfig.BundleIdentifier.getBundleIdentifier(exp) && !warnPrinted) {
95
- log_1.default.warn(`Specifying "ios.bundleIdentifier" in ${(0, projectUtils_1.getProjectConfigDescription)(projectDir)} is deprecated for generic projects.\n` +
96
+ log_1.default.warn(`Specifying "ios.bundleIdentifier" in ${(0, projectUtils_1.getProjectConfigDescription)(projectDir)} is deprecated for bare workflow projects.\n` +
96
97
  'EAS Build depends only on the value in the native code. Please remove the deprecated configuration.');
97
98
  warnPrinted = true;
98
99
  }
99
100
  }
100
- exports.warnIfBundleIdentifierDefinedInAppConfigForGenericProject = warnIfBundleIdentifierDefinedInAppConfigForGenericProject;
101
+ exports.warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject = warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject;
101
102
  function isWildcardBundleIdentifier(bundleIdentifier) {
102
103
  const wildcardRegex = /^[A-Za-z0-9.-]+\*$/;
103
104
  return wildcardRegex.test(bundleIdentifier);
@@ -184,7 +184,7 @@ async function getBranchByNameAsync({ appId, name, }) {
184
184
  `, {
185
185
  appId,
186
186
  name,
187
- })
187
+ }, { additionalTypenames: ['UpdateBranch'] })
188
188
  .toPromise());
189
189
  return data.app.byId.updateBranchByName;
190
190
  }
@@ -13,7 +13,7 @@ const PublishMutation_1 = require("../graphql/mutations/PublishMutation");
13
13
  const PublishQuery_1 = require("../graphql/queries/PublishQuery");
14
14
  const log_1 = (0, tslib_1.__importDefault)(require("../log"));
15
15
  const uploads_1 = require("../uploads");
16
- const expoCommand_1 = require("../utils/expoCommand");
16
+ const expoCli_1 = require("../utils/expoCli");
17
17
  const uniqBy_1 = (0, tslib_1.__importDefault)(require("../utils/expodash/uniqBy"));
18
18
  exports.TIMEOUT_LIMIT = 60000; // 1 minute
19
19
  const fileMetadataJoi = joi_1.default.object({
@@ -108,7 +108,7 @@ async function buildBundlesAsync({ projectDir, inputDir, }) {
108
108
  throw new Error('Could not locate package.json');
109
109
  }
110
110
  log_1.default.withTick(`Building bundle with expo-cli...`);
111
- await (0, expoCommand_1.expoCommandAsync)(projectDir, ['export', '--output-dir', inputDir, '--experimental-bundle']);
111
+ await (0, expoCli_1.expoCommandAsync)(projectDir, ['export', '--output-dir', inputDir, '--experimental-bundle']);
112
112
  }
113
113
  exports.buildBundlesAsync = buildBundlesAsync;
114
114
  async function resolveInputDirectoryAsync(customInputDirectory) {
@@ -6,7 +6,7 @@ const config_plugins_1 = require("@expo/config-plugins");
6
6
  const eas_build_job_1 = require("@expo/eas-build-job");
7
7
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
8
8
  const path_1 = (0, tslib_1.__importDefault)(require("path"));
9
- const vcs_1 = (0, tslib_1.__importDefault)(require("../vcs"));
9
+ const vcs_1 = require("../vcs");
10
10
  async function resolveWorkflowAsync(projectDir, platform) {
11
11
  let platformWorkflowMarker;
12
12
  try {
@@ -19,7 +19,7 @@ async function resolveWorkflowAsync(projectDir, platform) {
19
19
  return eas_build_job_1.Workflow.MANAGED;
20
20
  }
21
21
  if (await fs_extra_1.default.pathExists(platformWorkflowMarker)) {
22
- return (await vcs_1.default.isFileIgnoredAsync(path_1.default.relative(projectDir, platformWorkflowMarker)))
22
+ return (await (0, vcs_1.getVcsClient)().isFileIgnoredAsync(path_1.default.relative(projectDir, platformWorkflowMarker)))
23
23
  ? eas_build_job_1.Workflow.MANAGED
24
24
  : eas_build_job_1.Workflow.GENERIC;
25
25
  }
@@ -1,11 +1,13 @@
1
1
  import { Platform } from '@expo/eas-build-job';
2
2
  import { BuildFragment } from '../graphql/generated';
3
+ export declare const BUILD_LIST_ITEM_COUNT = 4;
3
4
  export declare enum ArchiveSourceType {
4
5
  url = 0,
5
6
  latest = 1,
6
7
  path = 2,
7
8
  buildId = 3,
8
- prompt = 4
9
+ buildList = 4,
10
+ prompt = 5
9
11
  }
10
12
  interface ArchiveSourceBase {
11
13
  sourceType: ArchiveSourceType;
@@ -28,6 +30,9 @@ interface ArchiveBuildIdSource extends ArchiveSourceBase {
28
30
  sourceType: ArchiveSourceType.buildId;
29
31
  id: string;
30
32
  }
33
+ interface ArchiveBuildListSource extends ArchiveSourceBase {
34
+ sourceType: ArchiveSourceType.buildList;
35
+ }
31
36
  interface ArchivePromptSource extends ArchiveSourceBase {
32
37
  sourceType: ArchiveSourceType.prompt;
33
38
  }
@@ -36,7 +41,7 @@ export interface Archive {
36
41
  source: ArchiveSource;
37
42
  url?: string;
38
43
  }
39
- export declare type ArchiveSource = ArchiveUrlSource | ArchiveLatestSource | ArchivePathSource | ArchiveBuildIdSource | ArchivePromptSource;
44
+ export declare type ArchiveSource = ArchiveUrlSource | ArchiveLatestSource | ArchivePathSource | ArchiveBuildIdSource | ArchiveBuildListSource | ArchivePromptSource;
40
45
  export declare function getArchiveAsync(source: ArchiveSource): Promise<Archive>;
41
46
  export declare function isUuidV4(s: string): boolean;
42
47
  export {};
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isUuidV4 = exports.getArchiveAsync = exports.ArchiveSourceType = void 0;
3
+ exports.isUuidV4 = exports.getArchiveAsync = exports.ArchiveSourceType = exports.BUILD_LIST_ITEM_COUNT = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const eas_build_job_1 = require("@expo/eas-build-job");
6
6
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
7
  const url_1 = require("url");
8
8
  const uuid = (0, tslib_1.__importStar)(require("uuid"));
9
+ const generated_1 = require("../graphql/generated");
9
10
  const BuildQuery_1 = require("../graphql/queries/BuildQuery");
10
11
  const AppPlatform_1 = require("../graphql/types/AppPlatform");
11
12
  const log_1 = (0, tslib_1.__importStar)(require("../log"));
@@ -13,13 +14,15 @@ const platform_1 = require("../platform");
13
14
  const prompts_1 = require("../prompts");
14
15
  const builds_1 = require("./utils/builds");
15
16
  const files_1 = require("./utils/files");
17
+ exports.BUILD_LIST_ITEM_COUNT = 4;
16
18
  var ArchiveSourceType;
17
19
  (function (ArchiveSourceType) {
18
20
  ArchiveSourceType[ArchiveSourceType["url"] = 0] = "url";
19
21
  ArchiveSourceType[ArchiveSourceType["latest"] = 1] = "latest";
20
22
  ArchiveSourceType[ArchiveSourceType["path"] = 2] = "path";
21
23
  ArchiveSourceType[ArchiveSourceType["buildId"] = 3] = "buildId";
22
- ArchiveSourceType[ArchiveSourceType["prompt"] = 4] = "prompt";
24
+ ArchiveSourceType[ArchiveSourceType["buildList"] = 4] = "buildList";
25
+ ArchiveSourceType[ArchiveSourceType["prompt"] = 5] = "prompt";
23
26
  })(ArchiveSourceType = exports.ArchiveSourceType || (exports.ArchiveSourceType = {}));
24
27
  async function getArchiveAsync(source) {
25
28
  switch (source.sourceType) {
@@ -38,6 +41,9 @@ async function getArchiveAsync(source) {
38
41
  case ArchiveSourceType.buildId: {
39
42
  return await handleBuildIdSourceAsync(source);
40
43
  }
44
+ case ArchiveSourceType.buildList: {
45
+ return await handleBuildListSourceAsync(source);
46
+ }
41
47
  }
42
48
  }
43
49
  exports.getArchiveAsync = getArchiveAsync;
@@ -67,7 +73,7 @@ async function handleUrlSourceAsync(source) {
67
73
  }
68
74
  async function handleLatestSourceAsync(source) {
69
75
  try {
70
- const latestBuild = await (0, builds_1.getLatestBuildForSubmissionAsync)((0, AppPlatform_1.toAppPlatform)(source.platform), source.projectId);
76
+ const [latestBuild] = await (0, builds_1.getRecentBuildsForSubmissionAsync)((0, AppPlatform_1.toAppPlatform)(source.platform), source.projectId);
71
77
  if (!latestBuild) {
72
78
  log_1.default.error(chalk_1.default.bold("Couldn't find any builds for this project on EAS servers. It looks like you haven't run 'eas build' yet."));
73
79
  return getArchiveAsync({
@@ -128,6 +134,83 @@ async function handleBuildIdSourceAsync(source) {
128
134
  });
129
135
  }
130
136
  }
137
+ async function handleBuildListSourceAsync(source) {
138
+ try {
139
+ const appPlatform = (0, AppPlatform_1.toAppPlatform)(source.platform);
140
+ const expiryDate = new Date(); // artifacts expire after 30 days
141
+ expiryDate.setDate(expiryDate.getDate() - 30);
142
+ const recentBuilds = await (0, builds_1.getRecentBuildsForSubmissionAsync)(appPlatform, source.projectId, {
143
+ limit: exports.BUILD_LIST_ITEM_COUNT,
144
+ });
145
+ if (recentBuilds.length < 1) {
146
+ log_1.default.error(chalk_1.default.bold(`Couldn't find any ${platform_1.appPlatformDisplayNames[appPlatform]} builds for this project on EAS servers. ` +
147
+ "It looks like you haven't run 'eas build' yet."));
148
+ return getArchiveAsync({
149
+ ...source,
150
+ sourceType: ArchiveSourceType.prompt,
151
+ });
152
+ }
153
+ if (recentBuilds.every(it => new Date(it.updatedAt) < expiryDate)) {
154
+ log_1.default.error(chalk_1.default.bold('It looks like all of your build artifacts have expired. ' +
155
+ 'EAS keeps your build artifacts only for 30 days.'));
156
+ return getArchiveAsync({
157
+ ...source,
158
+ sourceType: ArchiveSourceType.prompt,
159
+ });
160
+ }
161
+ const choices = recentBuilds.map(build => formatBuildChoice(build, expiryDate));
162
+ choices.push({
163
+ title: 'None of the above (select another option)',
164
+ value: null,
165
+ });
166
+ const { selectedBuild } = await (0, prompts_1.promptAsync)({
167
+ name: 'selectedBuild',
168
+ type: 'select',
169
+ message: 'Which build would you like to submit?',
170
+ choices: choices.map(choice => ({ ...choice, title: `- ${choice.title}` })),
171
+ // @ts-expect-error field documented in npm, but not defined in typescript
172
+ warn: 'This artifact has expired',
173
+ });
174
+ if (selectedBuild == null) {
175
+ return getArchiveAsync({
176
+ ...source,
177
+ sourceType: ArchiveSourceType.prompt,
178
+ });
179
+ }
180
+ return {
181
+ build: selectedBuild,
182
+ source,
183
+ };
184
+ }
185
+ catch (err) {
186
+ log_1.default.error(err);
187
+ throw err;
188
+ }
189
+ }
190
+ function formatBuildChoice(build, expiryDate) {
191
+ const { id, platform, updatedAt, appVersion, sdkVersion, runtimeVersion, buildProfile, appBuildVersion, releaseChannel, } = build;
192
+ const formatValue = (field) => field ? chalk_1.default.bold(field) : chalk_1.default.dim('Unknown');
193
+ const buildDate = new Date(updatedAt);
194
+ const maybeRuntimeVersion = runtimeVersion ? `Runtime: ${formatValue(runtimeVersion)}` : null;
195
+ const maybeSdkVersion = sdkVersion ? `SDK: ${formatValue(sdkVersion)}` : null;
196
+ const appBuildVersionString = `${platform === generated_1.AppPlatform.Android ? 'Version code' : 'Build number'}: ${formatValue(appBuildVersion)}`;
197
+ const title = [
198
+ `ID: ${chalk_1.default.dim(id)}, Finished at: ${chalk_1.default.bold(buildDate.toLocaleString())}`,
199
+ [
200
+ `\tApp version: ${formatValue(appVersion)}, ${appBuildVersionString}`,
201
+ maybeRuntimeVersion,
202
+ maybeSdkVersion,
203
+ ]
204
+ .filter(it => it != null)
205
+ .join(', '),
206
+ `\tProfile: ${formatValue(buildProfile)}, Release channel: ${formatValue(releaseChannel)}`,
207
+ ].join('\n');
208
+ return {
209
+ title,
210
+ value: build,
211
+ disabled: buildDate < expiryDate,
212
+ };
213
+ }
131
214
  async function handlePromptSourceAsync(source) {
132
215
  const { sourceType: sourceTypeRaw } = await (0, prompts_1.promptAsync)({
133
216
  name: 'sourceType',
@@ -135,16 +218,16 @@ async function handlePromptSourceAsync(source) {
135
218
  message: 'What would you like to submit?',
136
219
  choices: [
137
220
  {
138
- title: 'Latest finished build from EAS',
139
- value: ArchiveSourceType.latest,
221
+ title: 'Select a build from EAS',
222
+ value: ArchiveSourceType.buildList,
140
223
  },
141
- { title: 'I have a url to the app archive', value: ArchiveSourceType.url },
224
+ { title: 'Provide a URL to the app archive', value: ArchiveSourceType.url },
142
225
  {
143
- title: 'Local app binary file',
226
+ title: 'Provide a path to a local app binary file',
144
227
  value: ArchiveSourceType.path,
145
228
  },
146
229
  {
147
- title: 'A build identified by a build ID',
230
+ title: 'Provide a build ID to identify a build on EAS',
148
231
  value: ArchiveSourceType.buildId,
149
232
  },
150
233
  ],
@@ -167,10 +250,10 @@ async function handlePromptSourceAsync(source) {
167
250
  path,
168
251
  });
169
252
  }
170
- case ArchiveSourceType.latest: {
253
+ case ArchiveSourceType.buildList: {
171
254
  return getArchiveAsync({
172
255
  ...source,
173
- sourceType: ArchiveSourceType.latest,
256
+ sourceType: ArchiveSourceType.buildList,
174
257
  });
175
258
  }
176
259
  case ArchiveSourceType.buildId: {
@@ -181,7 +264,7 @@ async function handlePromptSourceAsync(source) {
181
264
  id,
182
265
  });
183
266
  }
184
- case ArchiveSourceType.prompt:
267
+ default:
185
268
  throw new Error('This should never happen');
186
269
  }
187
270
  }
@@ -0,0 +1,28 @@
1
+ import { AscApiKeyPath, MinimalAscApiKey } from '../../credentials/ios/credentials';
2
+ export declare enum AscApiKeySourceType {
3
+ path = 0,
4
+ prompt = 1
5
+ }
6
+ interface AscApiKeySourceBase {
7
+ sourceType: AscApiKeySourceType;
8
+ }
9
+ interface AscApiKeyPromptSource extends AscApiKeySourceBase {
10
+ sourceType: AscApiKeySourceType.prompt;
11
+ }
12
+ interface AscApiKeyEnvVarSource extends AscApiKeySourceBase {
13
+ sourceType: AscApiKeySourceType.path;
14
+ path: AscApiKeyPath;
15
+ }
16
+ export declare type AscApiKeySource = AscApiKeyEnvVarSource | AscApiKeyPromptSource;
17
+ declare type AscApiKeySummary = {
18
+ source: 'local' | 'EAS servers';
19
+ path?: string;
20
+ keyId: string;
21
+ };
22
+ export declare type AscApiKeyResult = {
23
+ result: MinimalAscApiKey;
24
+ summary: AscApiKeySummary;
25
+ };
26
+ export declare function getAscApiKeyLocallyAsync(source: AscApiKeySource): Promise<AscApiKeyResult>;
27
+ export declare function getAscApiKeyPathAsync(source: AscApiKeySource): Promise<AscApiKeyPath>;
28
+ export {};
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAscApiKeyPathAsync = exports.getAscApiKeyLocallyAsync = exports.AscApiKeySourceType = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
6
+ const AscApiKeyUtils_1 = require("../../credentials/ios/actions/AscApiKeyUtils");
7
+ const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
8
+ const files_1 = require("../utils/files");
9
+ var AscApiKeySourceType;
10
+ (function (AscApiKeySourceType) {
11
+ AscApiKeySourceType[AscApiKeySourceType["path"] = 0] = "path";
12
+ AscApiKeySourceType[AscApiKeySourceType["prompt"] = 1] = "prompt";
13
+ })(AscApiKeySourceType = exports.AscApiKeySourceType || (exports.AscApiKeySourceType = {}));
14
+ async function getAscApiKeyLocallyAsync(source) {
15
+ const ascApiKeyPath = await getAscApiKeyPathAsync(source);
16
+ const { keyP8Path, keyId, issuerId } = ascApiKeyPath;
17
+ const keyP8 = await fs_extra_1.default.readFile(keyP8Path, 'utf-8');
18
+ return {
19
+ result: { keyP8, keyId, issuerId },
20
+ summary: {
21
+ source: 'local',
22
+ path: keyP8Path,
23
+ keyId,
24
+ },
25
+ };
26
+ }
27
+ exports.getAscApiKeyLocallyAsync = getAscApiKeyLocallyAsync;
28
+ async function getAscApiKeyPathAsync(source) {
29
+ switch (source.sourceType) {
30
+ case AscApiKeySourceType.path:
31
+ return await handlePathSourceAsync(source);
32
+ case AscApiKeySourceType.prompt:
33
+ return await handlePromptSourceAsync(source);
34
+ }
35
+ }
36
+ exports.getAscApiKeyPathAsync = getAscApiKeyPathAsync;
37
+ async function handlePathSourceAsync(source) {
38
+ const { keyP8Path } = source.path;
39
+ if (!(await (0, files_1.isExistingFileAsync)(keyP8Path))) {
40
+ log_1.default.warn(`File ${keyP8Path} doesn't exist.`);
41
+ return await getAscApiKeyPathAsync({ sourceType: AscApiKeySourceType.prompt });
42
+ }
43
+ return source.path;
44
+ }
45
+ async function handlePromptSourceAsync(_source) {
46
+ const ascApiKeyPath = await (0, AscApiKeyUtils_1.promptForAscApiKeyAsync)();
47
+ return await getAscApiKeyPathAsync({
48
+ sourceType: AscApiKeySourceType.path,
49
+ path: ascApiKeyPath,
50
+ });
51
+ }
@@ -5,8 +5,10 @@ export default class IosSubmitCommand {
5
5
  private ctx;
6
6
  constructor(ctx: SubmissionContext<Platform.IOS>);
7
7
  runAsync(): Promise<SubmissionFragment>;
8
+ private resolveCredentialSubmissionOptionsAsync;
8
9
  private resolveSubmissionOptionsAsync;
9
10
  private resolveAppSpecificPasswordSource;
11
+ private resolveAscApiKeySource;
10
12
  private resolveArchiveSource;
11
13
  private resolveAscAppIdentifierAsync;
12
14
  private resolveAppleIdUsernameAsync;