eas-cli 0.40.0 → 0.41.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.
@@ -2,126 +2,33 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleDeprecatedEasJsonAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const eas_build_job_1 = require("@expo/eas-build-job");
6
5
  const eas_json_1 = require("@expo/eas-json");
7
6
  const command_1 = require("@oclif/command");
8
7
  const errors_1 = require("@oclif/errors");
9
8
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
10
9
  const figures_1 = (0, tslib_1.__importDefault)(require("figures"));
11
10
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
12
- const nullthrows_1 = (0, tslib_1.__importDefault)(require("nullthrows"));
13
- const build_1 = require("../../build/android/build");
14
- const build_2 = require("../../build/build");
15
- const configure_1 = require("../../build/configure");
16
- const createContext_1 = require("../../build/createContext");
17
- const build_3 = require("../../build/ios/build");
18
- const devClient_1 = require("../../build/utils/devClient");
19
- const printBuildInfo_1 = require("../../build/utils/printBuildInfo");
11
+ const runBuildAndSubmit_1 = require("../../build/runBuildAndSubmit");
20
12
  const repository_1 = require("../../build/utils/repository");
21
13
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
22
- const generated_1 = require("../../graphql/generated");
23
- const AppPlatform_1 = require("../../graphql/types/AppPlatform");
24
14
  const log_1 = (0, tslib_1.__importStar)(require("../../log"));
25
15
  const platform_1 = require("../../platform");
26
- const metroConfig_1 = require("../../project/metroConfig");
27
16
  const projectUtils_1 = require("../../project/projectUtils");
28
17
  const prompts_1 = require("../../prompts");
29
- const context_1 = require("../../submit/context");
30
- const submit_1 = require("../../submit/submit");
31
- const urls_1 = require("../../submit/utils/urls");
32
18
  const easCli_1 = require("../../utils/easCli");
33
19
  const json_1 = require("../../utils/json");
34
- const profiles_1 = require("../../utils/profiles");
35
20
  const vcs_1 = require("../../vcs");
36
21
  const git_1 = (0, tslib_1.__importDefault)(require("../../vcs/clients/git"));
