eas-cli 0.57.0 → 0.58.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 (61) hide show
  1. package/README.md +44 -44
  2. package/build/build/android/build.js +17 -3
  3. package/build/build/android/graphql.js +2 -0
  4. package/build/build/android/prepareJob.js +5 -0
  5. package/build/build/android/syncProjectConfiguration.d.ts +3 -4
  6. package/build/build/android/syncProjectConfiguration.js +2 -3
  7. package/build/build/android/version.d.ts +11 -0
  8. package/build/build/android/version.js +71 -1
  9. package/build/build/build.js +1 -1
  10. package/build/build/context.d.ts +4 -0
  11. package/build/build/createContext.d.ts +2 -1
  12. package/build/build/createContext.js +7 -1
  13. package/build/build/ios/build.js +17 -1
  14. package/build/build/ios/graphql.js +2 -0
  15. package/build/build/ios/prepareJob.js +5 -0
  16. package/build/build/ios/syncProjectConfiguration.d.ts +3 -4
  17. package/build/build/ios/syncProjectConfiguration.js +2 -3
  18. package/build/build/ios/version.d.ts +13 -0
  19. package/build/build/ios/version.js +72 -1
  20. package/build/build/local.d.ts +2 -2
  21. package/build/build/local.js +7 -7
  22. package/build/build/metadata.js +18 -2
  23. package/build/build/runBuildAndSubmit.js +21 -3
  24. package/build/build/utils/printBuildInfo.d.ts +1 -1
  25. package/build/build/utils/printBuildInfo.js +7 -13
  26. package/build/commands/build/version/set.d.ts +0 -1
  27. package/build/commands/build/version/set.js +2 -3
  28. package/build/commands/build/version/sync.d.ts +0 -1
  29. package/build/commands/build/version/sync.js +2 -3
  30. package/build/commands/submit.js +4 -1
  31. package/build/commands/update/index.js +12 -2
  32. package/build/graphql/generated.d.ts +230 -0
  33. package/build/graphql/generated.js +2 -0
  34. package/build/graphql/mutations/PublishMutation.d.ts +2 -4
  35. package/build/graphql/queries/BuildQuery.d.ts +4 -1
  36. package/build/graphql/queries/BuildQuery.js +19 -0
  37. package/build/graphql/queries/PublishQuery.d.ts +2 -1
  38. package/build/graphql/queries/PublishQuery.js +16 -0
  39. package/build/graphql/types/Build.d.ts +1 -0
  40. package/build/graphql/types/Build.js +16 -1
  41. package/build/metadata/apple/config/reader.d.ts +3 -2
  42. package/build/metadata/apple/config/reader.js +22 -5
  43. package/build/metadata/apple/config/writer.d.ts +3 -2
  44. package/build/metadata/apple/config/writer.js +22 -6
  45. package/build/metadata/apple/tasks/app-version.d.ts +5 -1
  46. package/build/metadata/apple/tasks/app-version.js +109 -8
  47. package/build/metadata/apple/tasks/index.d.ts +6 -1
  48. package/build/metadata/apple/tasks/index.js +7 -2
  49. package/build/metadata/apple/types.d.ts +3 -7
  50. package/build/metadata/upload.js +6 -1
  51. package/build/project/publish.d.ts +3 -1
  52. package/build/project/publish.js +17 -8
  53. package/build/project/remoteVersionSource.d.ts +5 -3
  54. package/build/project/remoteVersionSource.js +18 -9
  55. package/build/submit/submit.d.ts +2 -1
  56. package/build/submit/submit.js +3 -2
  57. package/build/vcs/clients/gitNoCommit.d.ts +1 -0
  58. package/build/vcs/clients/gitNoCommit.js +14 -0
  59. package/oclif.manifest.json +1 -1
  60. package/package.json +4 -4
  61. package/schema/metadata-0.json +38 -233
@@ -11,12 +11,13 @@ const retry_1 = require("../../utils/retry");
11
11
  const task_1 = require("../task");
