eas-cli 0.55.1 → 0.56.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 (47) hide show
  1. package/README.md +44 -44
  2. package/build/build/android/version.d.ts +5 -0
  3. package/build/build/android/version.js +16 -9
  4. package/build/build/build.js +7 -2
  5. package/build/build/context.d.ts +2 -3
  6. package/build/build/createContext.d.ts +3 -2
  7. package/build/build/createContext.js +2 -1
  8. package/build/build/ios/build.js +1 -16
  9. package/build/build/ios/syncProjectConfiguration.d.ts +3 -3
  10. package/build/build/ios/syncProjectConfiguration.js +2 -2
  11. package/build/build/ios/version.d.ts +10 -3
  12. package/build/build/ios/version.js +57 -28
  13. package/build/build/metadata.js +1 -1
  14. package/build/build/runBuildAndSubmit.js +7 -4
  15. package/build/commands/build/version/set.d.ts +10 -0
  16. package/build/commands/build/version/set.js +82 -0
  17. package/build/commands/build/version/sync.d.ts +12 -0
  18. package/build/commands/build/version/sync.js +124 -0
  19. package/build/commands/update/index.js +3 -1
  20. package/build/credentials/ios/types.d.ts +2 -0
  21. package/build/graphql/generated.d.ts +87 -2
  22. package/build/graphql/generated.js +1 -0
  23. package/build/graphql/mutations/AppVersionMutation.d.ts +11 -0
  24. package/build/graphql/mutations/AppVersionMutation.js +28 -0
  25. package/build/graphql/queries/AppVersionQuery.d.ts +4 -0
  26. package/build/graphql/queries/AppVersionQuery.js +37 -0
  27. package/build/platform.d.ts +1 -0
  28. package/build/platform.js +17 -1
  29. package/build/project/android/applicationId.js +2 -2
  30. package/build/project/android/versions.d.ts +3 -0
  31. package/build/project/android/versions.js +23 -0
  32. package/build/project/applicationIdentifier.d.ts +4 -0
  33. package/build/project/applicationIdentifier.js +37 -0
  34. package/build/project/ios/bundleIdentifier.js +2 -2
  35. package/build/project/ios/target.js +14 -1
  36. package/build/project/ios/versions.d.ts +3 -0
  37. package/build/project/ios/versions.js +17 -0
  38. package/build/project/publish.d.ts +1 -2
  39. package/build/project/publish.js +7 -11
  40. package/build/project/remoteVersionSource.d.ts +6 -0
  41. package/build/project/remoteVersionSource.js +52 -0
  42. package/build/submit/utils/files.d.ts +0 -6
  43. package/build/submit/utils/files.js +3 -16
  44. package/build/uploads.d.ts +8 -2
  45. package/build/uploads.js +19 -4
  46. package/oclif.manifest.json +1 -1
  47. package/package.json +8 -4
@@ -1,15 +1,16 @@
1
1
  import { ExpoConfig } from '@expo/config';
2
2
  import type { XCBuildConfiguration } from 'xcode';
3
+ import { Target } from '../../credentials/ios/types';
3
4
  export declare enum BumpStrategy {
4
5
  APP_VERSION = 0,
5
6
  BUILD_NUMBER = 1,
6
7
  NOOP = 2
7
8
  }
8
- export declare function bumpVersionAsync({ bumpStrategy, projectDir, exp, buildSettings, }: {
9
+ export declare function bumpVersionAsync({ bumpStrategy, projectDir, exp, targets, }: {
9
10
  projectDir: string;
10
11
  exp: ExpoConfig;
11
12
  bumpStrategy: BumpStrategy;
12
- buildSettings: XCBuildConfiguration['buildSettings'];
13
+ targets: Target[];
13
14
  }): Promise<void>;
14
15
  export declare function bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp, }: {
15
16
  bumpStrategy: BumpStrategy;
@@ -18,9 +19,15 @@ export declare function bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, ex
18
19
  }): Promise<void>;
19
20
  export declare function readShortVersionAsync(projectDir: string, exp: ExpoConfig, buildSettings: XCBuildConfiguration['buildSettings']): Promise<string | undefined>;
20
21
  export declare function readBuildNumberAsync(projectDir: string, exp: ExpoConfig, buildSettings: XCBuildConfiguration['buildSettings']): Promise<string | undefined>;
