eas-cli 0.39.0 → 0.42.3

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 (117) hide show
  1. package/README.md +457 -104
  2. package/bin/run +3 -4
  3. package/build/api.d.ts +1 -0
  4. package/build/api.js +13 -1
  5. package/build/build/build.js +3 -3
  6. package/build/build/configure.js +3 -3
  7. package/build/build/context.d.ts +2 -1
  8. package/build/build/createContext.d.ts +3 -2
  9. package/build/build/createContext.js +3 -3
  10. package/build/build/local.d.ts +9 -1
  11. package/build/build/local.js +35 -5
  12. package/build/build/runBuildAndSubmit.d.ts +15 -0
  13. package/build/build/runBuildAndSubmit.js +173 -0
  14. package/build/build/utils/devClient.js +3 -3
  15. package/build/commandUtils/EasCommand.d.ts +2 -1
  16. package/build/commandUtils/EasCommand.js +7 -4
  17. package/build/commands/account/login.d.ts +1 -0
  18. package/build/commands/account/login.js +1 -0
  19. package/build/commands/account/logout.d.ts +1 -0
  20. package/build/commands/account/logout.js +1 -0
  21. package/build/commands/account/view.d.ts +1 -0
  22. package/build/commands/account/view.js +1 -0
  23. package/build/commands/analytics.js +1 -1
  24. package/build/commands/branch/create.d.ts +1 -2
  25. package/build/commands/branch/create.js +3 -4
  26. package/build/commands/branch/delete.d.ts +1 -2
  27. package/build/commands/branch/delete.js +4 -5
  28. package/build/commands/branch/list.d.ts +1 -2
  29. package/build/commands/branch/list.js +4 -5
  30. package/build/commands/branch/publish.d.ts +1 -18
  31. package/build/commands/branch/publish.js +2 -354
  32. package/build/commands/branch/rename.d.ts +3 -5
  33. package/build/commands/branch/rename.js +5 -6
  34. package/build/commands/branch/view.d.ts +1 -2
  35. package/build/commands/branch/view.js +3 -4
  36. package/build/commands/build/cancel.js +1 -1
  37. package/build/commands/build/configure.d.ts +1 -2
  38. package/build/commands/build/configure.js +3 -3
  39. package/build/commands/build/index.d.ts +11 -17
  40. package/build/commands/build/index.js +28 -178
  41. package/build/commands/build/inspect.d.ts +21 -0
  42. package/build/commands/build/inspect.js +129 -0
  43. package/build/commands/build/list.d.ts +13 -14
  44. package/build/commands/build/list.js +15 -15
  45. package/build/commands/build/view.d.ts +1 -1
  46. package/build/commands/build/view.js +3 -3
  47. package/build/commands/channel/create.d.ts +1 -2
  48. package/build/commands/channel/create.js +3 -4
  49. package/build/commands/channel/edit.d.ts +2 -4
  50. package/build/commands/channel/edit.js +4 -5
  51. package/build/commands/channel/list.d.ts +1 -2
  52. package/build/commands/channel/list.js +3 -4
  53. package/build/commands/channel/rollout.d.ts +4 -5
  54. package/build/commands/channel/rollout.js +6 -7
  55. package/build/commands/channel/view.d.ts +1 -2
  56. package/build/commands/channel/view.js +3 -4
  57. package/build/commands/config.d.ts +2 -3
  58. package/build/commands/config.js +4 -4
  59. package/build/commands/credentials.js +1 -7
  60. package/build/commands/device/list.d.ts +1 -2
  61. package/build/commands/device/list.js +3 -3
  62. package/build/commands/device/view.js +1 -1
  63. package/build/commands/diagnostics.js +1 -0
  64. package/build/commands/secret/create.d.ts +4 -5
  65. package/build/commands/secret/create.js +6 -6
  66. package/build/commands/secret/delete.d.ts +1 -2
  67. package/build/commands/secret/delete.js +3 -3
  68. package/build/commands/submit.d.ts +9 -10
  69. package/build/commands/submit.js +14 -15
  70. package/build/commands/update/configure.d.ts +0 -2
  71. package/build/commands/update/configure.js +14 -14
  72. package/build/commands/update/delete.d.ts +1 -2
  73. package/build/commands/update/delete.js +3 -4
  74. package/build/commands/update/index.d.ts +18 -0
  75. package/build/commands/update/index.js +392 -0
  76. package/build/commands/update/view.d.ts +1 -2
  77. package/build/commands/update/view.js +3 -4
  78. package/build/commands/webhook/create.d.ts +3 -4
  79. package/build/commands/webhook/create.js +5 -5
  80. package/build/commands/webhook/delete.js +1 -1
  81. package/build/commands/webhook/list.d.ts +1 -2
  82. package/build/commands/webhook/list.js +3 -3
  83. package/build/commands/webhook/update.d.ts +4 -5
  84. package/build/commands/webhook/update.js +6 -6
  85. package/build/commands/webhook/view.js +1 -1
  86. package/build/credentials/context.d.ts +5 -0
  87. package/build/credentials/context.js +12 -7
  88. package/build/credentials/manager/ManageAndroid.d.ts +3 -3
  89. package/build/credentials/manager/ManageAndroid.js +21 -13
  90. package/build/credentials/manager/ManageIos.d.ts +3 -3
  91. package/build/credentials/manager/ManageIos.js +23 -13
  92. package/build/credentials/manager/SelectBuildProfileFromEasJson.d.ts +2 -3
  93. package/build/credentials/manager/SelectBuildProfileFromEasJson.js +3 -6
  94. package/build/credentials/manager/SelectPlatform.d.ts +1 -2
  95. package/build/credentials/manager/SelectPlatform.js +3 -3
  96. package/build/graphql/generated.d.ts +31 -11
  97. package/build/graphql/generated.js +6 -1
  98. package/build/graphql/types/Submission.js +1 -0
  99. package/build/index.d.ts +1 -1
  100. package/build/index.js +2 -2
  101. package/build/project/expoSdk.d.ts +3 -0
  102. package/build/project/expoSdk.js +30 -0
  103. package/build/project/metroConfig.js +2 -2
  104. package/build/project/publish.js +1 -3
  105. package/build/prompts.d.ts +3 -3
  106. package/build/submit/context.js +0 -1
  107. package/build/submit/ios/IosSubmitCommand.js +6 -1
  108. package/build/submit/utils/urls.js +1 -1
  109. package/build/update/utils.js +4 -4
  110. package/build/user/actions.js +2 -2
  111. package/build/utils/expoCli.d.ts +3 -1
  112. package/build/utils/expoCli.js +13 -11
  113. package/build/utils/profiles.d.ts +1 -1
  114. package/build/utils/profiles.js +80 -30
  115. package/build/vcs/clients/git.js +2 -2
  116. package/oclif.manifest.json +1 -1
  117. package/package.json +16 -12