12
12
  class AppVersionTask extends task_1.AppleTask {
13
13
  constructor(options = {}) {
14
- var _a, _b;
14
+ var _a, _b, _c;
15
15
  super();
16
16
  this.name = () => (this.options.editLive ? 'live app version' : 'editable app version');
17
17
  this.options = {
18
18
  platform: (_a = options.platform) !== null && _a !== void 0 ? _a : apple_utils_1.Platform.IOS,
19
19
  editLive: (_b = options.editLive) !== null && _b !== void 0 ? _b : false,
20
+ version: (_c = options.version) !== null && _c !== void 0 ? _c : null,
20
21
  };
21
22
  }
22
23
  async prepareAsync({ context }) {
@@ -26,24 +27,39 @@ class AppVersionTask extends task_1.AppleTask {
26
27
  context.versionIsFirst = versionIsFirst;
27
28
  context.versionIsLive = versionIsLive;
28
29
  context.versionLocales = await version.getLocalizationsAsync();
30
+ context.versionPhasedRelease = await version.getPhasedReleaseAsync();
29
31
  }
30
32
  async downloadAsync({ config, context }) {
33
+ var _a;
31
34
  (0, assert_1.default)(context.version, `App version not initialized, can't download version`);
32
35
  config.setVersion(context.version.attributes);
33
- config.setVersionRelease(context.version.attributes);
36
+ config.setVersionReleaseType(context.version.attributes);
37
+ config.setVersionReleasePhased((_a = context.versionPhasedRelease) === null || _a === void 0 ? void 0 : _a.attributes);
34
38
  for (const locale of context.versionLocales) {
35
39
  config.setVersionLocale(locale.attributes);
36
40
  }
37
41
  }
38
42
  async uploadAsync({ config, context }) {
39
- (0, assert_1.default)(context.version, `App version not initialized, can't update version`);
40
43
  const version = config.getVersion();
41
- const release = config.getVersionRelease();
44
+ if (!context.version && (version === null || version === void 0 ? void 0 : version.versionString)) {
45
+ context.version = await (0, log_2.logAsync)(() => {
46
+ return context.app.createVersionAsync({
47
+ versionString: version.versionString,
48
+ platform: this.options.platform,
49
+ });
50
+ }, {
51
+ pending: `Creating new version ${chalk_1.default.bold(version.versionString)}...`,
52
+ success: `Created new version ${chalk_1.default.bold(version.versionString)}`,
53
+ failure: `Failed creating new version ${chalk_1.default.bold(version.versionString)}`,
54
+ });
55
+ }
56
+ (0, assert_1.default)(context.version, `App version not initialized, can't update version`);
57
+ const { versionString } = context.version.attributes;
58
+ const release = config.getVersionReleaseType();
42
59
  if (!version && !release) {
43
60
  log_1.default.log((0, chalk_1.default) `{dim - Skipped version and release update, not configured}`);
44
61
  }
45
62
  else {
46
- const { versionString } = context.version.attributes;
47
63
  const description = [version && 'version', release && 'release']
48
64
  .filter(Boolean)
49
65
  .join(' and ');
@@ -53,6 +69,24 @@ class AppVersionTask extends task_1.AppleTask {
53
69
  failure: `Failed updating ${description} info for ${chalk_1.default.bold(versionString)}`,
54
70
  });
55
71
  }
72
+ const phasedRelease = config.getVersionReleasePhased();
73
+ if (!phasedRelease && shouldDeletePhasedRelease(context.versionPhasedRelease)) {
74
+ // if phased release was enabled, but now disabled, we need to remove it
75
+ await (0, log_2.logAsync)(() => context.versionPhasedRelease.deleteAsync(), {
76
+ pending: `Disabling phased release for ${chalk_1.default.bold(versionString)}...`,
77
+ success: `Disabled phased release for ${chalk_1.default.bold(versionString)}`,
78
+ failure: `Failed disabling phased release for ${chalk_1.default.bold(versionString)}`,
79
+ });
80
+ context.versionPhasedRelease = null;
81
+ }
82
+ else if (phasedRelease && !context.versionPhasedRelease) {
83
+ // if phased release was not yet set, but now enabled, we need to create it
84
+ context.versionPhasedRelease = await (0, log_2.logAsync)(() => context.version.createPhasedReleaseAsync({ state: phasedRelease.phasedReleaseState }), {
85
+ pending: `Enabling phased release for ${chalk_1.default.bold(versionString)}...`,
86
+ success: `Enabled phased release for ${chalk_1.default.bold(versionString)}`,
87
+ failure: `Failed enabling phased release for ${chalk_1.default.bold(versionString)}`,
88
+ });
89
+ }
56
90
  const locales = config.getLocales();
57
91
  if (locales.length <= 0) {
58
92
  log_1.default.log((0, chalk_1.default) `{dim - Skipped localized version update, no locales configured}`);
@@ -80,13 +114,23 @@ class AppVersionTask extends task_1.AppleTask {
80
114
  }
81
115
  exports.AppVersionTask = AppVersionTask;
82
116
  /**
83
- * Resolve the AppStoreVersion instance, either from live or editable version.
117
+ * Resolve the AppStoreVersion instance, either from the store config, live, or editable version.
84
118
  * This also checks if this is the first version, which disallow release notes.
85
119
  */
86
- async function resolveVersionAsync(app, { editLive, platform }) {
120
+ async function resolveVersionAsync(app, { editLive, platform, version: versionString }) {
87
121
  let version = null;
88
122
  let versionIsLive = false;
89
- if (editLive) {
123
+ if (versionString) {
124
+ version = await findEditAppStoreVersionAsync(app, { platform, version: versionString });
125
+ if (!version) {
126
+ version = await createOrUpdateEditAppStoreVersionAsync(app, {
127
+ platform,
128
+ version: versionString,
129
+ });
130
+ }
131
+ versionIsLive = (version === null || version === void 0 ? void 0 : version.attributes.appStoreState) === apple_utils_1.AppStoreState.READY_FOR_SALE;
132
+ }
133
+ if (!version && editLive) {
90
134
  version = await app.getLiveAppStoreVersionAsync({ platform });
91
135
  versionIsLive = !!version;
92
136
  }
@@ -102,3 +146,60 @@ async function resolveVersionAsync(app, { editLive, platform }) {
102
146
  versionIsFirst: versions.length === 1,
103
147
  };
104
148
  }
149
+ /**
150
+ * Determine if we can, and should, delete the phased release instance.
151
+ * This returns true if the instance exist, and has one of the states below:
152
+ * - PhasedReleaseState.INACTIVE
153
+ * - PhasedReleaseState.ACTIVE
154
+ * - PhasedReleaseState.PAUSED
155
+ */
156
+ function shouldDeletePhasedRelease(phasedRelease) {
157
+ if (!phasedRelease ||
158
+ phasedRelease.attributes.phasedReleaseState === apple_utils_1.PhasedReleaseState.COMPLETE) {
159
+ return false;
160
+ }
161
+ return true;
162
+ }
163
+ /*
164
+ * Search for editable app store versions that matches the `versionString` option.
165
+ * When nothing is found, it will return `null`, and a new version should be created.
166
+ */
167
+ async function findEditAppStoreVersionAsync(app, options) {
168
+ if (options.version) {
169
+ const versions = await app.getAppStoreVersionsAsync({
170
+ query: {
171
+ limit: 200,
172
+ filter: {
173
+ platform: options.platform,
174
+ appStoreState: [
175
+ apple_utils_1.AppStoreState.PREPARE_FOR_SUBMISSION,
176
+ apple_utils_1.AppStoreState.DEVELOPER_REJECTED,
177
+ apple_utils_1.AppStoreState.REJECTED,
178
+ apple_utils_1.AppStoreState.METADATA_REJECTED,
179
+ apple_utils_1.AppStoreState.WAITING_FOR_REVIEW,
180
+ apple_utils_1.AppStoreState.INVALID_BINARY,
181
+ ].join(','),
182
+ },
183
+ },
184
+ });
185
+ const version = versions.find(model => model.attributes.versionString === options.version);
186
+ if (version) {
187
+ return version;
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+ /**
193
+ * Check if we can reuse an existing editable app version that has not been published yet.
194
+ * If not, it creates a new version based on the version string.
195
+ */
196
+ async function createOrUpdateEditAppStoreVersionAsync(app, options) {
197
+ const version = await app.getEditAppStoreVersionAsync({ platform: options.platform });
198
+ if (version) {
199
+ return await version.updateAsync({ versionString: options.version });
200
+ }
201
+ return await app.createVersionAsync({
202
+ versionString: options.version,
203
+ platform: options.platform,
204
+ });
205
+ }
@@ -1,6 +1,11 @@
1
1
  import { MetadataContext } from '../../context';
2
2
  import { AppleTask } from '../task';
3
+ import { AppVersionOptions } from './app-version';
4
+ declare type AppleTaskOptions = {
5
+ version?: AppVersionOptions['version'];
6
+ };
3
7
  /**
4
8
  * List of all eligible tasks to sync local store configuration to the App store.
5
9
  */
6
- export declare function createAppleTasks(_ctx: MetadataContext): AppleTask[];
10
+ export declare function createAppleTasks(_ctx: MetadataContext, { version }?: AppleTaskOptions): AppleTask[];
11
+ export {};
@@ -8,7 +8,12 @@ const app_version_1 = require("./app-version");
8
8
  /**
9
9
  * List of all eligible tasks to sync local store configuration to the App store.
10
10
  */
11
- function createAppleTasks(_ctx) {
12
- return [new app_version_1.AppVersionTask(), new app_info_1.AppInfoTask(), new age_rating_1.AgeRatingTask(), new app_review_detail_1.AppReviewDetailTask()];
11
+ function createAppleTasks(_ctx, { version } = {}) {
12
+ return [
13
+ new app_version_1.AppVersionTask({ version }),
14
+ new app_info_1.AppInfoTask(),
15
+ new age_rating_1.AgeRatingTask(),
16
+ new app_review_detail_1.AppReviewDetailTask(),
17
+ ];
13
18
  }
14
19
  exports.createAppleTasks = createAppleTasks;
@@ -2,6 +2,7 @@
2
2
  import type { AgeRatingDeclarationProps } from '@expo/apple-utils';
3
3
  export declare type AppleLocale = string;
4
4
  export interface AppleMetadata {
5
+ version?: string;
5
6
  copyright?: string;
6
7
  info?: Record<AppleLocale, AppleInfo>;
7
8
  categories?: AppleCategory;
@@ -14,13 +15,8 @@ export declare type AppleAdvisory = Partial<AgeRatingDeclarationProps>;
14
15
  /** Apps can define up to two categories, or categories with up to two subcategories */
15
16
  export declare type AppleCategory = (string | string[])[];
16
17
  export interface AppleRelease {
17
- isPhasedReleaseEnabled?: boolean;
18
- shouldResetRatings?: boolean;
19
- autoReleaseDate?: number | string;
20
- automaticRelease?: boolean;
21
- usesThirdPartyContent?: boolean;
22
- /** Alternative to setting `ITSAppUsesNonExemptEncryption` in the binary's `Info.plist`. */
23
- usesNonExemptEncryption?: boolean;
18
+ automaticRelease?: boolean | string;
19
+ phasedRelease?: boolean;
24
20
  }
25
21
  export interface AppleInfo {
26
22
  title: string;
@@ -17,6 +17,7 @@ const telemetry_1 = require("./utils/telemetry");
17
17
  * Note, only App Store is supported at this time.
18
18
  */
19
19
  async function uploadMetadataAsync(metadataCtx) {
20
+ var _a;
20
21
  const filePath = path_1.default.resolve(metadataCtx.projectDir, metadataCtx.metadataPath);
21
22
  if (!(await fs_extra_1.default.pathExists(filePath))) {
22
23
  throw new errors_1.MetadataValidationError(`Store configuration file not found "${filePath}"`);
@@ -41,7 +42,11 @@ async function uploadMetadataAsync(metadataCtx) {
41
42
  log_1.default.log('Uploading App Store configuration...');
42
43
  const errors = [];
43
44
  const config = (0, config_1.createAppleReader)(fileData);
44
- const tasks = (0, tasks_1.createAppleTasks)(metadataCtx);
45
+ const tasks = (0, tasks_1.createAppleTasks)(metadataCtx, {
46
+ // We need to resolve a different version as soon as possible.
47
+ // This version is the parent model of all changes we are going to push.
48
+ version: (_a = config.getVersion()) === null || _a === void 0 ? void 0 : _a.versionString,
49
+ });
45
50
  const taskCtx = { app };
46
51
  for (const task of tasks) {
47
52
  try {
@@ -76,6 +76,8 @@ declare type AssetUploadResult = {
76
76
  assetCount: number;
77
77
  uniqueAssetCount: number;
78
78
  uniqueUploadedAssetCount: number;
79
+ assetLimitPerUpdateGroup: number;
79
80
  };
80
- export declare function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAssets, updateSpinnerText?: (totalAssets: number, missingAssets: number) => void): Promise<AssetUploadResult>;
81
+ export declare function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAssets, projectId: string, updateSpinnerText?: (totalAssets: number, missingAssets: number) => void): Promise<AssetUploadResult>;
82
+ export declare function isUploadedAssetCountAboveWarningThreshold(uploadedAssetCount: number, assetLimitPerUpdateGroup: number): boolean;
81
83
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
3
+ exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const json_file_1 = tslib_1.__importDefault(require("@expo/json-file"));
6
6
  const crypto_1 = tslib_1.__importDefault(require("crypto"));
@@ -184,7 +184,7 @@ async function filterOutAssetsThatAlreadyExistAsync(uniqueAssetsWithStorageKey)
184
184
  return missingAssets;
185
185
  }
186
186
  exports.filterOutAssetsThatAlreadyExistAsync = filterOutAssetsThatAlreadyExistAsync;
187
- async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
187
+ async function uploadAssetsAsync(assetsForUpdateInfoGroup, projectId, updateSpinnerText) {
188
188
  let assets = [];
189
189
  let platform;
190
190
  for (platform in assetsForUpdateInfoGroup) {
@@ -208,12 +208,15 @@ async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
208
208
  const { specifications } = await PublishMutation_1.PublishMutation.getUploadURLsAsync(missingAssets.map(ma => ma.contentType));
209
209
  updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(totalAssets, missingAssets.length);
210
210
  const assetUploadPromiseLimit = (0, promise_limit_1.default)(15);
211
- await Promise.all(missingAssets.map((missingAsset, i) => {
212
- assetUploadPromiseLimit(async () => {
213
- const presignedPost = JSON.parse(specifications[i]);
214
- await (0, uploads_1.uploadWithPresignedPostAsync)(missingAsset.path, presignedPost);
215
- });
216
- }));
211
+ const [assetLimitPerUpdateGroup] = await Promise.all([
212
+ PublishQuery_1.PublishQuery.getAssetLimitPerUpdateGroupAsync(projectId),
213
+ missingAssets.map((missingAsset, i) => {
214
+ assetUploadPromiseLimit(async () => {
215
+ const presignedPost = JSON.parse(specifications[i]);
216
+ await (0, uploads_1.uploadWithPresignedPostAsync)(missingAsset.path, presignedPost);
217
+ });
218
+ }),
219
+ ]);
217
220
  let timeout = 1;
218
221
  while (missingAssets.length > 0) {
219
222
  const timeoutPromise = new Promise(resolve => setTimeout(resolve, Math.min(timeout * 1000, 5000))); // linear backoff
@@ -226,6 +229,12 @@ async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
226
229
  assetCount: assets.length,
227
230
  uniqueAssetCount: uniqueAssets.length,
228
231
  uniqueUploadedAssetCount,
232
+ assetLimitPerUpdateGroup,
229
233
  };
230
234
  }
231
235
  exports.uploadAssetsAsync = uploadAssetsAsync;
236
+ function isUploadedAssetCountAboveWarningThreshold(uploadedAssetCount, assetLimitPerUpdateGroup) {
237
+ const warningThreshold = Math.floor(assetLimitPerUpdateGroup * 0.75);
238
+ return uploadedAssetCount > warningThreshold;
239
+ }
240
+ exports.isUploadedAssetCountAboveWarningThreshold = isUploadedAssetCountAboveWarningThreshold;
@@ -1,6 +1,8 @@
1
1
  import { ExpoConfig } from '@expo/config';
2
2
  import { Platform } from '@expo/eas-build-job';
3
- import { EasJsonReader } from '@expo/eas-json';
4
- export declare function ensureRemoteVersionPolicyAsync(projectDir: string, easJsonReader: EasJsonReader): Promise<void>;
5
- export declare function validateAppConfigForRemoteVersionPolicyAsync(exp: ExpoConfig): Promise<void>;
3
+ import { EasJson, EasJsonReader } from '@expo/eas-json';
4
+ import { ProfileData } from '../utils/profiles';
5
+ export declare function ensureVersionSourceIsRemoteAsync(projectDir: string, easJsonReader: EasJsonReader): Promise<void>;
6
+ export declare function validateBuildProfileVersionSettings(profileInfo: ProfileData<'build'>, cliConfig: EasJson['cli']): void;
7
+ export declare function validateAppConfigForRemoteVersionSource(exp: ExpoConfig, platform: Platform): void;
6
8
  export declare function getBuildVersionName(platform: Platform): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getBuildVersionName = exports.validateAppConfigForRemoteVersionPolicyAsync = exports.ensureRemoteVersionPolicyAsync = void 0;
3
+ exports.getBuildVersionName = exports.validateAppConfigForRemoteVersionSource = exports.validateBuildProfileVersionSettings = exports.ensureVersionSourceIsRemoteAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const eas_build_job_1 = require("@expo/eas-build-job");
6
6
  const eas_json_1 = require("@expo/eas-json");
@@ -8,7 +8,7 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
8
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
9
9
  const log_1 = tslib_1.__importDefault(require("../log"));
10
10
  const prompts_1 = require("../prompts");
11
- async function ensureRemoteVersionPolicyAsync(projectDir, easJsonReader) {
11
+ async function ensureVersionSourceIsRemoteAsync(projectDir, easJsonReader) {
12
12
  const easJsonCliConfig = await easJsonReader.getCliConfigAsync();
13
13
  if ((easJsonCliConfig === null || easJsonCliConfig === void 0 ? void 0 : easJsonCliConfig.appVersionSource) === eas_json_1.AppVersionSource.REMOTE) {
14
14
  return;
@@ -27,20 +27,29 @@ async function ensureRemoteVersionPolicyAsync(projectDir, easJsonReader) {
27
27
  await fs_extra_1.default.writeFile(easJsonPath, `${JSON.stringify(easJson, null, 2)}\n`);
28
28
  log_1.default.withTick('Updated eas.json');
29
29
  }
30
- exports.ensureRemoteVersionPolicyAsync = ensureRemoteVersionPolicyAsync;
31
- async function validateAppConfigForRemoteVersionPolicyAsync(exp) {
30
+ exports.ensureVersionSourceIsRemoteAsync = ensureVersionSourceIsRemoteAsync;
31
+ function validateBuildProfileVersionSettings(profileInfo, cliConfig) {
32
+ if ((cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.appVersionSource) !== eas_json_1.AppVersionSource.REMOTE) {
33
+ return;
34
+ }
35
+ if (profileInfo.profile.autoIncrement === 'version') {
36
+ throw new Error(`${chalk_1.default.bold('{"autoIncrement": "version"}')} is not supported when app version source is set to remote.`);
37
+ }
38
+ }
39
+ exports.validateBuildProfileVersionSettings = validateBuildProfileVersionSettings;
40
+ function validateAppConfigForRemoteVersionSource(exp, platform) {
32
41
  var _a, _b, _c;
33
42
  if (typeof exp.runtimeVersion === 'object' && ((_a = exp.runtimeVersion) === null || _a === void 0 ? void 0 : _a.policy) === 'nativeVersion') {
34
43
  throw new Error(`${chalk_1.default.bold('nativeVersion')} policy for ${chalk_1.default.bold('runtimeVersion')} is currently not supported when version source is set to remote. Switch policy e.g. to ${chalk_1.default.bold('appVersion')} or define version explicitly.`);
35
44
  }
36
- if (((_b = exp.ios) === null || _b === void 0 ? void 0 : _b.buildNumber) !== undefined) {
37
- throw new Error(`${chalk_1.default.bold('ios.buildNumber')} field in app config is not supported when version source is set to remote, remove it and re-run the command.`);
45
+ if (platform === eas_build_job_1.Platform.IOS && ((_b = exp.ios) === null || _b === void 0 ? void 0 : _b.buildNumber) !== undefined) {
46
+ log_1.default.warn(`${chalk_1.default.bold('ios.buildNumber')} field in app config is ignored when version source is set to remote, but this value will still be in the manifest available via ${chalk_1.default.bold('expo-constants')}. It's recommended to remove this value from app config.`);
38
47
  }
39
- if (((_c = exp.android) === null || _c === void 0 ? void 0 : _c.versionCode) !== undefined) {
40
- throw new Error(`${chalk_1.default.bold('android.versionCode')} field in app config is not supported when version source is set to remote, remove it and re-run the command.`);
48
+ if (platform === eas_build_job_1.Platform.ANDROID && ((_c = exp.android) === null || _c === void 0 ? void 0 : _c.versionCode) !== undefined) {
49
+ log_1.default.warn(`${chalk_1.default.bold('android.versionCode')} field in app config is ignored when version source is set to remote, but this value will still be in the manifest available via ${chalk_1.default.bold('expo-constants')}. It's recommended to remove this value from app config.`);
41
50
  }
42
51
  }
43
- exports.validateAppConfigForRemoteVersionPolicyAsync = validateAppConfigForRemoteVersionPolicyAsync;
52
+ exports.validateAppConfigForRemoteVersionSource = validateAppConfigForRemoteVersionSource;
44
53
  function getBuildVersionName(platform) {
45
54
  if (platform === eas_build_job_1.Platform.ANDROID) {
46
55
  return 'versionCode';
@@ -4,4 +4,5 @@ import { SubmissionContext } from './context';
4
4
  export declare function submitAsync<T extends Platform>(ctx: SubmissionContext<T>): Promise<SubmissionFragment>;
5
5
  export declare function waitToCompleteAsync(submissions: SubmissionFragment[], { verbose }?: {
6
6
  verbose?: boolean;
7
- }): Promise<void>;
7
+ }): Promise<SubmissionFragment[]>;
8
+ export declare function exitWithNonZeroCodeIfSomeSubmissionsDidntFinish(submissions: SubmissionFragment[]): void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.waitToCompleteAsync = exports.submitAsync = void 0;
3
+ exports.exitWithNonZeroCodeIfSomeSubmissionsDidntFinish = exports.waitToCompleteAsync = exports.submitAsync = 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 = tslib_1.__importDefault(require("chalk"));
@@ -49,7 +49,7 @@ async function waitToCompleteAsync(submissions, { verbose = false } = {}) {
49
49
  log_1.default.newLine();
50
50
  }
51
51
  }
52
- exitWithNonZeroCodeIfSomeSubmissionsDidntFinish(completedSubmissions);
52
+ return completedSubmissions;
53
53
  }
54
54
  exports.waitToCompleteAsync = waitToCompleteAsync;
55
55
  function printInstructionsForAndroidSubmission(submission) {
@@ -79,3 +79,4 @@ function exitWithNonZeroCodeIfSomeSubmissionsDidntFinish(submissions) {
79
79
  process.exit(1);
80
80
  }
81
81
  }
82
+ exports.exitWithNonZeroCodeIfSomeSubmissionsDidntFinish = exitWithNonZeroCodeIfSomeSubmissionsDidntFinish;
@@ -4,4 +4,5 @@ export default class GitNoCommitClient extends GitClient {
4
4
  getRootPathAsync(): Promise<string>;
5
5
  makeShallowCopyAsync(destinationPath: string): Promise<void>;
6
6
  isFileIgnoredAsync(filePath: string): Promise<boolean>;
7
+ trackFileAsync(file: string): Promise<void>;
7
8
  }
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
6
  const path_1 = tslib_1.__importDefault(require("path"));
7
+ const log_1 = tslib_1.__importDefault(require("../../log"));
6
8
  const local_1 = require("../local");
7
9
  const git_1 = tslib_1.__importDefault(require("./git"));
8
10
  class GitNoCommitClient extends git_1.default {
@@ -23,5 +25,17 @@ class GitNoCommitClient extends git_1.default {
23
25
  await ignore.initIgnoreAsync();
24
26
  return ignore.ignores(filePath);
25
27
  }
28
+ async trackFileAsync(file) {
29
+ try {
30
+ await super.trackFileAsync(file);
31
+ }
32
+ catch {
33
+ // In the no commit workflow it doesn't matter if we fail to track changes,
34
+ // so we can ignore if this throws an exception
35
+ log_1.default.warn(`Unable to track ${chalk_1.default.bold(path_1.default.basename(file))} in Git. Proceeding without tracking.`);
36
+ log_1.default.warn(` Reason: the command ${chalk_1.default.bold(`"git add ${file}"`)} exited with an error.`);
37
+ log_1.default.newLine();
38
+ }
39
+ }
26
40
  }
27
41
  exports.default = GitNoCommitClient;