21
- export declare function maybeResolveVersionsAsync(projectDir: string, exp: ExpoConfig, buildSettings: XCBuildConfiguration['buildSettings']): Promise<{
22
+ export declare function maybeResolveVersionsAsync(projectDir: string, exp: ExpoConfig, targets: Target[]): Promise<{
22
23
  appVersion?: string;
23
24
  appBuildVersion?: string;
24
25
  }>;
25
26
  export declare function getInfoPlistPath(projectDir: string, buildSettings: XCBuildConfiguration['buildSettings']): string;
27
+ export declare function updateNativeVersionsAsync({ projectDir, version, buildNumber, targets, }: {
28
+ projectDir: string;
29
+ version?: string;
30
+ buildNumber?: string;
31
+ targets: Target[];
32
+ }): Promise<void>;
26
33
  export declare function evaluateTemplateString(s: string, buildSettings: XCBuildConfiguration['buildSettings']): string;
@@ -1,15 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.evaluateTemplateString = exports.getInfoPlistPath = exports.maybeResolveVersionsAsync = exports.readBuildNumberAsync = exports.readShortVersionAsync = exports.bumpVersionInAppJsonAsync = exports.bumpVersionAsync = exports.BumpStrategy = void 0;
3
+ exports.evaluateTemplateString = exports.updateNativeVersionsAsync = exports.getInfoPlistPath = exports.maybeResolveVersionsAsync = exports.readBuildNumberAsync = exports.readShortVersionAsync = exports.bumpVersionInAppJsonAsync = exports.bumpVersionAsync = exports.BumpStrategy = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const config_1 = require("@expo/config");
6
5
  const config_plugins_1 = require("@expo/config-plugins");
7
6
  const eas_build_job_1 = require("@expo/eas-build-job");
8
7
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
9
8
  const path_1 = tslib_1.__importDefault(require("path"));
10
9
  const log_1 = tslib_1.__importDefault(require("../../log"));
10
+ const target_1 = require("../../project/ios/target");
11
+ const versions_1 = require("../../project/ios/versions");
11
12
  const workflow_1 = require("../../project/workflow");
12
13
  const prompts_1 = require("../../prompts");
14
+ const uniqBy_1 = tslib_1.__importDefault(require("../../utils/expodash/uniqBy"));
13
15
  const plist_1 = require("../../utils/plist");
14
16
  const appJson_1 = require("../utils/appJson");
15
17
  const version_1 = require("../utils/version");
@@ -19,15 +21,20 @@ var BumpStrategy;
19
21
  BumpStrategy[BumpStrategy["BUILD_NUMBER"] = 1] = "BUILD_NUMBER";
20
22
  BumpStrategy[BumpStrategy["NOOP"] = 2] = "NOOP";
21
23
  })(BumpStrategy = exports.BumpStrategy || (exports.BumpStrategy = {}));
22
- async function bumpVersionAsync({ bumpStrategy, projectDir, exp, buildSettings, }) {
24
+ async function bumpVersionAsync({ bumpStrategy, projectDir, exp, targets, }) {
25
+ var _a;
23
26
  if (bumpStrategy === BumpStrategy.NOOP) {
24
27
  return;
25
28
  }
26
- ensureStaticConfigExists(projectDir);
27
- const infoPlist = await readInfoPlistAsync(projectDir, buildSettings);
29
+ (0, version_1.ensureStaticConfigExists)(projectDir);
28
30
  await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
29
31
  log_1.default.log('Updated versions in app.json');
30
- await writeVersionsToInfoPlistAsync({ projectDir, exp, infoPlist, buildSettings });
32
+ await updateNativeVersionsAsync({
33
+ projectDir,
34
+ version: exp.version,
35
+ buildNumber: (_a = exp.ios) === null || _a === void 0 ? void 0 : _a.buildNumber,
36
+ targets,
37
+ });
31
38
  log_1.default.log('Synchronized versions with Info.plist');
32
39
  }
33
40
  exports.bumpVersionAsync = bumpVersionAsync;
@@ -35,7 +42,7 @@ async function bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp, }) {
35
42
  if (bumpStrategy === BumpStrategy.NOOP) {
36
43
  return;
37
44
  }
38
- ensureStaticConfigExists(projectDir);
45
+ (0, version_1.ensureStaticConfigExists)(projectDir);
39
46
  log_1.default.addNewLineIfNone();
40
47
  if (bumpStrategy === BumpStrategy.APP_VERSION) {
41
48
  const appVersion = config_plugins_1.IOSConfig.Version.getVersion(exp);
@@ -43,10 +50,8 @@ async function bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp, }) {
43
50
  }