@@ -1,27 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getEASUpdateURLAsync = void 0;
4
3
  const tslib_1 = require("tslib");
5
4
  const config_1 = require("@expo/config");
6
5
  const eas_build_job_1 = require("@expo/eas-build-job");
7
6
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
+ const api_1 = require("../../api");
8
8
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
9
9
  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
- const EAS_UPDATE_URL = 'https://u.expo.dev';
13
- const DEFAULT_RUNTIME_VERSION = { policy: 'sdkVersion' };
14
- async function getEASUpdateURLAsync(exp) {
15
- const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
16
- return new URL(projectId, EAS_UPDATE_URL).href;
17
- }
18
- exports.getEASUpdateURLAsync = getEASUpdateURLAsync;
19
- async function configureProjectForEASUpdateAsync(projectDir, exp) {
12
+ const DEFAULT_MANAGED_RUNTIME_VERSION = { policy: 'sdkVersion' };
13
+ const DEFAULT_BARE_RUNTIME_VERSION = '1.0.0';
14
+ async function configureProjectForEASUpdateAsync(projectDir, exp, isBare) {
20
15
  var _a, _b;
21
- const easUpdateURL = await getEASUpdateURLAsync(exp);
16
+ const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
17
+ const easUpdateURL = (0, api_1.getEASUpdateURL)(projectId);
22
18
  const preexistingRuntimeVersion = exp.runtimeVersion;
19
+ const defaultRuntimeVersion = isBare
20
+ ? DEFAULT_BARE_RUNTIME_VERSION
21
+ : DEFAULT_MANAGED_RUNTIME_VERSION;
23
22
  const result = await (0, config_1.modifyConfigAsync)(projectDir, {
24
- runtimeVersion: preexistingRuntimeVersion !== null && preexistingRuntimeVersion !== void 0 ? preexistingRuntimeVersion : DEFAULT_RUNTIME_VERSION,
23
+ runtimeVersion: preexistingRuntimeVersion !== null && preexistingRuntimeVersion !== void 0 ? preexistingRuntimeVersion : defaultRuntimeVersion,
25
24
  updates: { ...exp.updates, url: easUpdateURL },
26
25
  });
27
26
  switch (result.type) {
@@ -35,7 +34,7 @@ async function configureProjectForEASUpdateAsync(projectDir, exp) {
35
34
  log_1.default.withTick(`Set updates.url value, to "${easUpdateURL}" in app.json`);
36
35
  }
37
36
  if (!preexistingRuntimeVersion) {
38
- log_1.default.withTick(`Set runtimeVersion to "${JSON.stringify(DEFAULT_RUNTIME_VERSION)}" in app.json`);
37
+ log_1.default.withTick(`Set runtimeVersion to "${JSON.stringify(defaultRuntimeVersion)}" in app.json`);
39
38
  }
40
39
  break;
41
40
  case 'warn': {
@@ -59,11 +58,12 @@ class UpdateConfigure extends EasCommand_1.default {
59
58
  const { exp } = (0, config_1.getConfig)(projectDir, {
60
59
  skipSDKVersionRequirement: true,
61
60
  });
62
- await configureProjectForEASUpdateAsync(projectDir, exp);
63
61
  const hasAndroidNativeProject = (await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.ANDROID)) === eas_build_job_1.Workflow.GENERIC;
64
62
  const hasIosNativeProject = (await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.IOS)) === eas_build_job_1.Workflow.GENERIC;
63
+ const isBare = hasAndroidNativeProject || hasIosNativeProject;
64
+ await configureProjectForEASUpdateAsync(projectDir, exp, isBare);
65
65
  log_1.default.addNewLineIfNone();
66
- if (hasAndroidNativeProject || hasIosNativeProject) {
66
+ if (isBare) {
67
67
  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
68
  }
69
69
  else {
@@ -1,6 +1,5 @@
1
1
  import EasCommand from '../../commandUtils/EasCommand';
2
2
  export default class UpdateDelete extends EasCommand {
3
- static hidden: boolean;
4
3
  static description: string;
5
4
  static args: {
6
5
  name: string;
@@ -8,7 +7,7 @@ export default class UpdateDelete extends EasCommand {
8
7
  description: string;
9
8
  }[];
10
9
  static flags: {
11
- json: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
10
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
11
  };
13
12
  runAsync(): Promise<void>;
14
13
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const command_1 = require("@oclif/command");
4
+ const core_1 = require("@oclif/core");
5
5
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6
6
  const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
7
7
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
@@ -23,7 +23,7 @@ async function deleteUpdateGroupAsync({ group, }) {
23
23
  }
24
24
  class UpdateDelete extends EasCommand_1.default {
25
25
  async runAsync() {
26
- const { args: { groupId: group }, flags: { json: jsonFlag }, } = this.parse(UpdateDelete);
26
+ const { args: { groupId: group }, flags: { json: jsonFlag }, } = await this.parse(UpdateDelete);
27
27
  if (!jsonFlag) {
28
28
  const shouldAbort = await (0, prompts_1.confirmAsync)({
29
29
  message: `🚨${chalk_1.default.red('CAUTION')}🚨\n\n` +
@@ -46,7 +46,6 @@ class UpdateDelete extends EasCommand_1.default {
46
46
  }
47
47
  }
48
48
  exports.default = UpdateDelete;
49
- UpdateDelete.hidden = true;
50
49
  UpdateDelete.description = 'Delete all the updates in an update Group.';
51
50
  UpdateDelete.args = [
52
51
  {
@@ -56,7 +55,7 @@ UpdateDelete.args = [
56
55
  },
57
56
  ];
58
57
  UpdateDelete.flags = {
59
- json: command_1.flags.boolean({
58
+ json: core_1.Flags.boolean({
60
59
  description: `Return a json with the group ID of the deleted updates.`,
61
60
  default: false,
62
61
  }),
@@ -0,0 +1,18 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ import { PublishPlatform } from '../../project/publish';
3
+ export declare const defaultPublishPlatforms: PublishPlatform[];
4
+ export default class UpdatePublish extends EasCommand {
5
+ static description: string;
6
+ static flags: {
7
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
9
+ republish: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ group: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
11
+ 'input-dir': import("@oclif/core/lib/interfaces").OptionFlag<string>;
12
+ 'skip-bundler': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
14
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ auto: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ };
17
+ runAsync(): Promise<void>;
18
+ }
@@ -0,0 +1,392 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultPublishPlatforms = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const config_1 = require("@expo/config");
6
+ const config_plugins_1 = require("@expo/config-plugins");
7
+ const eas_build_job_1 = require("@expo/eas-build-job");
8
+ const core_1 = require("@oclif/core");
9
+ const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
10
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
11
+ const dateformat_1 = (0, tslib_1.__importDefault)(require("dateformat"));
12
+ const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
13
+ const api_1 = require("../../api");
14
+ const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
15
+ const client_1 = require("../../graphql/client");
16
+ const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
17
+ const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
18
+ const ora_1 = require("../../ora");
19
+ const projectUtils_1 = require("../../project/projectUtils");
20
+ const publish_1 = require("../../project/publish");
21
+ const workflow_1 = require("../../project/workflow");
22
+ const prompts_1 = require("../../prompts");
23
+ const utils_1 = require("../../update/utils");
24
+ const uniqBy_1 = (0, tslib_1.__importDefault)(require("../../utils/expodash/uniqBy"));
25
+ const formatFields_1 = (0, tslib_1.__importDefault)(require("../../utils/formatFields"));
26
+ const vcs_1 = require("../../vcs");
27
+ const create_1 = require("../branch/create");
28
+ const list_1 = require("../branch/list");
29
+ const view_1 = require("../branch/view");
30
+ const create_2 = require("../channel/create");
31
+ exports.defaultPublishPlatforms = ['android', 'ios'];
32
+ async function getUpdateGroupAsync({ group, }) {
33
+ const { updatesByGroup } = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
34
+ .query((0, graphql_tag_1.default) `
35
+ query getUpdateGroupAsync($group: ID!) {
36
+ updatesByGroup(group: $group) {
37
+ id
38
+ group
39
+ runtimeVersion
40
+ manifestFragment
41
+ platform
42
+ message
43
+ }
44
+ }
45
+ `, {
46
+ group,
47
+ }, { additionalTypenames: ['Update'] })
48
+ .toPromise());
49
+ return updatesByGroup;
50
+ }
51
+ async function ensureChannelExistsAsync({ appId, branchId, channelName, }) {
52
+ var _a;
53
+ try {
54
+ await (0, create_2.createUpdateChannelOnAppAsync)({
55
+ appId,
56
+ channelName,
57
+ branchId,
58
+ });
59
+ log_1.default.withTick(`Created a channel: ${chalk_1.default.bold(channelName)} pointed at branch: ${chalk_1.default.bold(channelName)}.`);
60
+ }
61
+ catch (e) {
62
+ const isIgnorableError = ((_a = e.graphQLErrors) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
63
+ e.graphQLErrors[0].extensions.errorCode === 'CHANNEL_ALREADY_EXISTS';
64
+ if (!isIgnorableError) {
65
+ throw e;
66
+ }
67
+ }
68
+ }
69
+ async function ensureBranchExistsAsync({ appId, name: branchName, }) {
70
+ const { app } = await (0, view_1.viewUpdateBranchAsync)({
71
+ appId,
72
+ name: branchName,
73
+ });
74
+ const updateBranch = app === null || app === void 0 ? void 0 : app.byId.updateBranchByName;
75
+ if (updateBranch) {
76
+ const { id, updates } = updateBranch;
77
+ await ensureChannelExistsAsync({ appId, branchId: id, channelName: branchName });
78
+ return { id, updates };
79
+ }
80
+ const newUpdateBranch = await (0, create_1.createUpdateBranchOnAppAsync)({ appId, name: branchName });
81
+ log_1.default.withTick(`Created branch: ${chalk_1.default.bold(branchName)}`);
82
+ await ensureChannelExistsAsync({ appId, branchId: newUpdateBranch.id, channelName: branchName });
83
+ return { id: newUpdateBranch.id, updates: [] };
84
+ }
85
+ class UpdatePublish extends EasCommand_1.default {
86
+ async runAsync() {
87
+ var _a, _b, _c;
88
+ let { flags: { branch: branchName, json: jsonFlag, auto: autoFlag, message, republish, group, 'input-dir': inputDir, 'skip-bundler': skipBundler, platform, }, } = await this.parse(UpdatePublish);
89
+ const platformFlag = platform;
90
+ // If a group was specified, that means we are republishing it.
91
+ republish = group ? true : republish;
92
+ const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
93
+ const { exp } = (0, config_1.getConfig)(projectDir, {
94
+ skipSDKVersionRequirement: true,
95
+ isPublicConfig: true,
96
+ });
97
+ const runtimeVersions = await getRuntimeVersionObjectAsync(exp, platformFlag, projectDir);
98
+ const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
99
+ await checkEASUpdateURLIsSetAsync(exp);
100
+ if (!branchName && autoFlag) {
101
+ branchName =
102
+ (await (0, vcs_1.getVcsClient)().getBranchNameAsync()) ||
103
+ `branch-${Math.random().toString(36).substr(2, 4)}`;
104
+ }
105
+ if (!branchName) {
106
+ const validationMessage = 'Branch name may not be empty.';
107
+ if (jsonFlag) {
108
+ throw new Error(validationMessage);
109
+ }
110
+ const branches = await (0, list_1.listBranchesAsync)({ projectId });
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.');
130
+ }
131
+ const { id: branchId, updates } = await ensureBranchExistsAsync({
132
+ appId: projectId,
133
+ name: branchName,
134
+ });
135
+ let unsortedUpdateInfoGroups = {};
136
+ let oldMessage, oldRuntimeVersion;
137
+ if (republish) {
138
+ // If we are republishing, we don't need to worry about building the bundle or uploading the assets.
139
+ // Instead we get the `updateInfoGroup` from the update we wish to republish.
140
+ let updatesToRepublish;
141
+ if (group) {
142
+ updatesToRepublish = await getUpdateGroupAsync({ group });
143
+ }
144
+ else {
145
+ // Drop into interactive mode if the user has not specified an update group to republish.
146
+ if (jsonFlag) {
147
+ throw new Error('You must specify the update group to republish.');
148
+ }
149
+ const updateGroups = (0, uniqBy_1.default)(updates, u => u.group)
150
+ .filter(update => {
151
+ // Only show groups that have updates on the specified platform(s).
152
+ return platformFlag === 'all' || update.platform === platformFlag;
153
+ })
154
+ .map(update => ({
155
+ title: formatUpdateTitle(update),
156
+ value: update.group,
157
+ }));
158
+ if (updateGroups.length === 0) {
159
+ throw new Error(`There are no updates on branch "${branchName}" published on the platform(s) ${platformFlag}. Did you mean to publish a new update instead?`);
160
+ }
161
+ const selectedUpdateGroup = await (0, prompts_1.selectAsync)('which update would you like to republish?', updateGroups);
162
+ updatesToRepublish = updates.filter(update => update.group === selectedUpdateGroup);
163
+ }
164
+ const updatesToRepublishFilteredByPlatform = updatesToRepublish.filter(
165
+ // Only republish to the specified platforms
166
+ update => platformFlag === 'all' || update.platform === platformFlag);
167
+ if (updatesToRepublishFilteredByPlatform.length === 0) {
168
+ throw new Error(`There are no updates on branch "${branchName}" published on the platform(s) "${platformFlag}" with group ID "${group ? group : updatesToRepublish[0].group}". Did you mean to publish a new update instead?`);
169
+ }
170
+ let publicationPlatformMessage;
171
+ if (platformFlag === 'all') {
172
+ if (updatesToRepublishFilteredByPlatform.length !== exports.defaultPublishPlatforms.length) {
173
+ log_1.default.warn(`You are republishing an update that wasn't published for all platforms.`);
174
+ }
175
+ publicationPlatformMessage = `The republished update will appear on the same plaforms it was originally published on: ${updatesToRepublishFilteredByPlatform
176
+ .map(update => update.platform)
177
+ .join(', ')}`;
178
+ }
179
+ else {
180
+ publicationPlatformMessage = `The republished update will appear only on: ${platformFlag}`;
181
+ }
182
+ log_1.default.withTick(publicationPlatformMessage);
183
+ for (const update of updatesToRepublishFilteredByPlatform) {
184
+ const { manifestFragment } = update;
185
+ const platform = update.platform;
186
+ unsortedUpdateInfoGroups[platform] = JSON.parse(manifestFragment);
187
+ }
188
+ // These are the same for each member of an update group
189
+ group = updatesToRepublishFilteredByPlatform[0].group;
190
+ oldMessage = (_a = updatesToRepublishFilteredByPlatform[0].message) !== null && _a !== void 0 ? _a : '';
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
+ }
205
+ }
206
+ else {
207
+ if (!message && autoFlag) {
208
+ message = (_b = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _b === void 0 ? void 0 : _b.trim();
209
+ }
210
+ if (!message) {
211
+ const validationMessage = 'publish message may not be empty.';
212
+ if (jsonFlag) {
213
+ throw new Error(validationMessage);
214
+ }
215
+ ({ publishMessage: message } = await (0, prompts_1.promptAsync)({
216
+ type: 'text',
217
+ name: 'publishMessage',
218
+ message: `Please enter an update message.`,
219
+ initial: (_c = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _c === void 0 ? void 0 : _c.trim(),
220
+ validate: (value) => (value ? true : validationMessage),
221
+ }));
222
+ }
223
+ // build bundle and upload assets for a new publish
224
+ if (!skipBundler) {
225
+ const bundleSpinner = (0, ora_1.ora)().start('Building bundle...');
226
+ try {
227
+ await (0, publish_1.buildBundlesAsync)({ projectDir, inputDir });
228
+ bundleSpinner.succeed('Built bundle!');
229
+ }
230
+ catch (e) {
231
+ bundleSpinner.fail('Failed to build bundle!');
232
+ throw e;
233
+ }
234
+ }
235
+ const assetSpinner = (0, ora_1.ora)().start('Uploading assets...');
236
+ try {
237
+ const platforms = platformFlag === 'all' ? exports.defaultPublishPlatforms : [platformFlag];
238
+ const assets = await (0, publish_1.collectAssetsAsync)({ inputDir: inputDir, platforms });
239
+ await (0, publish_1.uploadAssetsAsync)(assets);
240
+ unsortedUpdateInfoGroups = await (0, publish_1.buildUnsortedUpdateInfoGroupAsync)(assets, exp);
241
+ assetSpinner.succeed('Uploaded assets!');
242
+ }
243
+ catch (e) {
244
+ assetSpinner.fail('Failed to upload assets');
245
+ throw e;
246
+ }
247
+ }
248
+ const runtimeToPlatformMapping = {};
249
+ for (const runtime of new Set(Object.values(runtimeVersions))) {
250
+ runtimeToPlatformMapping[runtime] = Object.entries(runtimeVersions)
251
+ .filter(pair => pair[1] === runtime)
252
+ .map(pair => pair[0]);
253
+ }
254
+ // Sort the updates into different groups based on their platform specific runtime versions
255
+ const updateGroups = Object.entries(runtimeToPlatformMapping).map(([runtime, platforms]) => {
256
+ const localUpdateInfoGroup = Object.fromEntries(platforms.map(platform => [
257
+ platform,
258
+ unsortedUpdateInfoGroups[platform],
259
+ ]));
260
+ if (republish && !oldRuntimeVersion) {
261
+ throw new Error('Can not find the runtime version of the update group that is being republished.');
262
+ }
263
+ return {
264
+ branchId,
265
+ updateInfoGroup: localUpdateInfoGroup,
266
+ runtimeVersion: republish ? oldRuntimeVersion : runtime,
267
+ message,
268
+ };
269
+ });
270
+ let newUpdates;
271
+ const publishSpinner = (0, ora_1.ora)('Publishing...').start();
272
+ try {
273
+ newUpdates = await PublishMutation_1.PublishMutation.publishUpdateGroupAsync(updateGroups);
274
+ publishSpinner.succeed('Published!');
275
+ }
276
+ catch (e) {
277
+ publishSpinner.fail('Failed to published updates');
278
+ throw e;
279
+ }
280
+ if (jsonFlag) {
281
+ log_1.default.log(JSON.stringify(newUpdates));
282
+ }
283
+ else {
284
+ if (new Set(newUpdates.map(update => update.group)).size > 1) {
285
+ log_1.default.addNewLineIfNone();
286
+ log_1.default.log('👉 Since multiple runtime versions are defined, multiple update groups have been published.');
287
+ }
288
+ log_1.default.addNewLineIfNone();
289
+ for (const runtime of new Set(Object.values(runtimeVersions))) {
290
+ const platforms = newUpdates
291
+ .filter(update => update.runtimeVersion === runtime)
292
+ .map(update => update.platform);
293
+ const newUpdate = newUpdates.find(update => update.runtimeVersion === runtime);
294
+ if (!newUpdate) {
295
+ throw new Error(`Publish response is missing updates with runtime ${runtime}.`);
296
+ }
297
+ log_1.default.log((0, formatFields_1.default)([
298
+ { label: 'branch', value: branchName },
299
+ { label: 'runtime version', value: runtime },
300
+ { label: 'platform', value: platforms.join(', ') },
301
+ { label: 'update group ID', value: newUpdate.group },
302
+ { label: 'message', value: message },
303
+ ]));
304
+ log_1.default.addNewLineIfNone();
305
+ }
306
+ }
307
+ }
308
+ }
309
+ exports.default = UpdatePublish;
310
+ UpdatePublish.description = 'Publish an update group.';
311
+ UpdatePublish.flags = {
312
+ branch: core_1.Flags.string({
313
+ description: 'Branch to publish the update group on',
314
+ required: false,
315
+ }),
316
+ message: core_1.Flags.string({
317
+ description: 'A short message describing the update',
318
+ required: false,
319
+ }),
320
+ republish: core_1.Flags.boolean({
321
+ description: 'Republish an update group',
322
+ exclusive: ['input-dir', 'skip-bundler'],
323
+ }),
324
+ group: core_1.Flags.string({
325
+ description: 'Update group to republish',
326
+ exclusive: ['input-dir', 'skip-bundler'],
327
+ }),
328
+ 'input-dir': core_1.Flags.string({
329
+ description: 'Location of the bundle',
330
+ default: 'dist',
331
+ required: false,
332
+ }),
333
+ 'skip-bundler': core_1.Flags.boolean({
334
+ description: `Skip running Expo CLI to bundle the app before publishing`,
335
+ default: false,
336
+ }),
337
+ platform: core_1.Flags.enum({
338
+ char: 'p',
339
+ options: [...exports.defaultPublishPlatforms, 'all'],
340
+ default: 'all',
341
+ required: false,
342
+ }),
343
+ json: core_1.Flags.boolean({
344
+ description: 'Enable JSON output, non-JSON messages will be printed to stderr',
345
+ default: false,
346
+ }),
347
+ auto: core_1.Flags.boolean({
348
+ description: 'Use the current git branch and commit message for the EAS branch and update message',
349
+ default: false,
350
+ }),
351
+ };
352
+ async function getRuntimeVersionObjectAsync(exp, platformFlag, projectDir) {
353
+ var _a, _b;
354
+ const platforms = (platformFlag === 'all' ? ['android', 'ios'] : [platformFlag]);
355
+ for (const platform of platforms) {
356
+ const isPolicy = typeof ((_b = (_a = exp[platform]) === null || _a === void 0 ? void 0 : _a.runtimeVersion) !== null && _b !== void 0 ? _b : exp.runtimeVersion) === 'object';
357
+ if (isPolicy) {
358
+ const isManaged = (await (0, workflow_1.resolveWorkflowAsync)(projectDir, platform)) === eas_build_job_1.Workflow.MANAGED;
359
+ if (!isManaged) {
360
+ throw new Error('Runtime version policies are only supported in the managed workflow.');
361
+ }
362
+ }
363
+ }
364
+ return Object.fromEntries(platforms.map(platform => [platform, config_plugins_1.Updates.getRuntimeVersion(exp, platform)]));
365
+ }
366
+ function formatUpdateTitle(update) {
367
+ const { message, createdAt, actor, runtimeVersion } = update;
368
+ let actorName;
369
+ switch (actor === null || actor === void 0 ? void 0 : actor.__typename) {
370
+ case 'User': {
371
+ actorName = actor.username;
372
+ break;
373
+ }
374
+ case 'Robot': {
375
+ const { firstName, id } = actor;
376
+ actorName = firstName !== null && firstName !== void 0 ? firstName : `robot: ${id.slice(0, 4)}...`;
377
+ break;
378
+ }
379
+ default:
380
+ actorName = 'unknown';
381
+ }
382
+ return `[${(0, dateformat_1.default)(createdAt, 'mmm dd HH:MM')} by ${actorName}, runtimeVersion: ${runtimeVersion}] ${message}`;
383
+ }
384
+ async function checkEASUpdateURLIsSetAsync(exp) {
385
+ var _a;
386
+ const configuredURL = (_a = exp.updates) === null || _a === void 0 ? void 0 : _a.url;
387
+ const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
388
+ const expectedURL = (0, api_1.getEASUpdateURL)(projectId);
389
+ if (configuredURL !== expectedURL) {
390
+ throw new Error(`The update URL is incorrectly configured for EAS Update. Please set updates.url to ${expectedURL} in your app.json.`);
391
+ }
392
+ }
@@ -4,7 +4,6 @@ export declare function viewUpdateAsync({ groupId, }: {
4
4
  groupId: string;
5
5
  }): Promise<UpdatesByGroupQuery>;
6
6
  export default class UpdateView extends EasCommand {
7
- static hidden: boolean;
8
7
  static description: string;
9
8
  static args: {
10
9
  name: string;
@@ -12,7 +11,7 @@ export default class UpdateView extends EasCommand {
12
11
  description: string;
13
12
  }[];
14
13
  static flags: {
15
- json: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
14
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
15
  };
17
16
  runAsync(): Promise<void>;
18
17
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.viewUpdateAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const command_1 = require("@oclif/command");
5
+ const core_1 = require("@oclif/core");
6
6
  const cli_table3_1 = (0, tslib_1.__importDefault)(require("cli-table3"));
7
7
  const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
8
8
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
@@ -44,7 +44,7 @@ exports.viewUpdateAsync = viewUpdateAsync;
44
44
  class UpdateView extends EasCommand_1.default {
45
45
  async runAsync() {
46
46
  var _a;
47
- const { args: { groupId }, flags: { json: jsonFlag }, } = this.parse(UpdateView);
47
+ const { args: { groupId }, flags: { json: jsonFlag }, } = await this.parse(UpdateView);
48
48
  const { updatesByGroup } = await viewUpdateAsync({ groupId });
49
49
  if (jsonFlag) {
50
50
  log_1.default.log(JSON.stringify(updatesByGroup));
@@ -68,7 +68,6 @@ class UpdateView extends EasCommand_1.default {
68
68
  }
69
69
  }
70
70
  exports.default = UpdateView;
71
- UpdateView.hidden = true;
72
71
  UpdateView.description = 'Update group details.';
73
72
  UpdateView.args = [
74
73
  {
@@ -78,7 +77,7 @@ UpdateView.args = [
78
77
  },
79
78
  ];
80
79
  UpdateView.flags = {
81
- json: command_1.flags.boolean({
80
+ json: core_1.Flags.boolean({
82
81
  description: `Return a json with the updates belonging to the group.`,
83
82
  default: false,
84
83
  }),
@@ -1,12 +1,11 @@
1
- import { flags } from '@oclif/command';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  import { WebhookType } from '../../graphql/generated';
4
3
  export default class WebhookCreate extends EasCommand {
5
4
  static description: string;
6
5
  static flags: {
7
- event: flags.IOptionFlag<WebhookType>;
8
- url: flags.IOptionFlag<string | undefined>;
9
- secret: flags.IOptionFlag<string | undefined>;
6
+ event: import("@oclif/core/lib/interfaces").OptionFlag<WebhookType>;
7
+ url: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ secret: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
10
9
  };
11
10
  runAsync(): Promise<void>;
12
11
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const config_1 = require("@expo/config");
5
- const command_1 = require("@oclif/command");
5
+ const core_1 = require("@oclif/core");
6
6
  const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
7
7
  const generated_1 = require("../../graphql/generated");
8
8
  const WebhookMutation_1 = require("../../graphql/mutations/WebhookMutation");
@@ -11,7 +11,7 @@ const projectUtils_1 = require("../../project/projectUtils");
11
11
  const input_1 = require("../../webhooks/input");
12
12
  class WebhookCreate extends EasCommand_1.default {
13
13
  async runAsync() {
14
- const { flags } = this.parse(WebhookCreate);
14
+ const { flags } = await this.parse(WebhookCreate);
15
15
  const webhookInputParams = await (0, input_1.prepareInputParamsAsync)(flags);
16
16
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
17
17
  const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
@@ -30,14 +30,14 @@ class WebhookCreate extends EasCommand_1.default {
30
30
  exports.default = WebhookCreate;
31
31
  WebhookCreate.description = 'Create a webhook on the current project.';
32
32
  WebhookCreate.flags = {
33
- event: command_1.flags.enum({
33
+ event: core_1.Flags.enum({
34
34
  description: 'Event type that triggers the webhook',
35
35
  options: [generated_1.WebhookType.Build, generated_1.WebhookType.Submit],
36
36
  }),
37
- url: command_1.flags.string({
37
+ url: core_1.Flags.string({
38
38
  description: 'Webhook URL',
39
39
  }),
40
- secret: command_1.flags.string({
40
+ secret: core_1.Flags.string({
41
41
  description: "Secret used to create a hash signature of the request payload, provided in the 'Expo-Signature' header.",
42
42
  }),
43
43
  };
@@ -15,7 +15,7 @@ const prompts_1 = require("../../prompts");
15
15
  const formatWebhook_1 = require("../../webhooks/formatWebhook");
16
16
  class WebhookDelete extends EasCommand_1.default {
17
17
  async runAsync() {
18
- let { args: { ID: webhookId }, } = this.parse(WebhookDelete);
18
+ let { args: { ID: webhookId }, } = await this.parse(WebhookDelete);
19
19
  const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
20
20
  const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
21
21
  const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
@@ -1,10 +1,9 @@
1
- import { flags } from '@oclif/command';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
2
  import { WebhookType } from '../../graphql/generated';
4
3
  export default class WebhookList extends EasCommand {
5
4
  static description: string;
6
5
  static flags: {
7
- event: flags.IOptionFlag<WebhookType>;
6
+ event: import("@oclif/core/lib/interfaces").OptionFlag<WebhookType>;
8
7
  };
9
8
  runAsync(): Promise<void>;
10
9
  }