eas-cli 1.0.0 → 1.2.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.
- package/README.md +72 -47
- package/build/analytics/events.d.ts +4 -1
- package/build/analytics/events.js +3 -0
- package/build/build/android/build.js +1 -1
- package/build/build/build.js +4 -4
- package/build/build/createContext.js +1 -0
- package/build/build/ios/graphql.js +0 -1
- package/build/build/utils/printBuildInfo.js +2 -2
- package/build/build/utils/repository.js +4 -4
- package/build/commandUtils/EasCommand.d.ts +2 -0
- package/build/commandUtils/EasCommand.js +44 -3
- package/build/commands/branch/create.js +1 -1
- package/build/commands/branch/delete.js +1 -1
- package/build/commands/branch/rename.js +2 -2
- package/build/commands/build/index.d.ts +2 -1
- package/build/commands/build/index.js +36 -18
- package/build/commands/channel/create.js +1 -1
- package/build/commands/channel/delete.js +1 -1
- package/build/commands/channel/edit.js +3 -3
- package/build/commands/channel/rollout.js +3 -3
- package/build/commands/channel/view.js +1 -1
- package/build/commands/credentials.d.ts +3 -0
- package/build/commands/credentials.js +6 -1
- package/build/commands/project/init.js +3 -1
- package/build/commands/secret/list.js +1 -1
- package/build/commands/submit.d.ts +2 -1
- package/build/commands/submit.js +28 -14
- package/build/commands/update/index.js +7 -4
- package/build/commands/update/list.js +1 -1
- package/build/credentials/android/actions/RemoveKeystore.js +1 -1
- package/build/credentials/android/api/GraphqlClient.js +1 -1
- package/build/credentials/context.d.ts +3 -0
- package/build/credentials/context.js +1 -0
- package/build/credentials/errors.js +1 -1
- package/build/credentials/ios/IosCredentialsProvider.d.ts +1 -0
- package/build/credentials/ios/IosCredentialsProvider.js +33 -5
- package/build/credentials/ios/actions/DistributionCertificateUtils.js +2 -2
- package/build/credentials/ios/actions/SetUpAdhocProvisioningProfile.js +1 -1
- package/build/credentials/ios/actions/SetUpInternalProvisioningProfile.js +2 -2
- package/build/credentials/ios/actions/SetUpProvisioningProfile.js +1 -1
- package/build/credentials/ios/actions/SetUpSubmissionCredentials.js +1 -1
- package/build/credentials/ios/api/GraphqlClient.js +1 -1
- package/build/credentials/ios/appstore/ascApiKey.d.ts +11 -0
- package/build/credentials/ios/appstore/ascApiKey.js +53 -3
- package/build/credentials/ios/appstore/bundleIdCapabilities.js +176 -15
- package/build/credentials/ios/appstore/contractMessages.js +1 -1
- package/build/credentials/ios/appstore/ensureAppExists.js +3 -3
- package/build/credentials/ios/appstore/pushKey.js +2 -2
- package/build/credentials/manager/ManageAndroid.js +2 -8
- package/build/credentials/manager/ManageIos.js +2 -4
- package/build/credentials/manager/SelectIosDistributionTypeGraphqlFromBuildProfile.js +1 -1
- package/build/credentials/manager/SelectPlatform.d.ts +2 -0
- package/build/credentials/manager/SelectPlatform.js +7 -12
- package/build/credentials/utils/promptForCredentials.js +1 -1
- package/build/devices/manager.js +1 -1
- package/build/graphql/client.js +1 -1
- package/build/graphql/generated.d.ts +191 -39
- package/build/graphql/generated.js +39 -1
- package/build/{credentials/ios/api/graphql → graphql}/queries/AppQuery.d.ts +1 -1
- package/build/{credentials/ios/api/graphql → graphql}/queries/AppQuery.js +2 -2
- package/build/graphql/queries/EnvironmentSecretsQuery.d.ts +1 -1
- package/build/graphql/queries/EnvironmentSecretsQuery.js +2 -2
- package/build/graphql/queries/StatuspageServiceQuery.d.ts +4 -0
- package/build/graphql/queries/StatuspageServiceQuery.js +28 -0
- package/build/graphql/types/StatuspageService.d.ts +1 -0
- package/build/graphql/types/StatuspageService.js +19 -0
- package/build/metadata/errors.js +2 -2
- package/build/project/ensureProjectExists.d.ts +0 -7
- package/build/project/ensureProjectExists.js +4 -14
- package/build/project/metroConfig.js +1 -1
- package/build/project/projectUtils.d.ts +16 -3
- package/build/project/projectUtils.js +47 -50
- package/build/submit/android/AndroidSubmitter.js +1 -1
- package/build/submit/submit.js +2 -2
- package/build/submit/utils/errors.js +11 -9
- package/build/update/utils.js +1 -1
- package/build/utils/statuspageService.d.ts +2 -0
- package/build/utils/statuspageService.js +41 -0
- package/build/vcs/local.d.ts +1 -0
- package/build/vcs/local.js +11 -2
- package/oclif.manifest.json +1 -1
- package/package.json +4 -7
- package/build/graphql/queries/ProjectQuery.d.ts +0 -6
- package/build/graphql/queries/ProjectQuery.js +0 -24
|
@@ -54,7 +54,7 @@ class BranchCreate extends EasCommand_1.default {
|
|
|
54
54
|
({ name } = await (0, prompts_1.promptAsync)({
|
|
55
55
|
type: 'text',
|
|
56
56
|
name: 'name',
|
|
57
|
-
message: '
|
|
57
|
+
message: 'Provide a branch name:',
|
|
58
58
|
initial: (await (0, vcs_1.getVcsClient)().getBranchNameAsync()) ||
|
|
59
59
|
`branch-${Math.random().toString(36).substr(2, 4)}`,
|
|
60
60
|
validate: value => (value ? true : validationMessage),
|
|
@@ -67,7 +67,7 @@ class BranchDelete extends EasCommand_1.default {
|
|
|
67
67
|
({ name } = await (0, prompts_1.promptAsync)({
|
|
68
68
|
type: 'text',
|
|
69
69
|
name: 'name',
|
|
70
|
-
message: '
|
|
70
|
+
message: 'Provide the name of the branch to delete:',
|
|
71
71
|
validate: value => (value ? true : validationMessage),
|
|
72
72
|
}));
|
|
73
73
|
}
|
|
@@ -50,7 +50,7 @@ class BranchRename extends EasCommand_1.default {
|
|
|
50
50
|
({ currentName } = await (0, prompts_1.promptAsync)({
|
|
51
51
|
type: 'text',
|
|
52
52
|
name: 'currentName',
|
|
53
|
-
message:
|
|
53
|
+
message: "Provide the name of the branch you'd like to rename:",
|
|
54
54
|
validate: value => (value ? true : validationMessage),
|
|
55
55
|
}));
|
|
56
56
|
}
|
|
@@ -62,7 +62,7 @@ class BranchRename extends EasCommand_1.default {
|
|
|
62
62
|
({ newName } = await (0, prompts_1.promptAsync)({
|
|
63
63
|
type: 'text',
|
|
64
64
|
name: 'newName',
|
|
65
|
-
message: `
|
|
65
|
+
message: `Rename ${currentName}`,
|
|
66
66
|
validate: value => (value ? true : validationMessage),
|
|
67
67
|
}));
|
|
68
68
|
}
|
|
@@ -19,5 +19,6 @@ export default class Build extends EasCommand {
|
|
|
19
19
|
message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
20
20
|
};
|
|
21
21
|
runAsync(): Promise<void>;
|
|
22
|
-
private
|
|
22
|
+
private sanitizeFlags;
|
|
23
|
+
private ensurePlatformSelectedAsync;
|
|
23
24
|
}
|
|
@@ -6,21 +6,29 @@ const path_1 = tslib_1.__importDefault(require("path"));
|
|
|
6
6
|
const runBuildAndSubmit_1 = require("../../build/runBuildAndSubmit");
|
|
7
7
|
const types_1 = require("../../build/types");
|
|
8
8
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
9
|
+
const generated_1 = require("../../graphql/generated");
|
|
9
10
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
10
11
|
const platform_1 = require("../../platform");
|
|
11
12
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
12
13
|
const json_1 = require("../../utils/json");
|
|
14
|
+
const statuspageService_1 = require("../../utils/statuspageService");
|
|
13
15
|
class Build extends EasCommand_1.default {
|
|
14
16
|
async runAsync() {
|
|
15
17
|
const { flags: rawFlags } = await this.parse(Build);
|
|
16
18
|
if (rawFlags.json) {
|
|
17
19
|
(0, json_1.enableJsonOutput)();
|
|
18
20
|
}
|
|
19
|
-
const flags =
|
|
21
|
+
const flags = this.sanitizeFlags(rawFlags);
|
|
20
22
|
const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
|
|
21
|
-
|
|
23
|
+
if (!flags.localBuildOptions.enable) {
|
|
24
|
+
await (0, statuspageService_1.maybeWarnAboutEasOutagesAsync)(flags.autoSubmit
|
|
25
|
+
? [generated_1.StatuspageServiceName.EasBuild, generated_1.StatuspageServiceName.EasSubmit]
|
|
26
|
+
: [generated_1.StatuspageServiceName.EasBuild]);
|
|
27
|
+
}
|
|
28
|
+
const flagsWithPlatform = await this.ensurePlatformSelectedAsync(flags);
|
|
29
|
+
await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(projectDir, flagsWithPlatform);
|
|
22
30
|
}
|
|
23
|
-
|
|
31
|
+
sanitizeFlags(flags) {
|
|
24
32
|
var _a, _b;
|
|
25
33
|
const nonInteractive = flags['non-interactive'];
|
|
26
34
|
if (!flags.local && flags.output) {
|
|
@@ -32,21 +40,10 @@ class Build extends EasCommand_1.default {
|
|
|
32
40
|
if (flags.json && !nonInteractive) {
|
|
33
41
|
core_1.Errors.error('--json is allowed only when building in non-interactive mode', { exit: 1 });
|
|
34
42
|
}
|
|
35
|
-
const requestedPlatform =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
core_1.Errors.error('Auto-submits are not yet supported when building locally', { exit: 1 });
|
|
40
|
-
}
|
|
41
|
-
if (requestedPlatform === platform_1.RequestedPlatform.All) {
|
|
42
|
-
core_1.Errors.error('Builds for multiple platforms are not supported with flag --local', {
|
|
43
|
-
exit: 1,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
else if (process.platform !== 'darwin' && requestedPlatform === platform_1.RequestedPlatform.Ios) {
|
|
47
|
-
core_1.Errors.error('Unsupported platform, macOS is required to build apps for iOS', { exit: 1 });
|
|
48
|
-
}
|
|
49
|
-
}
|
|
43
|
+
const requestedPlatform = flags.platform &&
|
|
44
|
+
Object.values(platform_1.RequestedPlatform).includes(flags.platform.toLowerCase())
|
|
45
|
+
? flags.platform.toLowerCase()
|
|
46
|
+
: undefined;
|
|
50
47
|
if (flags['skip-credentials-check']) {
|
|
51
48
|
log_1.default.warnDeprecatedFlag('skip-credentials-check', 'Build credentials validation is always skipped with the --non-interactive flag. You can also skip interactively.');
|
|
52
49
|
log_1.default.newLine();
|
|
@@ -82,6 +79,27 @@ class Build extends EasCommand_1.default {
|
|
|
82
79
|
message,
|
|
83
80
|
};
|
|
84
81
|
}
|
|
82
|
+
async ensurePlatformSelectedAsync(flags) {
|
|
83
|
+
const requestedPlatform = await (0, platform_1.selectRequestedPlatformAsync)(flags.requestedPlatform);
|
|
84
|
+
if (flags.localBuildOptions.enable) {
|
|
85
|
+
if (flags.autoSubmit) {
|
|
86
|
+
// TODO: implement this
|
|
87
|
+
core_1.Errors.error('Auto-submits are not yet supported when building locally', { exit: 1 });
|
|
88
|
+
}
|
|
89
|
+
if (requestedPlatform === platform_1.RequestedPlatform.All) {
|
|
90
|
+
core_1.Errors.error('Builds for multiple platforms are not supported with flag --local', {
|
|
91
|
+
exit: 1,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else if (process.platform !== 'darwin' && requestedPlatform === platform_1.RequestedPlatform.Ios) {
|
|
95
|
+
core_1.Errors.error('Unsupported platform, macOS is required to build apps for iOS', { exit: 1 });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
...flags,
|
|
100
|
+
requestedPlatform,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
85
103
|
}
|
|
86
104
|
exports.default = Build;
|
|
87
105
|
Build.description = 'start a build';
|
|
@@ -57,7 +57,7 @@ class ChannelCreate extends EasCommand_1.default {
|
|
|
57
57
|
({ name: channelName } = await (0, prompts_1.promptAsync)({
|
|
58
58
|
type: 'text',
|
|
59
59
|
name: 'name',
|
|
60
|
-
message: '
|
|
60
|
+
message: 'Provide a channel name:',
|
|
61
61
|
validate: value => (value ? true : validationMessage),
|
|
62
62
|
}));
|
|
63
63
|
}
|
|
@@ -35,7 +35,7 @@ class ChannelDelete extends EasCommand_1.default {
|
|
|
35
35
|
name = (await (0, prompts_1.promptAsync)({
|
|
36
36
|
type: 'text',
|
|
37
37
|
name: 'name',
|
|
38
|
-
message: '
|
|
38
|
+
message: 'Provide the name of the channel to delete:',
|
|
39
39
|
validate: (value) => (value ? true : 'Channel name may not be empty.'),
|
|
40
40
|
})).name;
|
|
41
41
|
}
|
|
@@ -74,7 +74,7 @@ class ChannelEdit extends EasCommand_1.default {
|
|
|
74
74
|
const channelName = (_a = args.name) !== null && _a !== void 0 ? _a : (await promptForChannelAsync());
|
|
75
75
|
const existingChannel = await getChannelByNameForAppAsync({ appId: projectId, channelName });
|
|
76
76
|
if (existingChannel.updateBranches.length > 1) {
|
|
77
|
-
throw new Error('There is a rollout in progress.
|
|
77
|
+
throw new Error('There is a rollout in progress. Manage it with "channel:rollout" instead.');
|
|
78
78
|
}
|
|
79
79
|
const branchName = (_b = flags.branch) !== null && _b !== void 0 ? _b : (await promptForBranchAsync());
|
|
80
80
|
const branch = await BranchQuery_1.BranchQuery.getBranchByNameAsync({
|
|
@@ -82,7 +82,7 @@ class ChannelEdit extends EasCommand_1.default {
|
|
|
82
82
|
name: branchName,
|
|
83
83
|
});
|
|
84
84
|
if (!branch) {
|
|
85
|
-
throw new Error(`Could not find a branch named "${branchName}".
|
|
85
|
+
throw new Error(`Could not find a branch named "${branchName}". Check what branches exist on this project with ${chalk_1.default.bold('eas branch:list')}.`);
|
|
86
86
|
}
|
|
87
87
|
const channel = await updateChannelBranchMappingAsync({
|
|
88
88
|
channelId: existingChannel.id,
|
|
@@ -125,7 +125,7 @@ async function promptForChannelAsync() {
|
|
|
125
125
|
const { name } = await (0, prompts_1.promptAsync)({
|
|
126
126
|
type: 'text',
|
|
127
127
|
name: 'name',
|
|
128
|
-
message: '
|
|
128
|
+
message: 'Provide the name of the channel to edit:',
|
|
129
129
|
validate: value => (value ? true : 'The channel name may not be empty.'),
|
|
130
130
|
});
|
|
131
131
|
return name;
|
|
@@ -48,7 +48,7 @@ async function startRolloutAsync({ channelName, branchName, percent, jsonFlag, p
|
|
|
48
48
|
name: branchName,
|
|
49
49
|
});
|
|
50
50
|
if (!branch) {
|
|
51
|
-
throw new Error(`Could not find a branch named "${branchName}".
|
|
51
|
+
throw new Error(`Could not find a branch named "${branchName}". Check which branches exist on this project with ${chalk_1.default.bold('eas branch:list')}.`);
|
|
52
52
|
}
|
|
53
53
|
const oldBranchId = currentBranchMapping.data[0].branchId;
|
|
54
54
|
if (branch.id === oldBranchId) {
|
|
@@ -114,7 +114,7 @@ async function endRolloutAsync({ channelName, branchName, jsonFlag, projectId, c
|
|
|
114
114
|
name: branchName,
|
|
115
115
|
});
|
|
116
116
|
if (!branch) {
|
|
117
|
-
throw new Error(`Could not find a branch named "${branchName}".
|
|
117
|
+
throw new Error(`Could not find a branch named "${branchName}". Check which branches exist on this project with ${chalk_1.default.bold('eas branch:list')}.`);
|
|
118
118
|
}
|
|
119
119
|
switch (branch.id) {
|
|
120
120
|
case newBranch.id:
|
|
@@ -176,7 +176,7 @@ class ChannelRollout extends EasCommand_1.default {
|
|
|
176
176
|
channelName: channelName,
|
|
177
177
|
});
|
|
178
178
|
if (!channel) {
|
|
179
|
-
throw new Error(`Could not find a channel named "${channelName}".
|
|
179
|
+
throw new Error(`Could not find a channel named "${channelName}". Check which channels exist on this project with ${chalk_1.default.bold('eas channel:list')}.`);
|
|
180
180
|
}
|
|
181
181
|
const { branchMapping: currentBranchMapping, isRollout } = (0, view_1.getBranchMapping)(channel.branchMapping);
|
|
182
182
|
if (currentBranchMapping.data.length === 0) {
|
|
@@ -119,7 +119,7 @@ class ChannelView extends EasCommand_1.default {
|
|
|
119
119
|
({ name: channelName } = await (0, prompts_1.promptAsync)({
|
|
120
120
|
type: 'text',
|
|
121
121
|
name: 'name',
|
|
122
|
-
message: '
|
|
122
|
+
message: 'Provide a channel name:',
|
|
123
123
|
validate: value => (value ? true : validationMessage),
|
|
124
124
|
}));
|
|
125
125
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
4
5
|
const EasCommand_1 = tslib_1.__importDefault(require("../commandUtils/EasCommand"));
|
|
5
6
|
const SelectPlatform_1 = require("../credentials/manager/SelectPlatform");
|
|
6
7
|
class Credentials extends EasCommand_1.default {
|
|
7
8
|
async runAsync() {
|
|
8
|
-
await
|
|
9
|
+
const { flags } = await this.parse(Credentials);
|
|
10
|
+
await new SelectPlatform_1.SelectPlatform(flags.platform).runAsync();
|
|
9
11
|
}
|
|
10
12
|
}
|
|
11
13
|
exports.default = Credentials;
|
|
12
14
|
Credentials.description = 'manage credentials';
|
|
15
|
+
Credentials.flags = {
|
|
16
|
+
platform: core_1.Flags.enum({ char: 'p', options: ['android', 'ios'] }),
|
|
17
|
+
};
|
|
@@ -15,7 +15,9 @@ class ProjectInit extends EasCommand_1.default {
|
|
|
15
15
|
log_1.default.error(`app.json is already linked to project with ID: ${chalk_1.default.bold((_d = (_c = exp.extra) === null || _c === void 0 ? void 0 : _c.eas) === null || _d === void 0 ? void 0 : _d.projectId)}`);
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
|
-
await (0, projectUtils_1.
|
|
18
|
+
const projectId = await (0, projectUtils_1.fetchProjectIdFromServerAsync)(exp);
|
|
19
|
+
await (0, projectUtils_1.saveProjectIdToAppConfigAsync)(projectDir, projectId);
|
|
20
|
+
log_1.default.withTick(`Linked app.json to project with ID ${chalk_1.default.bold(projectId)}`);
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
exports.default = ProjectInit;
|
|
@@ -16,7 +16,7 @@ class EnvironmentSecretList extends EasCommand_1.default {
|
|
|
16
16
|
const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
|
|
17
17
|
const projectAccountName = await (0, projectUtils_1.getProjectAccountNameAsync)(exp);
|
|
18
18
|
if (!projectDir) {
|
|
19
|
-
throw new Error("
|
|
19
|
+
throw new Error("Run this command inside your project's directory");
|
|
20
20
|
}
|
|
21
21
|
const secrets = await EnvironmentSecretsQuery_1.EnvironmentSecretsQuery.allAsync(projectAccountName, projectId);
|
|
22
22
|
const table = new cli_table3_1.default({
|
|
@@ -14,5 +14,6 @@ export default class Submit extends EasCommand {
|
|
|
14
14
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
15
|
};
|
|
16
16
|
runAsync(): Promise<void>;
|
|
17
|
-
private
|
|
17
|
+
private sanitizeFlags;
|
|
18
|
+
private ensurePlatformSelectedAsync;
|
|
18
19
|
}
|
package/build/commands/submit.js
CHANGED
|
@@ -5,6 +5,7 @@ const eas_json_1 = require("@expo/eas-json");
|
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
7
|
const EasCommand_1 = tslib_1.__importDefault(require("../commandUtils/EasCommand"));
|
|
8
|
+
const generated_1 = require("../graphql/generated");
|
|
8
9
|
const AppPlatform_1 = require("../graphql/types/AppPlatform");
|
|
9
10
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
10
11
|
const platform_1 = require("../platform");
|
|
@@ -14,19 +15,22 @@ const context_1 = require("../submit/context");
|
|
|
14
15
|
const submit_1 = require("../submit/submit");
|
|
15
16
|
const urls_1 = require("../submit/utils/urls");
|
|
16
17
|
const profiles_1 = require("../utils/profiles");
|
|
18
|
+
const statuspageService_1 = require("../utils/statuspageService");
|
|
17
19
|
class Submit extends EasCommand_1.default {
|
|
18
20
|
async runAsync() {
|
|
19
21
|
const { flags: rawFlags } = await this.parse(Submit);
|
|
20
|
-
const flags =
|
|
22
|
+
const flags = this.sanitizeFlags(rawFlags);
|
|
21
23
|
const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
|
|
22
24
|
const exp = (0, expoConfig_1.getExpoConfig)(projectDir);
|
|
23
25
|
const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
|
|
24
|
-
|
|
26
|
+
await (0, statuspageService_1.maybeWarnAboutEasOutagesAsync)([generated_1.StatuspageServiceName.EasSubmit]);
|
|
27
|
+
const flagsWithPlatform = await this.ensurePlatformSelectedAsync(flags);
|
|
28
|
+
const platforms = (0, platform_1.toPlatforms)(flagsWithPlatform.requestedPlatform);
|
|
25
29
|
const submissionProfiles = await (0, profiles_1.getProfilesAsync)({
|
|
26
30
|
type: 'submit',
|
|
27
31
|
easJsonReader: new eas_json_1.EasJsonReader(projectDir),
|
|
28
32
|
platforms,
|
|
29
|
-
profileName:
|
|
33
|
+
profileName: flagsWithPlatform.profile,
|
|
30
34
|
});
|
|
31
35
|
const submissions = [];
|
|
32
36
|
for (const submissionProfile of submissionProfiles) {
|
|
@@ -35,8 +39,8 @@ class Submit extends EasCommand_1.default {
|
|
|
35
39
|
projectDir,
|
|
36
40
|
projectId,
|
|
37
41
|
profile: submissionProfile.profile,
|
|
38
|
-
archiveFlags:
|
|
39
|
-
nonInteractive:
|
|
42
|
+
archiveFlags: flagsWithPlatform.archiveFlags,
|
|
43
|
+
nonInteractive: flagsWithPlatform.nonInteractive,
|
|
40
44
|
});
|
|
41
45
|
if (submissionProfiles.length > 1) {
|
|
42
46
|
log_1.default.newLine();
|
|
@@ -48,24 +52,22 @@ class Submit extends EasCommand_1.default {
|
|
|
48
52
|
}
|
|
49
53
|
log_1.default.newLine();
|
|
50
54
|
(0, urls_1.printSubmissionDetailsUrls)(submissions);
|
|
51
|
-
if (
|
|
55
|
+
if (flagsWithPlatform.wait) {
|
|
52
56
|
const completedSubmissions = await (0, submit_1.waitToCompleteAsync)(submissions, {
|
|
53
|
-
verbose:
|
|
57
|
+
verbose: flagsWithPlatform.verbose,
|
|
54
58
|
});
|
|
55
59
|
(0, submit_1.exitWithNonZeroCodeIfSomeSubmissionsDidntFinish)(completedSubmissions);
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
|
-
|
|
62
|
+
sanitizeFlags(flags) {
|
|
59
63
|
const { platform, verbose, wait, profile, 'non-interactive': nonInteractive, ...archiveFlags } = flags;
|
|
60
64
|
if (!flags.platform && nonInteractive) {
|
|
61
65
|
core_1.Errors.error('--platform is required when building in non-interactive mode', { exit: 1 });
|
|
62
66
|
}
|
|
63
|
-
const requestedPlatform =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
}
|
|
67
|
+
const requestedPlatform = flags.platform &&
|
|
68
|
+
Object.values(platform_1.RequestedPlatform).includes(flags.platform.toLowerCase())
|
|
69
|
+
? flags.platform.toLowerCase()
|
|
70
|
+
: undefined;
|
|
69
71
|
return {
|
|
70
72
|
archiveFlags,
|
|
71
73
|
requestedPlatform,
|
|
@@ -75,6 +77,18 @@ class Submit extends EasCommand_1.default {
|
|
|
75
77
|
nonInteractive,
|
|
76
78
|
};
|
|
77
79
|
}
|
|
80
|
+
async ensurePlatformSelectedAsync(flags) {
|
|
81
|
+
const requestedPlatform = await (0, platform_1.selectRequestedPlatformAsync)(flags.requestedPlatform);
|
|
82
|
+
if (requestedPlatform === platform_1.RequestedPlatform.All) {
|
|
83
|
+
if (flags.archiveFlags.id || flags.archiveFlags.path || flags.archiveFlags.url) {
|
|
84
|
+
core_1.Errors.error('--id, --path, and --url params are only supported when performing a single-platform submit', { exit: 1 });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
...flags,
|
|
89
|
+
requestedPlatform,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
78
92
|
}
|
|
79
93
|
exports.default = Submit;
|
|
80
94
|
Submit.description = 'submit app binary to App Store and/or Play Store';
|
|
@@ -16,6 +16,7 @@ const url_1 = require("../../build/utils/url");
|
|
|
16
16
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
17
17
|
const fetch_1 = tslib_1.__importDefault(require("../../fetch"));
|
|
18
18
|
const client_1 = require("../../graphql/client");
|
|
19
|
+
const generated_1 = require("../../graphql/generated");
|
|
19
20
|
const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
|
|
20
21
|
const BranchQuery_1 = require("../../graphql/queries/BranchQuery");
|
|
21
22
|
const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
|
|
@@ -32,6 +33,7 @@ const code_signing_1 = require("../../utils/code-signing");
|
|
|
32
33
|
const uniqBy_1 = tslib_1.__importDefault(require("../../utils/expodash/uniqBy"));
|
|
33
34
|
const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
|
|
34
35
|
const json_1 = require("../../utils/json");
|
|
36
|
+
const statuspageService_1 = require("../../utils/statuspageService");
|
|
35
37
|
const vcs_1 = require("../../vcs");
|
|
36
38
|
const create_1 = require("../branch/create");
|
|
37
39
|
const create_2 = require("../channel/create");
|
|
@@ -109,6 +111,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
109
111
|
const expPrivate = (0, expoConfig_1.getExpoConfig)(projectDir, {
|
|
110
112
|
isPublicConfig: false,
|
|
111
113
|
});
|
|
114
|
+
await (0, statuspageService_1.maybeWarnAboutEasOutagesAsync)([generated_1.StatuspageServiceName.EasUpdate]);
|
|
112
115
|
const codeSigningInfo = await (0, code_signing_1.getCodeSigningInfoAsync)(expPrivate, privateKeyPath);
|
|
113
116
|
const hasExpoUpdates = (0, projectUtils_1.isExpoUpdatesInstalledOrAvailable)(projectDir, exp.sdkVersion);
|
|
114
117
|
if (!hasExpoUpdates && nonInteractive) {
|
|
@@ -153,7 +156,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
153
156
|
({ name: branchName } = await (0, prompts_1.promptAsync)({
|
|
154
157
|
type: 'text',
|
|
155
158
|
name: 'name',
|
|
156
|
-
message: 'No branches found.
|
|
159
|
+
message: 'No branches found. Provide a branch name:',
|
|
157
160
|
initial: (await (0, vcs_1.getVcsClient)().getBranchNameAsync()) ||
|
|
158
161
|
`branch-${Math.random().toString(36).substr(2, 4)}`,
|
|
159
162
|
validate: value => (value ? true : validationMessage),
|
|
@@ -229,7 +232,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
229
232
|
({ publishMessage: message } = await (0, prompts_1.promptAsync)({
|
|
230
233
|
type: 'text',
|
|
231
234
|
name: 'publishMessage',
|
|
232
|
-
message: `
|
|
235
|
+
message: `Provide an update message.`,
|
|
233
236
|
initial: `Republish "${oldMessage}" - group: ${group}`,
|
|
234
237
|
validate: (value) => (value ? true : validationMessage),
|
|
235
238
|
}));
|
|
@@ -250,7 +253,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
250
253
|
({ publishMessage: message } = await (0, prompts_1.promptAsync)({
|
|
251
254
|
type: 'text',
|
|
252
255
|
name: 'publishMessage',
|
|
253
|
-
message: `
|
|
256
|
+
message: `Provide an update message.`,
|
|
254
257
|
initial: (_c = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _c === void 0 ? void 0 : _c.trim(),
|
|
255
258
|
validate: (value) => (value ? true : validationMessage),
|
|
256
259
|
}));
|
|
@@ -529,7 +532,7 @@ async function checkEASUpdateURLIsSetAsync(exp) {
|
|
|
529
532
|
const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
|
|
530
533
|
const expectedURL = (0, api_1.getEASUpdateURL)(projectId);
|
|
531
534
|
if (configuredURL !== expectedURL) {
|
|
532
|
-
throw new Error(`The update URL is incorrectly configured for EAS Update.
|
|
535
|
+
throw new Error(`The update URL is incorrectly configured for EAS Update. Set updates.url to ${expectedURL} in your ${chalk_1.default.bold('app.json')}.`);
|
|
533
536
|
}
|
|
534
537
|
}
|
|
535
538
|
const truncatePublishUpdateMessage = (originalMessage) => {
|
|
@@ -47,7 +47,7 @@ class BranchView extends EasCommand_1.default {
|
|
|
47
47
|
({ name: branchInteractive } = await (0, prompts_1.promptAsync)({
|
|
48
48
|
type: 'text',
|
|
49
49
|
name: 'name',
|
|
50
|
-
message: '
|
|
50
|
+
message: 'Provide the name of the branch whose updates you wish to view:',
|
|
51
51
|
initial: (_a = (await (0, vcs_1.getVcsClient)().getBranchNameAsync())) !== null && _a !== void 0 ? _a : undefined,
|
|
52
52
|
validate: (value) => (value ? true : validationMessage),
|
|
53
53
|
}));
|
|
@@ -35,7 +35,7 @@ class RemoveKeystore {
|
|
|
35
35
|
log_1.default.newLine();
|
|
36
36
|
log_1.default.warn(`Clearing your Android build credentials from our build servers is a ${chalk_1.default.bold('PERMANENT and IRREVERSIBLE action.')}`);
|
|
37
37
|
log_1.default.warn(chalk_1.default.bold('Android Keystore must be identical to the one previously used to submit your app to the Google Play Store.'));
|
|
38
|
-
log_1.default.warn('
|
|
38
|
+
log_1.default.warn('Read https://docs.expo.dev/distribution/building-standalone-apps/#if-you-choose-to-build-for-android for more info before proceeding.');
|
|
39
39
|
log_1.default.newLine();
|
|
40
40
|
log_1.default.warn(chalk_1.default.bold('Your Keystore will be backed up to your current directory if you continue.'));
|
|
41
41
|
log_1.default.newLine();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.formatProjectFullName = exports.getGoogleServiceAccountKeysForAccountAsync = exports.deleteGoogleServiceAccountKeyAsync = exports.createGoogleServiceAccountKeyAsync = exports.deleteFcmAsync = exports.createFcmAsync = exports.deleteKeystoreAsync = exports.createKeystoreAsync = exports.createOrUpdateDefaultIosAppBuildCredentialsAsync = exports.createOrUpdateAndroidAppBuildCredentialsByNameAsync = exports.getAndroidAppBuildCredentialsByNameAsync = exports.getDefaultAndroidAppBuildCredentialsAsync = exports.createAndroidAppBuildCredentialsAsync = exports.updateAndroidAppBuildCredentialsAsync = exports.updateAndroidAppCredentialsAsync = exports.createOrGetExistingAndroidAppCredentialsWithBuildCredentialsAsync = exports.getLegacyAndroidAppBuildCredentialsAsync = exports.getLegacyAndroidAppCredentialsWithCommonFieldsAsync = exports.getAndroidAppBuildCredentialsListAsync = exports.getAndroidAppCredentialsWithCommonFieldsAsync = void 0;
|
|
4
|
-
const AppQuery_1 = require("
|
|
4
|
+
const AppQuery_1 = require("../../../graphql/queries/AppQuery");
|
|
5
5
|
const AndroidAppBuildCredentialsMutation_1 = require("./graphql/mutations/AndroidAppBuildCredentialsMutation");
|
|
6
6
|
const AndroidAppCredentialsMutation_1 = require("./graphql/mutations/AndroidAppCredentialsMutation");
|
|
7
7
|
const AndroidFcmMutation_1 = require("./graphql/mutations/AndroidFcmMutation");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ExpoConfig } from '@expo/config';
|
|
2
2
|
import { Env } from '@expo/eas-build-job';
|
|
3
|
+
import { EasJson } from '@expo/eas-json';
|
|
3
4
|
import { Actor } from '../user/User';
|
|
4
5
|
import * as AndroidGraphqlClient from './android/api/GraphqlClient';
|
|
5
6
|
import * as IosGraphqlClient from './ios/api/GraphqlClient';
|
|
@@ -12,10 +13,12 @@ export declare class CredentialsContext {
|
|
|
12
13
|
readonly nonInteractive: boolean;
|
|
13
14
|
readonly projectDir: string;
|
|
14
15
|
readonly user: Actor;
|
|
16
|
+
readonly easJsonCliConfig?: EasJson['cli'];
|
|
15
17
|
private shouldAskAuthenticateAppStore;
|
|
16
18
|
private resolvedExp?;
|
|
17
19
|
constructor(options: {
|
|
18
20
|
exp?: ExpoConfig;
|
|
21
|
+
easJsonCliConfig?: EasJson['cli'];
|
|
19
22
|
nonInteractive?: boolean;
|
|
20
23
|
projectDir: string;
|
|
21
24
|
user: Actor;
|
|
@@ -20,6 +20,7 @@ class CredentialsContext {
|
|
|
20
20
|
this.appStore = new AppStoreApi_1.default();
|
|
21
21
|
this.ios = IosGraphqlClient;
|
|
22
22
|
this.shouldAskAuthenticateAppStore = true;
|
|
23
|
+
this.easJsonCliConfig = options.easJsonCliConfig;
|
|
23
24
|
this.projectDir = options.projectDir;
|
|
24
25
|
this.user = options.user;
|
|
25
26
|
this.nonInteractive = (_a = options.nonInteractive) !== null && _a !== void 0 ? _a : false;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.UnsupportedCredentialsChoiceError = exports.MissingCredentialsError = exports.MissingCredentialsNonInteractiveError = void 0;
|
|
4
4
|
class MissingCredentialsNonInteractiveError extends Error {
|
|
5
5
|
constructor(message) {
|
|
6
|
-
super(message !== null && message !== void 0 ? message : 'Credentials are not set up.
|
|
6
|
+
super(message !== null && message !== void 0 ? message : 'Credentials are not set up. Run this command again in interactive mode.');
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.MissingCredentialsNonInteractiveError = MissingCredentialsNonInteractiveError;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
5
5
|
const eas_json_1 = require("@expo/eas-json");
|
|
6
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
6
7
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
7
8
|
const target_1 = require("../../project/ios/target");
|
|
8
9
|
const prompts_1 = require("../../prompts");
|
|
@@ -12,6 +13,12 @@ const BuildCredentialsUtils_1 = require("./actions/BuildCredentialsUtils");
|
|
|
12
13
|
const SetUpBuildCredentials_1 = require("./actions/SetUpBuildCredentials");
|
|
13
14
|
const SetUpPushKey_1 = require("./actions/SetUpPushKey");
|
|
14
15
|
const provisioningProfile_1 = require("./utils/provisioningProfile");
|
|
16
|
+
var PushNotificationSetupOption;
|
|
17
|
+
(function (PushNotificationSetupOption) {
|
|
18
|
+
PushNotificationSetupOption[PushNotificationSetupOption["YES"] = 0] = "YES";
|
|
19
|
+
PushNotificationSetupOption[PushNotificationSetupOption["NO"] = 1] = "NO";
|
|
20
|
+
PushNotificationSetupOption[PushNotificationSetupOption["NO_DONT_ASK_AGAIN"] = 2] = "NO_DONT_ASK_AGAIN";
|
|
21
|
+
})(PushNotificationSetupOption || (PushNotificationSetupOption = {}));
|
|
15
22
|
class IosCredentialsProvider {
|
|
16
23
|
constructor(ctx, options) {
|
|
17
24
|
this.ctx = ctx;
|
|
@@ -47,6 +54,7 @@ class IosCredentialsProvider {
|
|
|
47
54
|
}).runAsync(this.ctx);
|
|
48
55
|
}
|
|
49
56
|
async getPushKeyAsync(ctx, targets) {
|
|
57
|
+
var _a;
|
|
50
58
|
if (ctx.nonInteractive) {
|
|
51
59
|
return null;
|
|
52
60
|
}
|
|
@@ -63,13 +71,33 @@ class IosCredentialsProvider {
|
|
|
63
71
|
log_1.default.succeed(`Push Notifications setup for ${app.projectName}: ${applicationTarget.bundleIdentifier}`);
|
|
64
72
|
return null;
|
|
65
73
|
}
|
|
66
|
-
|
|
67
|
-
message: `Would you like to set up Push Notifications for your project?`,
|
|
68
|
-
});
|
|
69
|
-
if (!confirmSetup) {
|
|
74
|
+
if (((_a = ctx.easJsonCliConfig) === null || _a === void 0 ? void 0 : _a.promptToConfigurePushNotfications) === false) {
|
|
70
75
|
return null;
|
|
71
76
|
}
|
|
72
|
-
|
|
77
|
+
const setupOption = await (0, prompts_1.selectAsync)(`Would you like to set up Push Notifications for your project?`, [
|
|
78
|
+
{ title: 'Yes', value: PushNotificationSetupOption.YES },
|
|
79
|
+
{ title: 'No', value: PushNotificationSetupOption.NO },
|
|
80
|
+
{
|
|
81
|
+
title: `No, don't ask again (preference will be saved to eas.json)`,
|
|
82
|
+
value: PushNotificationSetupOption.NO_DONT_ASK_AGAIN,
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
if (setupOption === PushNotificationSetupOption.YES) {
|
|
86
|
+
return await setupPushKeyAction.runAsync(ctx);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
if (setupOption === PushNotificationSetupOption.NO_DONT_ASK_AGAIN) {
|
|
90
|
+
await this.disablePushNotificationsSetupInEasJsonAsync(ctx);
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async disablePushNotificationsSetupInEasJsonAsync(ctx) {
|
|
96
|
+
const easJsonPath = eas_json_1.EasJsonReader.formatEasJsonPath(ctx.projectDir);
|
|
97
|
+
const easJson = await fs_extra_1.default.readJSON(easJsonPath);
|
|
98
|
+
easJson.cli = { ...easJson === null || easJson === void 0 ? void 0 : easJson.cli, promptToConfigurePushNotfications: false };
|
|
99
|
+
await fs_extra_1.default.writeFile(easJsonPath, `${JSON.stringify(easJson, null, 2)}\n`);
|
|
100
|
+
log_1.default.withTick('Updated eas.json');
|
|
73
101
|
}
|
|
74
102
|
assertProvisioningProfileType(provisioningProfile, targetName) {
|
|
75
103
|
const isAdHoc = (0, provisioningProfile_1.isAdHocProfile)(provisioningProfile);
|
|
@@ -96,8 +96,8 @@ async function selectValidDistributionCertificateAsync(ctx, appLookupParams) {
|
|
|
96
96
|
exports.selectValidDistributionCertificateAsync = selectValidDistributionCertificateAsync;
|
|
97
97
|
const APPLE_DIST_CERTS_TOO_MANY_GENERATED_ERROR = `
|
|
98
98
|
You can have only ${chalk_1.default.underline('three')} Apple Distribution Certificates generated on your Apple Developer account.
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
Revoke the old ones or reuse existing from your other apps.
|
|
100
|
+
Remember that Apple Distribution Certificates are not application specific!
|
|
101
101
|
`;
|
|
102
102
|
async function provideOrGenerateDistributionCertificateAsync(ctx) {
|
|
103
103
|
if (!ctx.nonInteractive) {
|
|
@@ -34,7 +34,7 @@ class SetUpAdhocProvisioningProfile {
|
|
|
34
34
|
return (0, nullthrows_1.default)(await (0, BuildCredentialsUtils_1.getBuildCredentialsAsync)(ctx, this.app, generated_1.IosDistributionType.AdHoc));
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
throw new errors_1.MissingCredentialsNonInteractiveError('Provisioning profile is not configured correctly.
|
|
37
|
+
throw new errors_1.MissingCredentialsNonInteractiveError('Provisioning profile is not configured correctly. Run this command again in interactive mode.');
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const currentBuildCredentials = await (0, BuildCredentialsUtils_1.getBuildCredentialsAsync)(ctx, this.app, generated_1.IosDistributionType.AdHoc);
|
|
@@ -59,7 +59,7 @@ class SetUpInternalProvisioningProfile {
|
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
61
|
if (adhocBuildCredentialsExist && enterpriseBuildCredentialsExist) {
|
|
62
|
-
throw new Error(`You're in non-interactive mode. You have set up both adhoc and universal distribution credentials.
|
|
62
|
+
throw new Error(`You're in non-interactive mode. You have set up both adhoc and universal distribution credentials. Set the 'enterpriseProvisioning' property (to 'adhoc' or 'universal') in eas.json to choose the credentials to use.`);
|
|
63
63
|
}
|
|
64
64
|
else if (adhocBuildCredentialsExist) {
|
|
65
65
|
return await this.setupAdhocProvisioningProfileAsync(ctx);
|
|
@@ -68,7 +68,7 @@ class SetUpInternalProvisioningProfile {
|
|
|
68
68
|
return await this.setupUniversalProvisioningProfileAsync(ctx);
|
|
69
69
|
}
|
|
70
70
|
else {
|
|
71
|
-
throw new Error(`You're in non-interactive mode. EAS CLI couldn't find any credentials suitable for internal distribution.
|
|
71
|
+
throw new Error(`You're in non-interactive mode. EAS CLI couldn't find any credentials suitable for internal distribution. Run this command again in interactive mode.`);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|