37
22
  class Build extends EasCommand_1.default {
38
- constructor() {
39
- super(...arguments);
40
- this.metroConfigValidated = false;
41
- }
42
23
  async runAsync() {
43
- var _a;
44
24
  const { flags: rawFlags } = this.parse(Build);
45
25
  if (rawFlags.json) {
46
26
  (0, json_1.enableJsonOutput)();
47
27
  }
48
28
  const flags = await this.sanitizeFlagsAsync(rawFlags);
49
- const { requestedPlatform } = flags;
50
29
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
51
30
  await handleDeprecatedEasJsonAsync(projectDir, flags.nonInteractive);
52
- await (0, vcs_1.getVcsClient)().ensureRepoExistsAsync();
53
- await (0, repository_1.ensureRepoIsCleanAsync)(flags.nonInteractive);
54
- await (0, configure_1.ensureProjectConfiguredAsync)(projectDir, requestedPlatform);
55
- const platforms = (0, platform_1.toPlatforms)(requestedPlatform);
56
- const buildProfiles = await (0, profiles_1.getProfilesAsync)({
57
- type: 'build',
58
- projectDir,
59
- platforms,
60
- profileName: (_a = flags.profile) !== null && _a !== void 0 ? _a : undefined,
61
- });
62
- await (0, devClient_1.ensureExpoDevClientInstalledForDevClientBuildsAsync)({
63
- projectDir,
64
- nonInteractive: flags.nonInteractive,
65
- buildProfiles,
66
- });
67
- const startedBuilds = [];
68
- const buildCtxByPlatform = {};
69
- for (const buildProfile of buildProfiles) {
70
- const { build: maybeBuild, buildCtx } = await this.prepareAndStartBuildAsync({
71
- projectDir,
72
- flags,
73
- moreBuilds: platforms.length > 1,
74
- buildProfile,
75
- });
76
- if (maybeBuild) {
77
- startedBuilds.push({ build: maybeBuild, buildProfile });
78
- }
79
- buildCtxByPlatform[(0, AppPlatform_1.toAppPlatform)(buildProfile.platform)] = buildCtx;
80
- }
81
- if (flags.local) {
82
- return;
83
- }
84
- log_1.default.newLine();
85
- (0, printBuildInfo_1.printLogsUrls)(startedBuilds.map(startedBuild => startedBuild.build));
86
- log_1.default.newLine();
87
- const submissions = [];
88
- if (flags.autoSubmit) {
89
- const submitProfiles = await (0, profiles_1.getProfilesAsync)({
90
- projectDir,
91
- platforms,
92
- profileName: flags.submitProfile,
93
- type: 'submit',
94
- });
95
- for (const startedBuild of startedBuilds) {
96
- const submitProfile = (0, nullthrows_1.default)(submitProfiles.find(({ platform }) => (0, AppPlatform_1.toAppPlatform)(platform) === startedBuild.build.platform)).profile;
97
- const submission = await this.prepareAndStartSubmissionAsync({
98
- build: startedBuild.build,
99
- buildCtx: (0, nullthrows_1.default)(buildCtxByPlatform[startedBuild.build.platform]),
100
- moreBuilds: startedBuilds.length > 1,
101
- projectDir,
102
- buildProfile: startedBuild.buildProfile.profile,
103
- submitProfile,
104
- nonInteractive: flags.nonInteractive,
105
- });
106
- submissions.push(submission);
107
- }
108
- log_1.default.newLine();
109
- (0, urls_1.printSubmissionDetailsUrls)(submissions);
110
- log_1.default.newLine();
111
- }
112
- if (!flags.wait) {
113
- return;
114
- }
115
- const builds = await (0, build_2.waitForBuildEndAsync)(startedBuilds.map(({ build }) => build.id));
116
- (0, printBuildInfo_1.printBuildResults)(builds, flags.json);
117
- const haveAllBuildsFailedOrCanceled = builds.every(build => (build === null || build === void 0 ? void 0 : build.status) && [generated_1.BuildStatus.Errored, generated_1.BuildStatus.Canceled].includes(build === null || build === void 0 ? void 0 : build.status));
118
- if (haveAllBuildsFailedOrCanceled || !flags.autoSubmit) {
119
- this.exitWithNonZeroCodeIfSomeBuildsFailed(builds);
120
- }
121
- else {
122
- // the following function also exits with non zero code if any of the submissions failed
123
- await (0, submit_1.waitToCompleteAsync)(submissions);
124
- }
31
+ await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(projectDir, flags);
125
32
  }
126
33
  async sanitizeFlagsAsync(flags) {
127
34
  var _a;
@@ -155,7 +62,11 @@ class Build extends EasCommand_1.default {
155
62
  skipProjectConfiguration: flags['skip-project-configuration'],
156
63
  profile,
157
64
  nonInteractive,
158
- local: flags['local'],
65
+ localBuildOptions: flags['local']
66
+ ? { enable: true, verbose: true }
67
+ : {
68
+ enable: false,
69
+ },
159
70
  wait: flags['wait'],
160
71
  clearCache: flags['clear-cache'],
161
72
  json: flags['json'],
@@ -163,68 +74,6 @@ class Build extends EasCommand_1.default {
163
74
  submitProfile: (_a = flags['auto-submit-with-profile']) !== null && _a !== void 0 ? _a : profile,
164
75
  };
165
76
  }
166
- async prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildProfile, }) {
167
- const buildCtx = await (0, createContext_1.createBuildContextAsync)({
168
- buildProfileName: buildProfile.profileName,
169
- clearCache: flags.clearCache,
170
- buildProfile: buildProfile.profile,
171
- local: flags.local,
172
- nonInteractive: flags.nonInteractive,
173
- platform: buildProfile.platform,
174
- projectDir,
175
- skipProjectConfiguration: flags.skipProjectConfiguration,
176
- });
177
- if (moreBuilds) {
178
- log_1.default.newLine();
179
- const appPlatform = (0, AppPlatform_1.toAppPlatform)(buildProfile.platform);
180
- log_1.default.log(`${platform_1.appPlatformEmojis[appPlatform]} ${chalk_1.default.bold(`${platform_1.appPlatformDisplayNames[appPlatform]} build`)}`);
181
- }
182
- if (buildCtx.workflow === eas_build_job_1.Workflow.MANAGED && !this.metroConfigValidated) {
183
- await (0, metroConfig_1.validateMetroConfigForManagedWorkflowAsync)(buildCtx);
184
- this.metroConfigValidated = true;
185
- }
186
- const build = await this.startBuildAsync(buildCtx);
187
- return {
188
- build,
189
- buildCtx,
190
- };
191
- }
192
- async startBuildAsync(ctx) {
193
- let sendBuildRequestAsync;
194
- if (ctx.platform === eas_build_job_1.Platform.ANDROID) {
195
- sendBuildRequestAsync = await (0, build_1.prepareAndroidBuildAsync)(ctx);
196
- }
197
- else {
198
- sendBuildRequestAsync = await (0, build_3.prepareIosBuildAsync)(ctx);
199
- }
200
- return await sendBuildRequestAsync();
201
- }
202
- async prepareAndStartSubmissionAsync({ build, buildCtx, moreBuilds, projectDir, buildProfile, submitProfile, nonInteractive, }) {
203
- var _a, _b, _c;
204
- const platform = (0, AppPlatform_1.toPlatform)(build.platform);
205
- const submissionCtx = await (0, context_1.createSubmissionContextAsync)({
206
- platform,
207
- projectDir,
208
- projectId: build.project.id,
209
- profile: submitProfile,
210
- archiveFlags: { id: build.id },
211
- nonInteractive,
212
- env: buildProfile.env,
213
- credentialsCtx: buildCtx.credentialsCtx,
214
- applicationIdentifier: (_b = (_a = buildCtx.android) === null || _a === void 0 ? void 0 : _a.applicationId) !== null && _b !== void 0 ? _b : (_c = buildCtx.ios) === null || _c === void 0 ? void 0 : _c.bundleIdentifier,
215
- });
216
- if (moreBuilds) {
217
- log_1.default.newLine();
218
- log_1.default.log(`${platform_1.appPlatformEmojis[build.platform]} ${chalk_1.default.bold(`${platform_1.appPlatformDisplayNames[build.platform]} submission`)}`);
219
- }
220
- return await (0, submit_1.submitAsync)(submissionCtx);
221
- }
222
- exitWithNonZeroCodeIfSomeBuildsFailed(maybeBuilds) {
223
- const failedBuilds = maybeBuilds.filter(i => i).filter(i => i.status === generated_1.BuildStatus.Errored);
224
- if (failedBuilds.length > 0) {
225
- process.exit(1);
226
- }
227
- }
228
77
  }