44
51
  else {
45
52
  const buildNumber = config_plugins_1.IOSConfig.Version.getBuildNumber(exp);
46
- if (buildNumber.match(/^\d+(\.\d+)*$/)) {
47
- const comps = buildNumber.split('.');
48
- comps[comps.length - 1] = String(Number(comps[comps.length - 1]) + 1);
49
- const bumpedBuildNumber = comps.join('.');
53
+ if ((0, versions_1.isValidBuildNumber)(buildNumber)) {
54
+ const bumpedBuildNumber = (0, versions_1.getNextBuildNumber)(buildNumber);
50
55
  log_1.default.log(`Bumping ${chalk_1.default.bold('expo.ios.buildNumber')} from ${chalk_1.default.bold(buildNumber)} to ${chalk_1.default.bold(bumpedBuildNumber)}`);
51
56
  await (0, appJson_1.updateAppJsonConfigAsync)({ projectDir, exp }, config => {
52
57
  config.ios = { ...config.ios, buildNumber: String(bumpedBuildNumber) };
@@ -89,11 +94,13 @@ async function readBuildNumberAsync(projectDir, exp, buildSettings) {
89
94
  }
90
95
  }
91
96
  exports.readBuildNumberAsync = readBuildNumberAsync;
92
- async function maybeResolveVersionsAsync(projectDir, exp, buildSettings) {
97
+ async function maybeResolveVersionsAsync(projectDir, exp, targets) {
98
+ var _a, _b;
99
+ const applicationTarget = (0, target_1.findApplicationTarget)(targets);
93
100
  try {
94
101
  return {
95
- appBuildVersion: await readBuildNumberAsync(projectDir, exp, buildSettings),
96
- appVersion: await readShortVersionAsync(projectDir, exp, buildSettings),
102
+ appBuildVersion: await readBuildNumberAsync(projectDir, exp, (_a = applicationTarget.buildSettings) !== null && _a !== void 0 ? _a : {}),
103
+ appVersion: await readShortVersionAsync(projectDir, exp, (_b = applicationTarget.buildSettings) !== null && _b !== void 0 ? _b : {}),
97
104
  };
98
105
  }
99
106
  catch (err) {
@@ -105,12 +112,6 @@ async function maybeResolveVersionsAsync(projectDir, exp, buildSettings) {
105
112
  }
106
113
  }
107
114
  exports.maybeResolveVersionsAsync = maybeResolveVersionsAsync;
108
- async function writeVersionsToInfoPlistAsync({ projectDir, exp, infoPlist, buildSettings, }) {
109
- let updatedInfoPlist = config_plugins_1.IOSConfig.Version.setVersion(exp, infoPlist);
110
- updatedInfoPlist = config_plugins_1.IOSConfig.Version.setBuildNumber(exp, updatedInfoPlist);
111
- await writeInfoPlistAsync({ projectDir, infoPlist: updatedInfoPlist, buildSettings });
112
- return updatedInfoPlist;
113
- }
114
115
  function getInfoPlistPath(projectDir, buildSettings) {
115
116
  if (buildSettings.INFOPLIST_FILE) {
116
117
  const infoPlistFile = buildSettings.INFOPLIST_FILE.startsWith('"')
@@ -133,16 +134,44 @@ async function readInfoPlistAsync(projectDir, buildSettings) {
133
134
  const infoPlistPath = getInfoPlistPath(projectDir, buildSettings);
134
135
  return ((_a = (await (0, plist_1.readPlistAsync)(infoPlistPath))) !== null && _a !== void 0 ? _a : {});
135
136
  }
136
- async function writeInfoPlistAsync({ projectDir, infoPlist, buildSettings, }) {
137
- const infoPlistPath = getInfoPlistPath(projectDir, buildSettings);
138
- await (0, plist_1.writePlistAsync)(infoPlistPath, infoPlist);
139
- }
140
- function ensureStaticConfigExists(projectDir) {
141
- const paths = (0, config_1.getConfigFilePaths)(projectDir);
142
- if (!paths.staticConfigPath) {
143
- throw new Error('autoIncrement option is not supported when using app.config.js');
137
+ async function updateNativeVersionsAsync({ projectDir, version, buildNumber, targets, }) {
138
+ var _a;
139
+ const project = config_plugins_1.IOSConfig.XcodeUtils.getPbxproj(projectDir);
140
+ const iosDir = path_1.default.join(projectDir, 'ios');
141
+ const infoPlistFiles = [];
142
+ for (const target of targets) {
143
+ const { targetName, buildConfiguration } = target;
144
+ const xcBuildConfiguration = config_plugins_1.IOSConfig.Target.getXCBuildConfigurationFromPbxproj(project, {
145
+ targetName,
146
+ buildConfiguration,
147
+ });
148
+ const infoPlist = (_a = xcBuildConfiguration === null || xcBuildConfiguration === void 0 ? void 0 : xcBuildConfiguration.buildSettings) === null || _a === void 0 ? void 0 : _a.INFOPLIST_FILE;
149
+ if (infoPlist) {
150
+ const evaluatedInfoPlistPath = trimQuotes(evaluateTemplateString(infoPlist, {
151
+ SRCROOT: iosDir,
152
+ }));
153
+ const absolutePath = path_1.default.isAbsolute(evaluatedInfoPlistPath)
154
+ ? evaluatedInfoPlistPath
155
+ : path_1.default.join(iosDir, evaluatedInfoPlistPath);
156
+ infoPlistFiles.push(path_1.default.normalize(absolutePath));
157
+ }
158
+ }
159
+ const uniqueInfoPlistPaths = (0, uniqBy_1.default)(infoPlistFiles, i => i);
160
+ for (const infoPlistPath of uniqueInfoPlistPaths) {
161
+ const infoPlist = (await (0, plist_1.readPlistAsync)(infoPlistPath));
162
+ if (buildNumber) {
163
+ infoPlist.CFBundleVersion = buildNumber;
164
+ }
165
+ if (version) {
166
+ infoPlist.CFBundleShortVersionString = version;
167
+ }
168
+ await (0, plist_1.writePlistAsync)(infoPlistPath, infoPlist);
144
169
  }
145
170
  }
171
+ exports.updateNativeVersionsAsync = updateNativeVersionsAsync;
172
+ function trimQuotes(s) {
173
+ return (s === null || s === void 0 ? void 0 : s.startsWith('"')) && s.endsWith('"') ? s.slice(1, -1) : s;
174
+ }
146
175
  function evaluateTemplateString(s, buildSettings) {
147
176
  // necessary because XCBuildConfiguration['buildSettings'] is not a plain object
148
177
  const vars = { ...buildSettings };
@@ -48,7 +48,7 @@ exports.collectMetadataAsync = collectMetadataAsync;
48
48
  async function maybeResolveVersionsAsync(ctx) {
49
49
  if (ctx.platform === eas_build_job_1.Platform.IOS) {
50
50
  const iosContext = ctx;
51
- return await (0, version_2.maybeResolveVersionsAsync)(ctx.projectDir, ctx.exp, iosContext.ios.applicationTargetBuildSettings);
51
+ return await (0, version_2.maybeResolveVersionsAsync)(ctx.projectDir, ctx.exp, iosContext.ios.targets);
52
52
  }
53
53
  else if (ctx.platform === eas_build_job_1.Platform.ANDROID) {
54
54
  const androidCtx = ctx;
@@ -40,7 +40,7 @@ const platformToGraphQLResourceClassMapping = {
40
40
  },
41
41
  };
42
42
  async function runBuildAndSubmitAsync(projectDir, flags) {
43
- var _a, _b;
43
+ var _a, _b, _c;
44
44
  await (0, vcs_1.getVcsClient)().ensureRepoExistsAsync();
45
45
  await (0, repository_1.ensureRepoIsCleanAsync)(flags.nonInteractive);
46
46
  await (0, configure_1.ensureProjectConfiguredAsync)({
@@ -48,12 +48,13 @@ async function runBuildAndSubmitAsync(projectDir, flags) {
48
48
  nonInteractive: flags.nonInteractive,
49
49
  });
50
50
  const easJsonReader = new eas_json_1.EasJsonReader(projectDir);
51
+ const easJsonCliConfig = (_a = (await easJsonReader.getCliConfigAsync())) !== null && _a !== void 0 ? _a : {};
51
52
  const platforms = (0, platform_1.toPlatforms)(flags.requestedPlatform);
52
53
  const buildProfiles = await (0, profiles_1.getProfilesAsync)({
53
54
  type: 'build',
54
55
  easJsonReader,
55
56
  platforms,
56
- profileName: (_a = flags.profile) !== null && _a !== void 0 ? _a : undefined,
57
+ profileName: (_b = flags.profile) !== null && _b !== void 0 ? _b : undefined,
57
58
  });
58
59
  await (0, devClient_1.ensureExpoDevClientInstalledForDevClientBuildsAsync)({
59
60
  projectDir,
@@ -68,7 +69,8 @@ async function runBuildAndSubmitAsync(projectDir, flags) {
68
69
  flags,
69
70
  moreBuilds: platforms.length > 1,
70
71
  buildProfile,
71
- resourceClass: platformToGraphQLResourceClassMapping[buildProfile.platform][(_b = flags.userInputResourceClass) !== null && _b !== void 0 ? _b : types_1.UserInputResourceClass.DEFAULT],
72
+ resourceClass: platformToGraphQLResourceClassMapping[buildProfile.platform][(_c = flags.userInputResourceClass) !== null && _c !== void 0 ? _c : types_1.UserInputResourceClass.DEFAULT],
73
+ easJsonCliConfig,
72
74
  });
73
75
  if (maybeBuild) {
74
76
  startedBuilds.push({ build: maybeBuild, buildProfile });
@@ -128,7 +130,7 @@ async function runBuildAndSubmitAsync(projectDir, flags) {
128
130
  }
129
131
  }
130
132
  exports.runBuildAndSubmitAsync = runBuildAndSubmitAsync;
131
- async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildProfile, resourceClass, }) {
133
+ async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildProfile, resourceClass, easJsonCliConfig, }) {
132
134
  const buildCtx = await (0, createContext_1.createBuildContextAsync)({
133
135
  buildProfileName: buildProfile.profileName,
134
136
  resourceClass,
@@ -138,6 +140,7 @@ async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildP
138
140
  platform: buildProfile.platform,
139
141
  projectDir,
140
142
  localBuildOptions: flags.localBuildOptions,
143
+ easJsonCliConfig,
141
144
  });
142
145
  if (moreBuilds) {
143
146
  log_1.default.newLine();
@@ -0,0 +1,10 @@
1
+ import EasCommand from '../../../commandUtils/EasCommand';
2
+ export default class BuildVersionSetView extends EasCommand {
3
+ static description: string;
4
+ static hidden: boolean;
5
+ static flags: {
6
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
7
+ profile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ };
9
+ runAsync(): Promise<void>;
10
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const Updates_1 = require("@expo/config-plugins/build/utils/Updates");
5
+ const eas_build_job_1 = require("@expo/eas-build-job");
6
+ const eas_json_1 = require("@expo/eas-json");
7
+ const core_1 = require("@oclif/core");
8
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
9
+ const EasCommand_1 = tslib_1.__importDefault(require("../../../commandUtils/EasCommand"));
10
+ const AppVersionMutation_1 = require("../../../graphql/mutations/AppVersionMutation");
11
+ const AppVersionQuery_1 = require("../../../graphql/queries/AppVersionQuery");
12
+ const AppPlatform_1 = require("../../../graphql/types/AppPlatform");
13
+ const log_1 = tslib_1.__importDefault(require("../../../log"));
14
+ const platform_1 = require("../../../platform");
15
+ const versions_1 = require("../../../project/android/versions");
16
+ const applicationIdentifier_1 = require("../../../project/applicationIdentifier");
17
+ const expoConfig_1 = require("../../../project/expoConfig");
18
+ const versions_2 = require("../../../project/ios/versions");
19
+ const projectUtils_1 = require("../../../project/projectUtils");
20
+ const remoteVersionSource_1 = require("../../../project/remoteVersionSource");
21
+ const prompts_1 = require("../../../prompts");
22
+ class BuildVersionSetView extends EasCommand_1.default {
23
+ async runAsync() {
24
+ var _a, _b, _c;
25
+ const { flags } = await this.parse(BuildVersionSetView);
26
+ const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
27
+ const platform = await (0, platform_1.selectPlatformAsync)(flags.platform);
28
+ const easJsonReader = new eas_json_1.EasJsonReader(projectDir);
29
+ await (0, remoteVersionSource_1.ensureRemoteVersionPolicyAsync)(projectDir, easJsonReader);
30
+ const profile = await easJsonReader.getBuildProfileAsync(platform, (_a = flags.profile) !== null && _a !== void 0 ? _a : undefined);
31
+ const exp = (0, expoConfig_1.getExpoConfig)(projectDir, { env: profile.env });
32
+ const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
33
+ const projectFullName = await (0, projectUtils_1.getProjectFullNameAsync)(exp);
34
+ await (0, remoteVersionSource_1.validateAppConfigForRemoteVersionPolicyAsync)(exp);
35
+ const applicationIdentifier = await (0, applicationIdentifier_1.getApplicationIdentifierAsync)(projectDir, exp, profile, platform);
36
+ const remoteVersions = await AppVersionQuery_1.AppVersionQuery.latestVersionAsync(projectId, (0, AppPlatform_1.toAppPlatform)(platform), applicationIdentifier);
37
+ const currentStateMessage = (remoteVersions === null || remoteVersions === void 0 ? void 0 : remoteVersions.buildVersion)
38
+ ? `Project ${chalk_1.default.bold(projectFullName)} with ${getApplicationIdentifierName(platform)} "${applicationIdentifier}" is configured with ${(0, remoteVersionSource_1.getBuildVersionName)(platform)} ${remoteVersions.buildVersion}.`
39
+ : `Project ${chalk_1.default.bold(projectFullName)} with ${getApplicationIdentifierName(platform)} "${applicationIdentifier}" does not have any ${(0, remoteVersionSource_1.getBuildVersionName)(platform)} configured.`;
40
+ const versionPromptMessage = (remoteVersions === null || remoteVersions === void 0 ? void 0 : remoteVersions.buildVersion)
41
+ ? `What version would you like to set?`
42
+ : `What version would you like to initialize it with?`;
43
+ log_1.default.log(currentStateMessage);
44
+ const { version } = await (0, prompts_1.promptAsync)({
45
+ type: platform === eas_build_job_1.Platform.ANDROID ? 'number' : 'text',
46
+ name: 'version',
47
+ message: versionPromptMessage,
48
+ validate: platform === eas_build_job_1.Platform.ANDROID
49
+ ? value => (0, versions_1.isValidVersionCode)(value) || `Invalid value: ${versions_1.VERSION_CODE_REQUIREMENTS}.`
50
+ : value => (0, versions_2.isValidBuildNumber)(value) || `Invalid value: ${versions_2.BUILD_NUMBER_REQUIREMENTS}.`,
51
+ });
52
+ await AppVersionMutation_1.AppVersionMutation.createAppVersionAsync({
53
+ appId: projectId,
54
+ platform: (0, AppPlatform_1.toAppPlatform)(platform),
55
+ applicationIdentifier,
56
+ storeVersion: (_b = exp.version) !== null && _b !== void 0 ? _b : '1.0.0',
57
+ buildVersion: String(version),
58
+ runtimeVersion: (_c = (0, Updates_1.getRuntimeVersionNullable)(exp, platform)) !== null && _c !== void 0 ? _c : undefined,
59
+ });
60
+ }
61
+ }
62
+ exports.default = BuildVersionSetView;
63
+ BuildVersionSetView.description = 'Update version of an app.';
64
+ BuildVersionSetView.hidden = true;
65
+ BuildVersionSetView.flags = {
66
+ platform: core_1.Flags.enum({
67
+ char: 'p',
68
+ options: ['android', 'ios'],
69
+ }),
70
+ profile: core_1.Flags.string({
71
+ description: 'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
72
+ helpValue: 'PROFILE_NAME',
73
+ }),
74
+ };
75
+ function getApplicationIdentifierName(platform) {
76
+ if (platform === eas_build_job_1.Platform.ANDROID) {
77
+ return 'application ID';
78
+ }
79
+ else {
80
+ return 'bundle identifier';
81
+ }
82
+ }
@@ -0,0 +1,12 @@
1
+ import EasCommand from '../../../commandUtils/EasCommand';
2
+ export default class BuildVersionSyncView extends EasCommand {
3
+ static description: string;
4
+ static hidden: boolean;
5
+ static flags: {
6
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
7
+ profile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ };
9
+ runAsync(): Promise<void>;
10
+ private syncIosAsync;
11
+ private syncAndroidAsync;
12
+ }
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const eas_build_job_1 = require("@expo/eas-build-job");
5
+ const eas_json_1 = require("@expo/eas-json");
6
+ const core_1 = require("@oclif/core");
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const version_1 = require("../../../build/android/version");
9
+ const version_2 = require("../../../build/ios/version");
10
+ const EasCommand_1 = tslib_1.__importDefault(require("../../../commandUtils/EasCommand"));
11
+ const AppVersionQuery_1 = require("../../../graphql/queries/AppVersionQuery");
12
+ const AppPlatform_1 = require("../../../graphql/types/AppPlatform");
13
+ const log_1 = tslib_1.__importDefault(require("../../../log"));
14
+ const platform_1 = require("../../../platform");
15
+ const gradleUtils_1 = require("../../../project/android/gradleUtils");
16
+ const versions_1 = require("../../../project/android/versions");
17
+ const applicationIdentifier_1 = require("../../../project/applicationIdentifier");
18
+ const expoConfig_1 = require("../../../project/expoConfig");
19
+ const scheme_1 = require("../../../project/ios/scheme");
20
+ const target_1 = require("../../../project/ios/target");
21
+ const versions_2 = require("../../../project/ios/versions");
22
+ const projectUtils_1 = require("../../../project/projectUtils");
23
+ const remoteVersionSource_1 = require("../../../project/remoteVersionSource");
24
+ const workflow_1 = require("../../../project/workflow");
25
+ const profiles_1 = require("../../../utils/profiles");
26
+ class BuildVersionSyncView extends EasCommand_1.default {
27
+ async runAsync() {
28
+ var _a;
29
+ const { flags } = await this.parse(BuildVersionSyncView);
30
+ const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
31
+ const requestedPlatform = await (0, platform_1.selectRequestedPlatformAsync)(flags.platform);
32
+ const easJsonReader = new eas_json_1.EasJsonReader(projectDir);
33
+ await (0, remoteVersionSource_1.ensureRemoteVersionPolicyAsync)(projectDir, easJsonReader);
34
+ const platforms = (0, platform_1.toPlatforms)(requestedPlatform);
35
+ const buildProfiles = await (0, profiles_1.getProfilesAsync)({
36
+ type: 'build',
37
+ easJsonReader,
38
+ platforms,
39
+ profileName: (_a = flags.profile) !== null && _a !== void 0 ? _a : undefined,
40
+ });
41
+ for (const profileInfo of buildProfiles) {
42
+ const exp = (0, expoConfig_1.getExpoConfig)(projectDir, { env: profileInfo.profile.env });
43
+ const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
44
+ await (0, remoteVersionSource_1.validateAppConfigForRemoteVersionPolicyAsync)(exp);
45
+ const platformDisplayName = platform_1.appPlatformDisplayNames[(0, AppPlatform_1.toAppPlatform)(profileInfo.platform)];
46
+ const applicationIdentifier = await (0, applicationIdentifier_1.getApplicationIdentifierAsync)(projectDir, exp, profileInfo.profile, profileInfo.platform);
47
+ const remoteVersions = await AppVersionQuery_1.AppVersionQuery.latestVersionAsync(projectId, (0, AppPlatform_1.toAppPlatform)(profileInfo.platform), applicationIdentifier);
48
+ const workflow = await (0, workflow_1.resolveWorkflowAsync)(projectDir, profileInfo.platform);
49
+ if (!(remoteVersions === null || remoteVersions === void 0 ? void 0 : remoteVersions.buildVersion)) {
50
+ log_1.default.warn(`Skipping versions sync for ${platformDisplayName}. There are no versions configured on Expo servers, use "eas build:version:set" or run a build to initialize it.`);
51
+ continue;
52
+ }
53
+ if (workflow === eas_build_job_1.Workflow.MANAGED) {
54
+ log_1.default.warn(`The remote value for the ${platformDisplayName} ${(0, remoteVersionSource_1.getBuildVersionName)(profileInfo.platform)} is ${chalk_1.default.bold(remoteVersions === null || remoteVersions === void 0 ? void 0 : remoteVersions.buildVersion)}, but it was not synced to the local project. This command has no effect on projects using managed workflow.`);
55
+ continue;
56
+ }
57
+ if (profileInfo.platform === eas_build_job_1.Platform.ANDROID) {
58
+ this.syncAndroidAsync({
59
+ projectDir,
60
+ exp,
61
+ profile: profileInfo.profile,
62
+ workflow,
63
+ buildVersion: remoteVersions.buildVersion,
64
+ });
65
+ }
66
+ else {
67
+ this.syncIosAsync({
68
+ projectDir,
69
+ exp,
70
+ profile: profileInfo.profile,
71
+ workflow,
72
+ buildVersion: remoteVersions.buildVersion,
73
+ });
74
+ }
75
+ log_1.default.withTick(`Successfully updated the ${platformDisplayName} ${(0, remoteVersionSource_1.getBuildVersionName)(profileInfo.platform)} in native code to ${chalk_1.default.bold(remoteVersions === null || remoteVersions === void 0 ? void 0 : remoteVersions.buildVersion)}.`);
76
+ }
77
+ }
78
+ async syncIosAsync({ workflow, projectDir, exp, profile, buildVersion, }) {
79
+ const xcodeBuildContext = await (0, scheme_1.resolveXcodeBuildContextAsync)({ exp, projectDir, nonInteractive: false }, profile);
80
+ const targets = await (0, target_1.resolveTargetsAsync)({
81
+ projectDir,
82
+ exp,
83
+ xcodeBuildContext,
84
+ env: profile.env,
85
+ });
86
+ if (!(0, versions_2.isValidBuildNumber)(buildVersion)) {
87
+ throw new Error(`Invalid buildNumber (${buildVersion}), ${versions_2.BUILD_NUMBER_REQUIREMENTS}.`);
88
+ }
89
+ if (workflow === eas_build_job_1.Workflow.GENERIC) {
90
+ await (0, version_2.updateNativeVersionsAsync)({
91
+ projectDir,
92
+ buildNumber: buildVersion,
93
+ targets,
94
+ });
95
+ }
96
+ }
97
+ async syncAndroidAsync({ projectDir, workflow, buildVersion, }) {
98
+ var _a, _b;
99
+ if (!(0, versions_1.isValidVersionCode)(buildVersion)) {
100
+ throw new Error(`Invalid versionCode (${buildVersion}), ${versions_1.VERSION_CODE_REQUIREMENTS}.`);
101
+ }
102
+ if (workflow === eas_build_job_1.Workflow.GENERIC) {
103
+ const buildGradle = await (0, gradleUtils_1.getAppBuildGradleAsync)(projectDir);
104
+ const isMultiFlavor = ((_a = buildGradle.android) === null || _a === void 0 ? void 0 : _a.productFlavors) || ((_b = buildGradle.android) === null || _b === void 0 ? void 0 : _b.flavorDimensions);
105
+ if (isMultiFlavor) {
106
+ throw new Error("Versions in native code can't be automatically synced in multi-flavor Android projects. If you are using EAS Build with app version source set to remote, the correct values will be injected at the build time.");
107
+ }
108
+ await (0, version_1.updateNativeVersionsAsync)({ projectDir, versionCode: Number(buildVersion) });
109
+ }
110
+ }
111
+ }
112
+ exports.default = BuildVersionSyncView;
113
+ BuildVersionSyncView.description = 'Update a version in native code with a value stored on EAS servers';
114
+ BuildVersionSyncView.hidden = true;
115
+ BuildVersionSyncView.flags = {
116
+ platform: core_1.Flags.enum({
117
+ char: 'p',
118
+ options: ['android', 'ios', 'all'],
119
+ }),
120
+ profile: core_1.Flags.string({
121
+ description: 'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
122
+ helpValue: 'PROFILE_NAME',
123
+ }),
124
+ };
@@ -265,7 +265,9 @@ class UpdatePublish extends EasCommand_1.default {
265
265
  try {
266
266
  const platforms = platformFlag === 'all' ? exports.defaultPublishPlatforms : [platformFlag];
267
267
  const assets = await (0, publish_1.collectAssetsAsync)({ inputDir: inputDir, platforms });
268
- const { uniqueUploadedAssetCount } = await (0, publish_1.uploadAssetsAsync)(assets, spinnerText => (assetSpinner.text = `Uploading assets... ${spinnerText}`));
268
+ const { uniqueUploadedAssetCount } = await (0, publish_1.uploadAssetsAsync)(assets, (totalAssets, missingAssets) => {
269
+ assetSpinner.text = `Uploading assets. Finished (${totalAssets - missingAssets}/${totalAssets})`;
270
+ });
269
271
  uploadedAssetCount = uniqueUploadedAssetCount;
270
272
  unsortedUpdateInfoGroups = await (0, publish_1.buildUnsortedUpdateInfoGroupAsync)(assets, exp);
271
273
  const uploadAssetSuccessMessage = uploadedAssetCount
@@ -1,4 +1,5 @@
1
1
  import { JSONObject } from '@expo/json-file';
2
+ import type { XCBuildConfiguration } from 'xcode';
2
3
  import { CommonIosAppCredentialsFragment, IosAppBuildCredentialsFragment } from '../../graphql/generated';
3
4
  import { Account } from '../../user/Account';
4
5
  export interface App {
@@ -11,6 +12,7 @@ export interface Target {
11
12
  bundleIdentifier: string;
12
13
  parentBundleIdentifier?: string;
13
14
  entitlements: JSONObject;
15
+ buildSettings?: XCBuildConfiguration['buildSettings'];
14
16
  }
15
17
  export interface TargetCredentials {
16
18
  distributionCertificate: {
@@ -709,6 +709,7 @@ export declare type App = Project & {
709
709
  isLikedByMe: Scalars['Boolean'];
710
710
  /** @deprecated No longer supported */
711
711
  lastPublishedTime: Scalars['DateTime'];
712
+ latestAppVersionByPlatformAndApplicationIdentifier?: Maybe<AppVersion>;
712
713
  latestReleaseForReleaseChannel?: Maybe<AppRelease>;
713
714
  /** ID of latest classic update release */
714
715
  latestReleaseId: Scalars['ID'];
@@ -812,6 +813,11 @@ export declare type AppIosAppCredentialsArgs = {
812
813
  filter?: InputMaybe<IosAppCredentialsFilter>;
813
814
  };
814
815
  /** Represents an Exponent App (or Experience in legacy terms) */
816
+ export declare type AppLatestAppVersionByPlatformAndApplicationIdentifierArgs = {
817
+ applicationIdentifier: Scalars['String'];
818
+ platform: AppPlatform;
819
+ };
820
+ /** Represents an Exponent App (or Experience in legacy terms) */
815
821
  export declare type AppLatestReleaseForReleaseChannelArgs = {
816
822
  platform: AppPlatform;
817
823
  releaseChannel: Scalars['String'];
@@ -1004,6 +1010,47 @@ export declare enum AppStoreConnectUserRole {
1004
1010
  Technical = "TECHNICAL",
1005
1011
  Unknown = "UNKNOWN"
1006
1012
  }
1013
+ /** Represents Play Store/App Store version of an application */
1014
+ export declare type AppVersion = {
1015
+ __typename?: 'AppVersion';
1016
+ /**
1017
+ * Store identifier for an application
1018
+ * - Android - applicationId
1019
+ * - iOS - bundle identifier
1020
+ */
1021
+ applicationIdentifier: Scalars['String'];
1022
+ /**
1023
+ * Value that identifies build in a store (it's visible to developers, but not to end users)
1024
+ * - Android - versionCode in build.gradle ("android.versionCode" field in app.json)
1025
+ * - iOS - CFBundleVersion in Info.plist ("ios.buildNumber" field in app.json)
1026
+ */
1027
+ buildVersion: Scalars['String'];
1028
+ id: Scalars['ID'];
1029
+ platform: AppPlatform;
1030
+ runtimeVersion?: Maybe<Scalars['String']>;
1031
+ /**
1032
+ * User-facing version in a store
1033
+ * - Android - versionName in build.gradle ("version" field in app.json)
1034
+ * - iOS - CFBundleShortVersionString in Info.plist ("version" field in app.json)
1035
+ */
1036
+ storeVersion: Scalars['String'];
1037
+ };
1038
+ export declare type AppVersionInput = {
1039
+ appId: Scalars['ID'];
1040
+ applicationIdentifier: Scalars['String'];
1041
+ buildVersion: Scalars['String'];
1042
+ platform: AppPlatform;
1043
+ runtimeVersion?: InputMaybe<Scalars['String']>;
1044
+ storeVersion: Scalars['String'];
1045
+ };
1046
+ export declare type AppVersionMutation = {
1047
+ __typename?: 'AppVersionMutation';
1048
+ /** Create an app version */
1049
+ createAppVersion: AppVersion;
1050
+ };
1051
+ export declare type AppVersionMutationCreateAppVersionArgs = {
1052
+ appVersionInput: AppVersionInput;
1053
+ };
1007
1054
  export declare type AppleAppIdentifier = {
1008
1055
  __typename?: 'AppleAppIdentifier';
1009
1056
  account: Account;
@@ -1181,7 +1228,7 @@ export declare type ApplePushKey = {
1181
1228
  updatedAt: Scalars['DateTime'];
1182
1229
  };
1183
1230
  export declare type ApplePushKeyInput = {
1184
- appleTeamId?: InputMaybe<Scalars['ID']>;
1231
+ appleTeamId: Scalars['ID'];
1185
1232
  keyIdentifier: Scalars['String'];
1186
1233
  keyP8: Scalars['String'];
1187
1234
  };
@@ -1321,6 +1368,7 @@ export declare type Build = ActivityTimelineProjectActivity & BuildOrBuildJob &
1321
1368
  iosEnterpriseProvisioning?: Maybe<BuildIosEnterpriseProvisioning>;
1322
1369
  isGitWorkingTreeDirty?: Maybe<Scalars['Boolean']>;
1323
1370
  logFiles: Array<Scalars['String']>;
1371
+ maxBuildTimeSeconds: Scalars['Int'];
1324
1372
  metrics?: Maybe<BuildMetrics>;
1325
1373
  parentBuild?: Maybe<Build>;
1326
1374
  platform: AppPlatform;
@@ -1521,7 +1569,8 @@ export declare type BuildParamsInput = {
1521
1569
  };
1522
1570
  export declare enum BuildPriority {
1523
1571
  High = "HIGH",
1524
- Normal = "NORMAL"
1572
+ Normal = "NORMAL",
1573
+ NormalPlus = "NORMAL_PLUS"
1525
1574
  }
1526
1575
  /** Publicly visible data for a Build. */
1527
1576
  export declare type BuildPublicData = {
@@ -2420,6 +2469,8 @@ export declare type RootMutation = {
2420
2469
  app?: Maybe<AppMutation>;
2421
2470
  /** Mutations that modify an App Store Connect Api Key */
2422
2471
  appStoreConnectApiKey: AppStoreConnectApiKeyMutation;
2472
+ /** Mutations that modify an AppVersion */
2473
+ appVersion: AppVersionMutation;
2423
2474
  /** Mutations that modify an Identifier for an iOS App */
2424
2475
  appleAppIdentifier: AppleAppIdentifierMutation;
2425
2476
  /** Mutations that modify an Apple Device */
@@ -5759,6 +5810,19 @@ export declare type CreateAppMutation = {
5759
5810
  };
5760
5811
  } | null;
5761
5812
  };
5813
+ export declare type CreateAppVersionMutationVariables = Exact<{
5814
+ appVersionInput: AppVersionInput;
5815
+ }>;
5816
+ export declare type CreateAppVersionMutation = {
5817
+ __typename?: 'RootMutation';
5818
+ appVersion: {
5819
+ __typename?: 'AppVersionMutation';
5820
+ createAppVersion: {
5821
+ __typename?: 'AppVersion';
5822
+ id: string;
5823
+ };
5824
+ };
5825
+ };
5762
5826
  export declare type CreateAndroidBuildMutationVariables = Exact<{
5763
5827
  appId: Scalars['ID'];
5764
5828
  job: AndroidJobInput;
@@ -6181,6 +6245,27 @@ export declare type DeleteWebhookMutation = {
6181
6245
  };
6182
6246
  };
6183
6247
  };
6248
+ export declare type LatestAppVersionQueryVariables = Exact<{
6249
+ appId: Scalars['String'];
6250
+ platform: AppPlatform;
6251
+ applicationIdentifier: Scalars['String'];
6252
+ }>;
6253
+ export declare type LatestAppVersionQuery = {
6254
+ __typename?: 'RootQuery';
6255
+ app: {
6256
+ __typename?: 'AppQuery';
6257
+ byId: {
6258
+ __typename?: 'App';
6259
+ id: string;
6260
+ latestAppVersionByPlatformAndApplicationIdentifier?: {
6261
+ __typename?: 'AppVersion';
6262
+ id: string;
6263
+ storeVersion: string;
6264
+ buildVersion: string;
6265
+ } | null;
6266
+ };
6267
+ };
6268
+ };
6184
6269
  export declare type ViewBranchQueryVariables = Exact<{
6185
6270
  appId: Scalars['String'];
6186
6271
  name: Scalars['String'];