229
78
  exports.default = Build;
230
79
  Build.description = 'Start a build';
@@ -0,0 +1,22 @@
1
+ import { flags } from '@oclif/command';
2
+ import EasCommand from '../../commandUtils/EasCommand';
3
+ import { RequestedPlatform } from '../../platform';
4
+ declare enum InspectStage {
5
+ ARCHIVE = "archive",
6
+ PRE_BUILD = "pre-build",
7
+ POST_BUILD = "post-build"
8
+ }
9
+ export default class BuildInspect extends EasCommand {
10
+ static description: string;
11
+ static flags: {
12
+ platform: flags.IOptionFlag<RequestedPlatform>;
13
+ profile: flags.IOptionFlag<string | undefined>;
14
+ stage: flags.IOptionFlag<InspectStage>;
15
+ output: flags.IOptionFlag<string>;
16
+ force: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
17
+ verbose: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
18
+ };
19
+ runAsync(): Promise<void>;
20
+ private prepareOutputDirAsync;
21
+ }
22
+ export {};
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const command_1 = require("@oclif/command");
5
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
+ const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
7
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
8
+ const uuid_1 = require("uuid");
9
+ const runBuildAndSubmit_1 = require("../../build/runBuildAndSubmit");
10
+ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
11
+ const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
12
+ const ora_1 = require("../../ora");
13
+ const platform_1 = require("../../platform");
14
+ const projectUtils_1 = require("../../project/projectUtils");
15
+ const paths_1 = require("../../utils/paths");
16
+ const vcs_1 = require("../../vcs");
17
+ var InspectStage;
18
+ (function (InspectStage) {
19
+ InspectStage["ARCHIVE"] = "archive";
20
+ InspectStage["PRE_BUILD"] = "pre-build";
21
+ InspectStage["POST_BUILD"] = "post-build";
22
+ })(InspectStage || (InspectStage = {}));
23
+ const STAGE_DESCRIPTION = `Stage of the build you want to inspect.
24
+ archive - builds the project archive that would be uploaded to EAS when building
25
+ pre-build - prepares the project to be built with Gradle/Xcode. Does not run the native build.
26
+ post-build - builds the native project and leaves the output directory for inspection`;
27
+ class BuildInspect extends EasCommand_1.default {
28
+ async runAsync() {
29
+ const { flags } = this.parse(BuildInspect);
30
+ const outputDirectory = path_1.default.resolve(process.cwd(), flags.output);
31
+ await this.prepareOutputDirAsync(outputDirectory, flags.force);
32
+ if (flags.stage === InspectStage.ARCHIVE) {
33
+ const vcs = (0, vcs_1.getVcsClient)();
34
+ await vcs.ensureRepoExistsAsync();
35
+ await vcs.makeShallowCopyAsync(outputDirectory);
36
+ log_1.default.withTick(`Project saved to ${outputDirectory}`);
37
+ }
38
+ else {
39
+ const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
40
+ const tmpWorkingdir = path_1.default.join((0, paths_1.getTmpDirectory)(), (0, uuid_1.v4)());
41
+ try {
42
+ await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(projectDir, {
43
+ skipProjectConfiguration: false,
44
+ nonInteractive: false,
45
+ wait: true,
46
+ clearCache: false,
47
+ json: false,
48
+ autoSubmit: false,
49
+ requestedPlatform: flags.platform,
50
+ profile: flags.profile,
51
+ localBuildOptions: {
52
+ enable: true,
53
+ ...(flags.stage === InspectStage.PRE_BUILD ? { skipNativeBuild: true } : {}),
54
+ ...(flags.stage === InspectStage.POST_BUILD ? { skipCleanup: true } : {}),
55
+ verbose: flags.verbose,
56
+ workingdir: tmpWorkingdir,
57
+ artifactsDir: path_1.default.join(tmpWorkingdir, 'artifacts'),
58
+ },
59
+ });
60
+ if (!flags.verbose) {
61
+ log_1.default.log(chalk_1.default.green('Build successful'));
62
+ }
63
+ }
64
+ catch (err) {
65
+ if (!flags.verbose) {
66
+ log_1.default.error('Build failed');
67
+ log_1.default.error(`Re-run this command with ${chalk_1.default.bold('--verbose')} flag to see the logs`);
68
+ }
69
+ }
70
+ finally {
71
+ const spinner = (0, ora_1.ora)().start(`Copying project build directory to ${outputDirectory}`);
72
+ try {
73
+ const tmpBuildDirectory = path_1.default.join(tmpWorkingdir, 'build');
74
+ if (await fs_extra_1.default.pathExists(tmpBuildDirectory)) {
75
+ await fs_extra_1.default.copy(tmpBuildDirectory, outputDirectory);
76
+ }
77
+ await fs_extra_1.default.remove(tmpWorkingdir);
78
+ spinner.succeed(`Project build directory saved to ${outputDirectory}`);
79
+ }
80
+ catch (err) {
81
+ spinner.fail();
82
+ throw err;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ async prepareOutputDirAsync(outputDir, force) {
88
+ if (await fs_extra_1.default.pathExists(outputDir)) {
89
+ if (force) {
90
+ await fs_extra_1.default.remove(outputDir);
91
+ }
92
+ else {
93
+ throw new Error(`Directory ${outputDir} already exists`);
94
+ }
95
+ }
96
+ await fs_extra_1.default.mkdirp(outputDir);
97
+ }
98
+ }
99
+ exports.default = BuildInspect;
100
+ BuildInspect.description = 'Inspect the state of the project at specific build stages. Useful for troubleshooting.';
101
+ BuildInspect.flags = {
102
+ platform: command_1.flags.enum({
103
+ char: 'p',
104
+ options: [platform_1.RequestedPlatform.Android, platform_1.RequestedPlatform.Ios],
105
+ required: true,
106
+ }),
107
+ profile: command_1.flags.string({
108
+ description: 'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
109
+ helpValue: 'PROFILE_NAME',
110
+ }),
111
+ stage: command_1.flags.enum({
112
+ char: 's',
113
+ description: STAGE_DESCRIPTION,
114
+ options: [InspectStage.ARCHIVE, InspectStage.PRE_BUILD, InspectStage.POST_BUILD],
115
+ required: true,
116
+ }),
117
+ output: command_1.flags.string({
118
+ description: 'Output directory.',
119
+ required: true,
120
+ helpValue: 'OUTPUT_DIRECTORY',
121
+ }),
122
+ force: command_1.flags.boolean({
123
+ description: 'Delete OUTPUT_DIRECTORY if it already exists.',
124
+ default: false,
125
+ }),
126
+ verbose: command_1.flags.boolean({
127
+ default: false,
128
+ }),
129
+ };
@@ -10,18 +10,22 @@ const log_1 = (0, tslib_1.__importStar)(require("../../log"));
10
10
  const projectUtils_1 = require("../../project/projectUtils");
11
11
  const workflow_1 = require("../../project/workflow");
12
12
  const EAS_UPDATE_URL = 'https://u.expo.dev';
13
- const DEFAULT_RUNTIME_VERSION = { policy: 'sdkVersion' };
13
+ const DEFAULT_MANAGED_RUNTIME_VERSION = { policy: 'sdkVersion' };
14
+ const DEFAULT_BARE_RUNTIME_VERSION = '1.0.0';
14
15
  async function getEASUpdateURLAsync(exp) {
15
16
  const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
16
17
  return new URL(projectId, EAS_UPDATE_URL).href;
17
18
  }
18
19
  exports.getEASUpdateURLAsync = getEASUpdateURLAsync;
19
- async function configureProjectForEASUpdateAsync(projectDir, exp) {
20
+ async function configureProjectForEASUpdateAsync(projectDir, exp, isBare) {
20
21
  var _a, _b;
21
22
  const easUpdateURL = await getEASUpdateURLAsync(exp);
22
23
  const preexistingRuntimeVersion = exp.runtimeVersion;
24
+ const defaultRuntimeVersion = isBare
25
+ ? DEFAULT_BARE_RUNTIME_VERSION
26
+ : DEFAULT_MANAGED_RUNTIME_VERSION;
23
27
  const result = await (0, config_1.modifyConfigAsync)(projectDir, {
24
- runtimeVersion: preexistingRuntimeVersion !== null && preexistingRuntimeVersion !== void 0 ? preexistingRuntimeVersion : DEFAULT_RUNTIME_VERSION,
28
+ runtimeVersion: preexistingRuntimeVersion !== null && preexistingRuntimeVersion !== void 0 ? preexistingRuntimeVersion : defaultRuntimeVersion,
25
29
  updates: { ...exp.updates, url: easUpdateURL },
26
30
  });
27
31
  switch (result.type) {
@@ -35,7 +39,7 @@ async function configureProjectForEASUpdateAsync(projectDir, exp) {
35
39
  log_1.default.withTick(`Set updates.url value, to "${easUpdateURL}" in app.json`);
36
40
  }
37
41
  if (!preexistingRuntimeVersion) {
38
- log_1.default.withTick(`Set runtimeVersion to "${JSON.stringify(DEFAULT_RUNTIME_VERSION)}" in app.json`);
42
+ log_1.default.withTick(`Set runtimeVersion to "${JSON.stringify(defaultRuntimeVersion)}" in app.json`);
39
43
  }
40
44
  break;
41
45
  case 'warn': {
@@ -59,11 +63,12 @@ class UpdateConfigure extends EasCommand_1.default {
59
63
  const { exp } = (0, config_1.getConfig)(projectDir, {
60
64
  skipSDKVersionRequirement: true,
61
65
  });
62
- await configureProjectForEASUpdateAsync(projectDir, exp);
63
66
  const hasAndroidNativeProject = (await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.ANDROID)) === eas_build_job_1.Workflow.GENERIC;
64
67
  const hasIosNativeProject = (await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.IOS)) === eas_build_job_1.Workflow.GENERIC;
68
+ const isBare = hasAndroidNativeProject || hasIosNativeProject;
69
+ await configureProjectForEASUpdateAsync(projectDir, exp, isBare);
65
70
  log_1.default.addNewLineIfNone();
66
- if (hasAndroidNativeProject || hasIosNativeProject) {
71
+ if (isBare) {
67
72
  log_1.default.log(`🧐 It seems you are on the bare workflow! Please also update your native files. You can do this by either running ${chalk_1.default.bold('eas build:configure')} or manually editing Expo.plist/AndroidManifest.xml. ${(0, log_1.learnMore)('https://expo.fyi/eas-update-config.md#native-configuration')}`);
68
73
  }
69
74
  else {
@@ -103,18 +103,30 @@ class UpdatePublish extends EasCommand_1.default {
103
103
  `branch-${Math.random().toString(36).substr(2, 4)}`;
104
104
  }
105
105
  if (!branchName) {
106
- const validationMessage = 'branch name may not be empty.';
106
+ const validationMessage = 'Branch name may not be empty.';
107
107
  if (jsonFlag) {
108
108
  throw new Error(validationMessage);
109
109
  }
110
110
  const branches = await (0, list_1.listBranchesAsync)({ projectId });
111
- branchName = await (0, prompts_1.selectAsync)('which branch would you like to publish on?', branches.map(branch => {
112
- return {
113
- title: `${branch.name} ${chalk_1.default.grey(`- current update: ${(0, utils_1.formatUpdate)(branch.updates[0])}`)}`,
114
- value: branch.name,
115
- };
116
- }));
117
- (0, assert_1.default)(branchName, 'branch name must be specified.');
111
+ if (branches.length === 0) {
112
+ ({ name: branchName } = await (0, prompts_1.promptAsync)({
113
+ type: 'text',
114
+ name: 'name',
115
+ message: 'No branches found. Creating a new one. Please name the new branch:',
116
+ initial: (await (0, vcs_1.getVcsClient)().getBranchNameAsync()) ||
117
+ `branch-${Math.random().toString(36).substr(2, 4)}`,
118
+ validate: value => (value ? true : validationMessage),
119
+ }));
120
+ }
121
+ else {
122
+ branchName = await (0, prompts_1.selectAsync)('Which branch would you like to publish on?', branches.map(branch => {
123
+ return {
124
+ title: `${branch.name} ${chalk_1.default.grey(`- current update: ${(0, utils_1.formatUpdate)(branch.updates[0])}`)}`,
125
+ value: branch.name,
126
+ };
127
+ }));
128
+ }
129
+ (0, assert_1.default)(branchName, 'Branch name must be specified.');
118
130
  }
119
131
  const { id: branchId, updates } = await ensureBranchExistsAsync({
120
132
  appId: projectId,
@@ -162,7 +174,7 @@ class UpdatePublish extends EasCommand_1.default {
162
174
  }
163
175
  publicationPlatformMessage = `The republished update will appear on the same plaforms it was originally published on: ${updatesToRepublishFilteredByPlatform
164
176
  .map(update => update.platform)
165
- .join(',')}`;
177
+ .join(', ')}`;
166
178
  }
167
179
  else {
168
180
  publicationPlatformMessage = `The republished update will appear only on: ${platformFlag}`;
@@ -177,6 +189,19 @@ class UpdatePublish extends EasCommand_1.default {
177
189
  group = updatesToRepublishFilteredByPlatform[0].group;
178
190
  oldMessage = (_a = updatesToRepublishFilteredByPlatform[0].message) !== null && _a !== void 0 ? _a : '';
179
191
  oldRuntimeVersion = updatesToRepublishFilteredByPlatform[0].runtimeVersion;
192
+ if (!message) {
193
+ const validationMessage = 'publish message may not be empty.';
194
+ if (jsonFlag) {
195
+ throw new Error(validationMessage);
196
+ }
197
+ ({ publishMessage: message } = await (0, prompts_1.promptAsync)({
198
+ type: 'text',
199
+ name: 'publishMessage',
200
+ message: `Please enter an update message.`,
201
+ initial: `Republish "${oldMessage}" - group: ${group}`,
202
+ validate: (value) => (value ? true : validationMessage),
203
+ }));
204
+ }
180
205
  }
181
206
  else {
182
207
  if (!message && autoFlag) {
@@ -191,9 +216,7 @@ class UpdatePublish extends EasCommand_1.default {
191
216
  type: 'text',
192
217
  name: 'publishMessage',
193
218
  message: `Please enter an update message.`,
194
- initial: republish
195
- ? `Republish "${oldMessage}" - group: ${group}`
196
- : (_c = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _c === void 0 ? void 0 : _c.trim(),
219
+ initial: (_c = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _c === void 0 ? void 0 : _c.trim(),
197
220
  validate: (value) => (value ? true : validationMessage),
198
221
  }));
199
222
  }
@@ -632,6 +632,7 @@ export declare type Build = ActivityTimelineProjectActivity & BuildOrBuildJob &
632
632
  appBuildVersion?: Maybe<Scalars['String']>;
633
633
  sdkVersion?: Maybe<Scalars['String']>;
634
634
  runtimeVersion?: Maybe<Scalars['String']>;
635
+ reactNativeVersion?: Maybe<Scalars['String']>;
635
636
  releaseChannel?: Maybe<Scalars['String']>;
636
637
  channel?: Maybe<Scalars['String']>;
637
638
  metrics?: Maybe<BuildMetrics>;
@@ -1535,6 +1536,7 @@ export declare type InvoiceQuery = {
1535
1536
  export declare type InvoiceQueryPreviewInvoiceForSubscriptionUpdateArgs = {
1536
1537
  accountId: Scalars['String'];
1537
1538
  newPlanIdentifier: Scalars['String'];
1539
+ couponCode?: Maybe<Scalars['String']>;
1538
1540
  };
1539
1541
  export declare type Invoice = {
1540
1542
  __typename?: 'Invoice';
@@ -1545,12 +1547,28 @@ export declare type Invoice = {
1545
1547
  amountPaid: Scalars['Int'];
1546
1548
  /** The total amount that needs to be paid, considering any discounts or account credit. Value is in cents. */
1547
1549
  amountRemaining: Scalars['Int'];
1550
+ discount?: Maybe<InvoiceDiscount>;
1551
+ totalDiscountedAmount: Scalars['Int'];
1548
1552
  lineItems: Array<InvoiceLineItem>;
1549
1553
  period: InvoicePeriod;
1550
1554
  startingBalance: Scalars['Int'];
1551
1555
  subtotal: Scalars['Int'];
1552
1556
  total: Scalars['Int'];
1553
1557
  };
1558
+ export declare type InvoiceDiscount = {
1559
+ __typename?: 'InvoiceDiscount';
1560
+ id: Scalars['ID'];
1561
+ name: Scalars['String'];
1562
+ type: InvoiceDiscountType;
1563
+ duration: Scalars['String'];
1564
+ durationInMonths?: Maybe<Scalars['Int']>;
1565
+ /** The coupon's discount value, in percentage or in dollar amount */
1566
+ amount: Scalars['Int'];
1567
+ };
1568
+ export declare enum InvoiceDiscountType {
1569
+ Percentage = "PERCENTAGE",
1570
+ Amount = "AMOUNT"
1571
+ }
1554
1572
  export declare type InvoiceLineItem = {
1555
1573
  __typename?: 'InvoiceLineItem';
1556
1574
  id: Scalars['ID'];
@@ -1818,6 +1836,7 @@ export declare type AccountMutationCancelSubscriptionArgs = {
1818
1836
  export declare type AccountMutationChangePlanArgs = {
1819
1837
  accountID: Scalars['ID'];
1820
1838
  newPlanIdentifier: Scalars['String'];
1839
+ couponCode?: Maybe<Scalars['String']>;
1821
1840
  };
1822
1841
  export declare type AccountMutationCancelScheduledSubscriptionChangeArgs = {
1823
1842
  accountID: Scalars['ID'];
@@ -2307,6 +2326,7 @@ export declare type BuildMetadataInput = {
2307
2326
  credentialsSource?: Maybe<BuildCredentialsSource>;
2308
2327
  sdkVersion?: Maybe<Scalars['String']>;
2309
2328
  runtimeVersion?: Maybe<Scalars['String']>;
2329
+ reactNativeVersion?: Maybe<Scalars['String']>;
2310
2330
  releaseChannel?: Maybe<Scalars['String']>;
2311
2331
  channel?: Maybe<Scalars['String']>;
2312
2332
  distribution?: Maybe<DistributionType>;
@@ -3060,16 +3080,6 @@ export declare type BranchesByAppQuery = ({
3060
3080
  });
3061
3081
  });
3062
3082
  });
3063
- export declare type GetUpdateGroupAsyncQueryVariables = Exact<{
3064
- group: Scalars['ID'];
3065
- }>;
3066
- export declare type GetUpdateGroupAsyncQuery = ({
3067
- __typename?: 'RootQuery';
3068
- } & {
3069
- updatesByGroup: Array<({
3070
- __typename?: 'Update';
3071
- } & Pick<Update, 'id' | 'group' | 'runtimeVersion' | 'manifestFragment' | 'platform' | 'message'>)>;
3072
- });
3073
3083
  export declare type EditUpdateBranchMutationVariables = Exact<{
3074
3084
  input: EditUpdateBranchInput;
3075
3085
  }>;
@@ -3277,6 +3287,16 @@ export declare type DeleteUpdateGroupMutation = ({
3277
3287
  } & Pick<DeleteUpdateGroupResult, 'group'>);
3278
3288
  });
3279
3289
  });
3290
+ export declare type GetUpdateGroupAsyncQueryVariables = Exact<{
3291
+ group: Scalars['ID'];
3292
+ }>;
3293
+ export declare type GetUpdateGroupAsyncQuery = ({
3294
+ __typename?: 'RootQuery';
3295
+ } & {
3296
+ updatesByGroup: Array<({
3297
+ __typename?: 'Update';
3298
+ } & Pick<Update, 'id' | 'group' | 'runtimeVersion' | 'manifestFragment' | 'platform' | 'message'>)>;
3299
+ });
3280
3300
  export declare type UpdatesByGroupQueryVariables = Exact<{
3281
3301
  groupId: Scalars['ID'];
3282
3302
  }>;
@@ -4585,7 +4605,7 @@ export declare type SubmissionFragment = ({
4585
4605
  } & Pick<Submission, 'id' | 'status' | 'platform' | 'logsUrl'> & {
4586
4606
  app: ({
4587
4607
  __typename?: 'App';
4588
- } & Pick<App, 'id' | 'name'> & {
4608
+ } & Pick<App, 'id' | 'name' | 'slug'> & {
4589
4609
  ownerAccount: ({
4590
4610
  __typename?: 'Account';
4591
4611
  } & Pick<Account, 'id' | 'name'>);
@@ -6,7 +6,7 @@
6
6
  * For more info and docs, visit https://graphql-code-generator.com/
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.CacheControlScope = exports.IosManagedBuildType = exports.IosSchemeBuildConfiguration = exports.StandardOffer = exports.MailchimpAudience = exports.MailchimpTag = exports.UploadSessionType = exports.IosBuildType = exports.EasBuildDeprecationInfoType = exports.BuildCredentialsSource = exports.AndroidBuildType = exports.ProjectArchiveSourceType = exports.BuildWorkflow = exports.Order = exports.AssetMetadataStatus = exports.AppSort = exports.AppsFilter = exports.WebhookType = exports.AndroidKeystoreType = exports.AndroidFcmVersion = exports.AppStoreConnectUserRole = exports.IosDistributionType = exports.AppleDeviceClass = exports.BuildJobStatus = exports.BuildJobLogsFormat = exports.SubmissionAndroidReleaseStatus = exports.SubmissionAndroidTrack = exports.SubmissionAndroidArchiveType = exports.SubmissionStatus = exports.BuildIosEnterpriseProvisioning = exports.ActivityTimelineProjectActivityType = exports.Role = exports.Permission = exports.SecondFactorMethod = exports.DistributionType = exports.BuildStatus = exports.AppPlatform = exports.AppPrivacy = exports.Feature = exports.OfferType = void 0;
9
+ exports.CacheControlScope = exports.IosManagedBuildType = exports.IosSchemeBuildConfiguration = exports.StandardOffer = exports.MailchimpAudience = exports.MailchimpTag = exports.UploadSessionType = exports.IosBuildType = exports.EasBuildDeprecationInfoType = exports.BuildCredentialsSource = exports.AndroidBuildType = exports.ProjectArchiveSourceType = exports.BuildWorkflow = exports.InvoiceDiscountType = exports.Order = exports.AssetMetadataStatus = exports.AppSort = exports.AppsFilter = exports.WebhookType = exports.AndroidKeystoreType = exports.AndroidFcmVersion = exports.AppStoreConnectUserRole = exports.IosDistributionType = exports.AppleDeviceClass = exports.BuildJobStatus = exports.BuildJobLogsFormat = exports.SubmissionAndroidReleaseStatus = exports.SubmissionAndroidTrack = exports.SubmissionAndroidArchiveType = exports.SubmissionStatus = exports.BuildIosEnterpriseProvisioning = exports.ActivityTimelineProjectActivityType = exports.Role = exports.Permission = exports.SecondFactorMethod = exports.DistributionType = exports.BuildStatus = exports.AppPlatform = exports.AppPrivacy = exports.Feature = exports.OfferType = void 0;
10
10
  var OfferType;
11
11
  (function (OfferType) {
12
12
  /** Term subscription */
@@ -202,6 +202,11 @@ var Order;
202
202
  Order["Desc"] = "DESC";
203
203
  Order["Asc"] = "ASC";
204
204
  })(Order = exports.Order || (exports.Order = {}));
205
+ var InvoiceDiscountType;
206
+ (function (InvoiceDiscountType) {
207
+ InvoiceDiscountType["Percentage"] = "PERCENTAGE";
208
+ InvoiceDiscountType["Amount"] = "AMOUNT";
209
+ })(InvoiceDiscountType = exports.InvoiceDiscountType || (exports.InvoiceDiscountType = {}));
205
210
  var BuildWorkflow;
206
211
  (function (BuildWorkflow) {
207
212
  BuildWorkflow["Generic"] = "GENERIC";
@@ -11,6 +11,7 @@ exports.SubmissionFragmentNode = (0, graphql_tag_1.default) `
11
11
  app {
12
12
  id
13
13
  name
14
+ slug
14
15
  ownerAccount {
15
16
  id
16
17
  name
@@ -0,0 +1,3 @@
1
+ import { Platform } from '@expo/eas-build-job';
2
+ import { BuildContext } from '../build/context';
3
+ export declare function checkExpoSdkIsSupportedAsync(ctx: BuildContext<Platform>): Promise<void>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkExpoSdkIsSupportedAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const eas_build_job_1 = require("@expo/eas-build-job");
6
+ const errors_1 = require("@oclif/errors");
7
+ const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
8
+ const semver_1 = (0, tslib_1.__importDefault)(require("semver"));
9
+ const log_1 = (0, tslib_1.__importDefault)(require("../log"));
10
+ const prompts_1 = require("../prompts");
11
+ const SUPPORTED_EXPO_SDK_VERSIONS = '>= 41.0.0';
12
+ (0, assert_1.default)(semver_1.default.validRange(SUPPORTED_EXPO_SDK_VERSIONS), 'Must be a valid version range');
13
+ async function checkExpoSdkIsSupportedAsync(ctx) {
14
+ (0, assert_1.default)(ctx.workflow === eas_build_job_1.Workflow.MANAGED, 'Must be a managed workflow project');
15
+ if (ctx.exp.sdkVersion && semver_1.default.satisfies(ctx.exp.sdkVersion, SUPPORTED_EXPO_SDK_VERSIONS)) {
16
+ return;
17
+ }
18
+ const unsupportedSdkMessage = 'EAS Build does not officially support building managed project with Expo SDK < 41.';
19
+ if (ctx.nonInteractive) {
20
+ log_1.default.warn(`${unsupportedSdkMessage} Proceeding because you are running in non-interactive mode.`);
21
+ return;
22
+ }
23
+ const proceed = await (0, prompts_1.confirmAsync)({
24
+ message: `${unsupportedSdkMessage} Do you want to proceed?`,
25
+ });
26
+ if (!proceed) {
27
+ (0, errors_1.exit)(1);
28
+ }
29
+ }
30
+ exports.checkExpoSdkIsSupportedAsync = checkExpoSdkIsSupportedAsync;