eas-cli 0.31.1 → 0.34.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 +29 -28
- package/build/analytics.js +3 -9
- package/build/build/android/UpdatesModule.js +4 -15
- package/build/build/android/configure.js +3 -3
- package/build/build/android/graphql.js +2 -4
- package/build/build/android/prepareJob.js +4 -3
- package/build/build/build.js +2 -2
- package/build/build/configure.js +26 -13
- package/build/build/ios/UpdatesModule.js +6 -18
- package/build/build/ios/configure.js +1 -1
- package/build/build/ios/graphql.js +2 -23
- package/build/build/ios/prepareJob.js +4 -6
- package/build/build/metadata.js +5 -10
- package/build/build/utils/appJson.d.ts +1 -0
- package/build/build/utils/appJson.js +13 -4
- package/build/build/utils/devClient.d.ts +4 -4
- package/build/build/utils/devClient.js +10 -18
- package/build/build/utils/repository.js +10 -7
- package/build/build/validate.js +4 -4
- package/build/commandUtils/EasCommand.d.ts +1 -0
- package/build/commandUtils/EasCommand.js +21 -0
- package/build/commands/branch/create.js +3 -2
- package/build/commands/branch/delete.js +1 -1
- package/build/commands/branch/list.js +1 -1
- package/build/commands/branch/publish.js +20 -48
- package/build/commands/branch/view.js +1 -1
- package/build/commands/build/index.d.ts +1 -1
- package/build/commands/build/index.js +64 -49
- package/build/commands/channel/edit.js +1 -1
- package/build/commands/channel/list.js +1 -1
- package/build/commands/channel/view.js +1 -1
- package/build/commands/diagnostics.js +2 -2
- package/build/commands/project/info.js +1 -1
- package/build/commands/submit.js +16 -11
- package/build/commands/update/view.js +1 -1
- package/build/credentials/android/api/graphql/queries/GoogleServiceAccountKeyQuery.js +2 -0
- package/build/credentials/context.d.ts +1 -1
- package/build/credentials/context.js +5 -5
- package/build/credentials/credentialsJson/update.js +5 -4
- package/build/credentials/errors.d.ts +3 -0
- package/build/credentials/errors.js +7 -1
- package/build/credentials/ios/IosCredentialsProvider.js +1 -1
- package/build/credentials/ios/actions/AscApiKeyUtils.d.ts +5 -0
- package/build/credentials/ios/actions/AscApiKeyUtils.js +63 -0
- package/build/credentials/ios/actions/CreateDistributionCertificate.js +1 -1
- package/build/credentials/ios/actions/CreatePushKey.js +1 -1
- package/build/credentials/ios/actions/DistributionCertificateUtils.d.ts +1 -1
- package/build/credentials/ios/actions/DistributionCertificateUtils.js +10 -12
- package/build/credentials/ios/actions/PushKeyUtils.d.ts +1 -1
- package/build/credentials/ios/actions/PushKeyUtils.js +5 -5
- package/build/credentials/ios/actions/SetupTargetBuildCredentials.js +1 -1
- package/build/credentials/ios/api/graphql/queries/AppQuery.js +3 -1
- package/build/credentials/ios/api/graphql/queries/AppleDeviceQuery.js +6 -2
- package/build/credentials/ios/api/graphql/queries/AppleDistributionCertificateQuery.js +7 -1
- package/build/credentials/ios/api/graphql/queries/AppleProvisioningProfileQuery.js +5 -1
- package/build/credentials/ios/api/graphql/queries/ApplePushKeyQuery.js +2 -0
- package/build/credentials/ios/api/graphql/queries/AppleTeamQuery.js +5 -1
- package/build/credentials/ios/appstore/AppStoreApi.d.ts +7 -1
- package/build/credentials/ios/appstore/AppStoreApi.js +17 -0
- package/build/credentials/ios/appstore/Credentials.js +3 -3
- package/build/credentials/ios/appstore/Credentials.types.d.ts +13 -0
- package/build/credentials/ios/appstore/ascApiKey.d.ts +9 -0
- package/build/credentials/ios/appstore/ascApiKey.js +99 -0
- package/build/credentials/ios/credentials.d.ts +17 -0
- package/build/credentials/ios/credentials.js +16 -1
- package/build/credentials/manager/Actions.d.ts +47 -0
- package/build/credentials/manager/Actions.js +48 -0
- package/build/credentials/manager/AndroidActions.d.ts +6 -0
- package/build/credentials/manager/AndroidActions.js +114 -0
- package/build/credentials/manager/IosActions.d.ts +6 -0
- package/build/credentials/manager/IosActions.js +110 -0
- package/build/credentials/manager/ManageAndroid.d.ts +1 -29
- package/build/credentials/manager/ManageAndroid.js +26 -159
- package/build/credentials/manager/ManageIos.d.ts +1 -29
- package/build/credentials/manager/ManageIos.js +28 -155
- package/build/graphql/client.d.ts +8 -2
- package/build/graphql/generated.d.ts +134 -121
- package/build/graphql/generated.js +46 -28
- package/build/graphql/queries/BuildQuery.js +4 -1
- package/build/graphql/queries/EnvironmentSecretsQuery.js +4 -2
- package/build/graphql/queries/ProjectQuery.js +3 -1
- package/build/graphql/queries/PublishQuery.js +4 -1
- package/build/graphql/queries/SubmissionQuery.js +5 -2
- package/build/graphql/queries/UserQuery.js +4 -1
- package/build/graphql/queries/WebhookQuery.js +6 -2
- package/build/log.d.ts +11 -3
- package/build/log.js +23 -22
- package/build/project/android/applicationId.d.ts +1 -1
- package/build/project/android/applicationId.js +7 -6
- package/build/project/ios/bundleIdentifier.d.ts +1 -1
- package/build/project/ios/bundleIdentifier.js +7 -6
- package/build/project/projectUtils.js +1 -1
- package/build/project/publish.js +2 -2
- package/build/project/workflow.js +2 -2
- package/build/submit/ArchiveSource.d.ts +7 -2
- package/build/submit/ArchiveSource.js +94 -11
- package/build/submit/ios/AscApiKeySource.d.ts +28 -0
- package/build/submit/ios/AscApiKeySource.js +51 -0
- package/build/submit/ios/IosSubmitCommand.d.ts +2 -0
- package/build/submit/ios/IosSubmitCommand.js +55 -3
- package/build/submit/ios/IosSubmitter.d.ts +3 -1
- package/build/submit/ios/IosSubmitter.js +49 -5
- package/build/submit/submit.js +1 -1
- package/build/submit/utils/builds.d.ts +3 -1
- package/build/submit/utils/builds.js +6 -6
- package/build/user/User.js +1 -0
- package/build/utils/easCli.d.ts +1 -0
- package/build/utils/easCli.js +5 -0
- package/build/utils/{expoCommand.d.ts → expoCli.d.ts} +0 -0
- package/build/utils/{expoCommand.js → expoCli.js} +0 -0
- package/build/utils/profiles.d.ts +11 -0
- package/build/utils/profiles.js +46 -0
- package/build/vcs/clients/git.d.ts +26 -0
- package/build/vcs/clients/git.js +184 -0
- package/build/vcs/clients/gitNoCommit.d.ts +7 -0
- package/build/vcs/clients/gitNoCommit.js +27 -0
- package/build/vcs/clients/noVcs.d.ts +6 -0
- package/build/vcs/clients/noVcs.js +19 -0
- package/build/vcs/git.d.ts +10 -17
- package/build/vcs/git.js +7 -175
- package/build/vcs/index.d.ts +2 -2
- package/build/vcs/index.js +15 -6
- package/build/vcs/local.d.ts +18 -5
- package/build/vcs/local.js +61 -32
- package/build/vcs/vcs.d.ts +2 -1
- package/build/vcs/vcs.js +8 -4
- package/oclif.manifest.json +1 -1
- package/package.json +7 -7
|
@@ -6,12 +6,14 @@ const results_1 = require("@expo/results");
|
|
|
6
6
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
7
7
|
const getenv_1 = (0, tslib_1.__importDefault)(require("getenv"));
|
|
8
8
|
const wrap_ansi_1 = (0, tslib_1.__importDefault)(require("wrap-ansi"));
|
|
9
|
+
const errors_1 = require("../../credentials/errors");
|
|
9
10
|
const log_1 = (0, tslib_1.__importStar)(require("../../log"));
|
|
10
11
|
const prompts_1 = require("../../prompts");
|
|
11
12
|
const UserSettings_1 = (0, tslib_1.__importDefault)(require("../../user/UserSettings"));
|
|
12
13
|
const commons_1 = require("../commons");
|
|
13
14
|
const AppProduce_1 = require("./AppProduce");
|
|
14
15
|
const AppSpecificPasswordSource_1 = require("./AppSpecificPasswordSource");
|
|
16
|
+
const AscApiKeySource_1 = require("./AscApiKeySource");
|
|
15
17
|
const IosSubmitter_1 = (0, tslib_1.__importDefault)(require("./IosSubmitter"));
|
|
16
18
|
class IosSubmitCommand {
|
|
17
19
|
constructor(ctx) {
|
|
@@ -23,14 +25,30 @@ class IosSubmitCommand {
|
|
|
23
25
|
const submitter = new IosSubmitter_1.default(this.ctx, options);
|
|
24
26
|
return await submitter.submitAsync();
|
|
25
27
|
}
|
|
28
|
+
async resolveCredentialSubmissionOptionsAsync() {
|
|
29
|
+
// Fall back to app specific password if no ascApiKey defined
|
|
30
|
+
const ascApiKeySource = this.resolveAscApiKeySource();
|
|
31
|
+
const shouldUseAppSpecificPassword = !ascApiKeySource.ok && ascApiKeySource.enforceError() instanceof errors_1.MissingCredentialsError;
|
|
32
|
+
if (shouldUseAppSpecificPassword) {
|
|
33
|
+
return { appSpecificPasswordSource: this.resolveAppSpecificPasswordSource() };
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return { ascApiKeySource };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
26
39
|
async resolveSubmissionOptionsAsync() {
|
|
27
40
|
const archiveSource = this.resolveArchiveSource();
|
|
28
|
-
const
|
|
41
|
+
const credentialsSource = await this.resolveCredentialSubmissionOptionsAsync();
|
|
42
|
+
const maybeAppSpecificPasswordSource = 'appSpecificPasswordSource' in credentialsSource
|
|
43
|
+
? credentialsSource.appSpecificPasswordSource
|
|
44
|
+
: null;
|
|
45
|
+
const maybeAscApiKeySource = 'ascApiKeySource' in credentialsSource ? credentialsSource.ascApiKeySource : null;
|
|
29
46
|
const ascAppIdentifier = await this.resolveAscAppIdentifierAsync();
|
|
30
47
|
const appleIdUsername = await this.resolveAppleIdUsernameAsync();
|
|
31
48
|
const errored = [
|
|
32
49
|
archiveSource,
|
|
33
|
-
|
|
50
|
+
...(maybeAppSpecificPasswordSource ? [maybeAppSpecificPasswordSource] : []),
|
|
51
|
+
...(maybeAscApiKeySource ? [maybeAscApiKeySource] : []),
|
|
34
52
|
ascAppIdentifier,
|
|
35
53
|
appleIdUsername,
|
|
36
54
|
].filter(r => !r.ok);
|
|
@@ -44,7 +62,16 @@ class IosSubmitCommand {
|
|
|
44
62
|
appleIdUsername: appleIdUsername.enforceValue(),
|
|
45
63
|
ascAppIdentifier: ascAppIdentifier.enforceValue(),
|
|
46
64
|
archiveSource: archiveSource.enforceValue(),
|
|
47
|
-
|
|
65
|
+
...(maybeAppSpecificPasswordSource
|
|
66
|
+
? {
|
|
67
|
+
appSpecificPasswordSource: maybeAppSpecificPasswordSource.enforceValue(),
|
|
68
|
+
}
|
|
69
|
+
: null),
|
|
70
|
+
...(maybeAscApiKeySource
|
|
71
|
+
? {
|
|
72
|
+
ascApiKeySource: maybeAscApiKeySource.enforceValue(),
|
|
73
|
+
}
|
|
74
|
+
: null),
|
|
48
75
|
};
|
|
49
76
|
}
|
|
50
77
|
resolveAppSpecificPasswordSource() {
|
|
@@ -64,6 +91,27 @@ class IosSubmitCommand {
|
|
|
64
91
|
});
|
|
65
92
|
}
|
|
66
93
|
}
|
|
94
|
+
resolveAscApiKeySource() {
|
|
95
|
+
const { ascApiKeyPath, ascApiKeyIssuerId, ascApiKeyId } = this.ctx.profile;
|
|
96
|
+
if (ascApiKeyPath && ascApiKeyIssuerId && ascApiKeyId) {
|
|
97
|
+
return (0, results_1.result)({
|
|
98
|
+
sourceType: AscApiKeySource_1.AscApiKeySourceType.path,
|
|
99
|
+
path: {
|
|
100
|
+
keyP8Path: ascApiKeyPath,
|
|
101
|
+
issuerId: ascApiKeyIssuerId,
|
|
102
|
+
keyId: ascApiKeyId,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// interpret this to mean the user had some intention of passing in ASC Api key
|
|
107
|
+
if (ascApiKeyPath || ascApiKeyIssuerId || ascApiKeyId) {
|
|
108
|
+
log_1.default.warn(`ascApiKeyPath, ascApiKeyIssuerId and ascApiKeyId must all be defined in eas.json`);
|
|
109
|
+
return (0, results_1.result)({
|
|
110
|
+
sourceType: AscApiKeySource_1.AscApiKeySourceType.prompt,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return (0, results_1.result)(new errors_1.MissingCredentialsError('Set the ascApiKeyPath, ascApiKeyIssuerId and ascApiKeyId fields in eas.json.'));
|
|
114
|
+
}
|
|
67
115
|
resolveArchiveSource() {
|
|
68
116
|
try {
|
|
69
117
|
return (0, results_1.result)((0, commons_1.resolveArchiveSource)(this.ctx, eas_build_job_1.Platform.IOS));
|
|
@@ -93,6 +141,7 @@ class IosSubmitCommand {
|
|
|
93
141
|
}
|
|
94
142
|
}
|
|
95
143
|
async resolveAppleIdUsernameAsync() {
|
|
144
|
+
var _a;
|
|
96
145
|
if (this.ctx.profile.appleId) {
|
|
97
146
|
return (0, results_1.result)(this.ctx.profile.appleId);
|
|
98
147
|
}
|
|
@@ -100,6 +149,9 @@ class IosSubmitCommand {
|
|
|
100
149
|
if (envAppleId) {
|
|
101
150
|
return (0, results_1.result)(envAppleId);
|
|
102
151
|
}
|
|
152
|
+
if ((_a = this.ctx.credentialsCtx.appStore.authCtx) === null || _a === void 0 ? void 0 : _a.appleId) {
|
|
153
|
+
return (0, results_1.result)(this.ctx.credentialsCtx.appStore.authCtx.appleId);
|
|
154
|
+
}
|
|
103
155
|
// Get the email address that was last used and set it as
|
|
104
156
|
// the default value for quicker authentication.
|
|
105
157
|
const lastAppleId = await UserSettings_1.default.getAsync('appleId', null);
|
|
@@ -3,10 +3,12 @@ import { IosSubmissionConfigInput, SubmissionFragment } from '../../graphql/gene
|
|
|
3
3
|
import { ArchiveSource } from '../ArchiveSource';
|
|
4
4
|
import BaseSubmitter, { SubmissionInput } from '../BaseSubmitter';
|
|
5
5
|
import { AppSpecificPasswordSource } from './AppSpecificPasswordSource';
|
|
6
|
+
import { AscApiKeySource } from './AscApiKeySource';
|
|
6
7
|
export interface IosSubmissionOptions extends Pick<IosSubmissionConfigInput, 'appleIdUsername' | 'ascAppIdentifier'> {
|
|
7
8
|
projectId: string;
|
|
8
9
|
archiveSource: ArchiveSource;
|
|
9
|
-
appSpecificPasswordSource
|
|
10
|
+
appSpecificPasswordSource?: AppSpecificPasswordSource;
|
|
11
|
+
ascApiKeySource?: AscApiKeySource;
|
|
10
12
|
}
|
|
11
13
|
export default class IosSubmitter extends BaseSubmitter<Platform.IOS, IosSubmissionOptions> {
|
|
12
14
|
submitAsync(): Promise<SubmissionFragment>;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
4
5
|
const SubmissionMutation_1 = require("../../graphql/mutations/SubmissionMutation");
|
|
6
|
+
const formatFields_1 = (0, tslib_1.__importDefault)(require("../../utils/formatFields"));
|
|
5
7
|
const ArchiveSource_1 = require("../ArchiveSource");
|
|
6
8
|
const BaseSubmitter_1 = (0, tslib_1.__importDefault)(require("../BaseSubmitter"));
|
|
7
9
|
const summary_1 = require("../utils/summary");
|
|
8
10
|
const AppSpecificPasswordSource_1 = require("./AppSpecificPasswordSource");
|
|
11
|
+
const AscApiKeySource_1 = require("./AscApiKeySource");
|
|
9
12
|
class IosSubmitter extends BaseSubmitter_1.default {
|
|
10
13
|
async submitAsync() {
|
|
11
14
|
var _a;
|
|
@@ -27,28 +30,46 @@ class IosSubmitter extends BaseSubmitter_1.default {
|
|
|
27
30
|
}
|
|
28
31
|
async resolveSourceOptionsAsync() {
|
|
29
32
|
const archive = await (0, ArchiveSource_1.getArchiveAsync)(this.options.archiveSource);
|
|
30
|
-
const
|
|
33
|
+
const maybeAppSpecificPassword = this.options.appSpecificPasswordSource
|
|
34
|
+
? await (0, AppSpecificPasswordSource_1.getAppSpecificPasswordAsync)(this.options.appSpecificPasswordSource)
|
|
35
|
+
: null;
|
|
36
|
+
const maybeAppStoreConnectApiKey = this.options.ascApiKeySource
|
|
37
|
+
? await (0, AscApiKeySource_1.getAscApiKeyLocallyAsync)(this.options.ascApiKeySource)
|
|
38
|
+
: null;
|
|
31
39
|
return {
|
|
32
40
|
archive,
|
|
33
|
-
appSpecificPassword,
|
|
41
|
+
...(maybeAppSpecificPassword ? { appSpecificPassword: maybeAppSpecificPassword } : null),
|
|
42
|
+
...(maybeAppStoreConnectApiKey ? { ascApiKeyResult: maybeAppStoreConnectApiKey } : null),
|
|
34
43
|
};
|
|
35
44
|
}
|
|
36
|
-
async formatSubmissionConfigAsync(options, { archive, appSpecificPassword }) {
|
|
45
|
+
async formatSubmissionConfigAsync(options, { archive, appSpecificPassword, ascApiKeyResult }) {
|
|
37
46
|
const { appleIdUsername, ascAppIdentifier } = options;
|
|
38
47
|
return {
|
|
39
48
|
ascAppIdentifier,
|
|
40
49
|
appleIdUsername,
|
|
41
50
|
archiveUrl: archive.url,
|
|
42
51
|
appleAppSpecificPassword: appSpecificPassword,
|
|
52
|
+
...((ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result)
|
|
53
|
+
? {
|
|
54
|
+
ascApiKey: {
|
|
55
|
+
keyP8: ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result.keyP8,
|
|
56
|
+
keyIdentifier: ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result.keyId,
|
|
57
|
+
issuerIdentifier: ascApiKeyResult === null || ascApiKeyResult === void 0 ? void 0 : ascApiKeyResult.result.issuerId,
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
: null),
|
|
43
61
|
};
|
|
44
62
|
}
|
|
45
|
-
prepareSummaryData(options, { archive }) {
|
|
63
|
+
prepareSummaryData(options, { archive, ascApiKeyResult }) {
|
|
46
64
|
const { appleIdUsername, ascAppIdentifier, projectId } = options;
|
|
47
65
|
// structuring order affects table rows order
|
|
48
66
|
return {
|
|
49
67
|
ascAppIdentifier,
|
|
50
|
-
appleIdUsername,
|
|
68
|
+
appleIdUsername: appleIdUsername !== null && appleIdUsername !== void 0 ? appleIdUsername : undefined,
|
|
51
69
|
projectId,
|
|
70
|
+
...(ascApiKeyResult
|
|
71
|
+
? { formattedAscApiKey: formatServiceAccountSummary(ascApiKeyResult) }
|
|
72
|
+
: null),
|
|
52
73
|
...(0, summary_1.formatArchiveSourceSummary)(archive),
|
|
53
74
|
};
|
|
54
75
|
}
|
|
@@ -61,4 +82,27 @@ const SummaryHumanReadableKeys = {
|
|
|
61
82
|
archiveUrl: 'Archive URL',
|
|
62
83
|
archivePath: 'Archive Path',
|
|
63
84
|
formattedBuild: 'Build',
|
|
85
|
+
formattedAscApiKey: 'App Store Connect Api Key',
|
|
64
86
|
};
|
|
87
|
+
function formatServiceAccountSummary({ summary }) {
|
|
88
|
+
const { source, path, keyId } = summary;
|
|
89
|
+
const fields = [
|
|
90
|
+
{
|
|
91
|
+
label: 'Key Source',
|
|
92
|
+
value: source,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
label: 'Key Path',
|
|
96
|
+
value: path,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Key ID',
|
|
100
|
+
value: keyId,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
const filteredFields = fields.filter(({ value }) => value !== undefined && value !== null);
|
|
104
|
+
return ('\n' +
|
|
105
|
+
(0, formatFields_1.default)(filteredFields, {
|
|
106
|
+
labelFormat: label => ` ${chalk_1.default.dim(label)}:`,
|
|
107
|
+
}));
|
|
108
|
+
}
|
package/build/submit/submit.js
CHANGED
|
@@ -58,7 +58,7 @@ function printInstructionsForIosSubmission(submission) {
|
|
|
58
58
|
'- It usually takes about 5-10 minutes depending on how busy Apple servers are.',
|
|
59
59
|
// ascAppIdentifier should be always available for ios submissions but check it anyway
|
|
60
60
|
((_a = submission.iosConfig) === null || _a === void 0 ? void 0 : _a.ascAppIdentifier) &&
|
|
61
|
-
`- When it’s done, you can see your build here: ${(0, log_1.
|
|
61
|
+
`- When it’s done, you can see your build here: ${(0, log_1.link)(`https://appstoreconnect.apple.com/apps/${(_b = submission.iosConfig) === null || _b === void 0 ? void 0 : _b.ascAppIdentifier}/appstore/ios`)}`,
|
|
62
62
|
].join('\n');
|
|
63
63
|
log_1.default.addNewLineIfNone();
|
|
64
64
|
log_1.default.log(logMsg);
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { AppPlatform, BuildFragment } from '../../graphql/generated';
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function getRecentBuildsForSubmissionAsync(platform: AppPlatform, appId: string, { limit }?: {
|
|
3
|
+
limit?: number;
|
|
4
|
+
}): Promise<BuildFragment[]>;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getRecentBuildsForSubmissionAsync = void 0;
|
|
4
4
|
const generated_1 = require("../../graphql/generated");
|
|
5
5
|
const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
|
|
6
|
-
async function
|
|
7
|
-
|
|
8
|
-
limit
|
|
6
|
+
async function getRecentBuildsForSubmissionAsync(platform, appId, { limit = 1 } = {}) {
|
|
7
|
+
return await BuildQuery_1.BuildQuery.allForAppAsync(appId, {
|
|
8
|
+
limit,
|
|
9
9
|
filter: {
|
|
10
10
|
platform,
|
|
11
|
+
distribution: generated_1.DistributionType.Store,
|
|
11
12
|
status: generated_1.BuildStatus.Finished,
|
|
12
13
|
},
|
|
13
14
|
});
|
|
14
|
-
return build;
|
|
15
15
|
}
|
|
16
|
-
exports.
|
|
16
|
+
exports.getRecentBuildsForSubmissionAsync = getRecentBuildsForSubmissionAsync;
|
package/build/user/User.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const easCliVersion: string;
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Platform } from '@expo/eas-build-job';
|
|
2
|
+
export declare type ProfileData<T> = {
|
|
3
|
+
profile: T;
|
|
4
|
+
platform: Platform;
|
|
5
|
+
profileName: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function getProfilesAsync<T>({ platforms, profileName: profileNameArg, readProfileAsync, }: {
|
|
8
|
+
platforms: Platform[];
|
|
9
|
+
profileName?: string | null;
|
|
10
|
+
readProfileAsync: (platform: Platform, profileName: string) => Promise<T>;
|
|
11
|
+
}): Promise<ProfileData<T>[]>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProfilesAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const eas_json_1 = require("@expo/eas-json");
|
|
6
|
+
const log_1 = (0, tslib_1.__importDefault)(require("../log"));
|
|
7
|
+
async function getProfilesAsync({ platforms, profileName: profileNameArg,
|
|
8
|
+
// eslint-disable-next-line async-protect/async-suffix
|
|
9
|
+
readProfileAsync, }) {
|
|
10
|
+
const results = platforms.map(async function (platform) {
|
|
11
|
+
let profile;
|
|
12
|
+
let profileName = profileNameArg;
|
|
13
|
+
if (!profileName) {
|
|
14
|
+
try {
|
|
15
|
+
profile = await readProfileAsync(platform, 'production');
|
|
16
|
+
profileName = 'production';
|
|
17
|
+
}
|
|
18
|
+
catch (errorOuter) {
|
|
19
|
+
if (errorOuter instanceof eas_json_1.errors.InvalidEasJsonError) {
|
|
20
|
+
throw errorOuter;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
profile = await readProfileAsync(platform, 'release');
|
|
24
|
+
profileName = 'release';
|
|
25
|
+
log_1.default.warn('The default profile changed from "release" to "production". We detected that you still have a "release" build profile, so we are using it. Update eas.json to have a profile named "production" under the `build` key, or specify which profile you\'d like to use with the --profile flag. This fallback behavior will be removed in the next major version of EAS CLI.');
|
|
26
|
+
}
|
|
27
|
+
catch (errorInner) {
|
|
28
|
+
if (errorInner instanceof eas_json_1.errors.InvalidEasJsonError) {
|
|
29
|
+
throw errorInner;
|
|
30
|
+
}
|
|
31
|
+
throw new Error('There is no profile named "production" in eas.json');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
profile = await readProfileAsync(platform, profileName);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
profile,
|
|
40
|
+
profileName,
|
|
41
|
+
platform,
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
return await Promise.all(results);
|
|
45
|
+
}
|
|
46
|
+
exports.getProfilesAsync = getProfilesAsync;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Client } from '../vcs';
|
|
2
|
+
export default class GitClient extends Client {
|
|
3
|
+
ensureRepoExistsAsync(): Promise<void>;
|
|
4
|
+
commitAsync({ commitMessage, commitAllFiles, }: {
|
|
5
|
+
commitMessage: string;
|
|
6
|
+
commitAllFiles?: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
isCommitRequiredAsync(): Promise<boolean>;
|
|
9
|
+
hasUncommittedChangesAsync(): Promise<boolean>;
|
|
10
|
+
getRootPathAsync(): Promise<string>;
|
|
11
|
+
makeShallowCopyAsync(destinationPath: string): Promise<void>;
|
|
12
|
+
getCommitHashAsync(): Promise<string | undefined>;
|
|
13
|
+
trackFileAsync(file: string): Promise<void>;
|
|
14
|
+
getBranchNameAsync(): Promise<string | null>;
|
|
15
|
+
getLastCommitMessageAsync(): Promise<string | null>;
|
|
16
|
+
showDiffAsync(): Promise<void>;
|
|
17
|
+
isFileUntrackedAsync(path: string): Promise<boolean>;
|
|
18
|
+
isFileIgnoredAsync(filePath: string): Promise<boolean>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Checks if git is configured to be case sensitive
|
|
22
|
+
* @returns {boolean | undefined}
|
|
23
|
+
* - boolean - is git case sensitive
|
|
24
|
+
* - undefined - case sensitivity is not configured and git is using default behavior
|
|
25
|
+
*/
|
|
26
|
+
export declare function isGitCaseSensitiveAsync(): Promise<boolean | undefined>;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isGitCaseSensitiveAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = (0, tslib_1.__importDefault)(require("@expo/spawn-async"));
|
|
6
|
+
const log_1 = (0, tslib_1.__importStar)(require("../../log"));
|
|
7
|
+
const prompts_1 = require("../../prompts");
|
|
8
|
+
const git_1 = require("../git");
|
|
9
|
+
const vcs_1 = require("../vcs");
|
|
10
|
+
class GitClient extends vcs_1.Client {
|
|
11
|
+
async ensureRepoExistsAsync() {
|
|
12
|
+
if (!(await (0, git_1.isGitInstalledAsync)())) {
|
|
13
|
+
throw new Error('git command not found, install it before proceeding');
|
|
14
|
+
}
|
|
15
|
+
if (await (0, git_1.doesGitRepoExistAsync)()) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
log_1.default.warn("It looks like you haven't initialized the git repository yet.");
|
|
19
|
+
log_1.default.warn('EAS Build requires you to use a git repository for your project.');
|
|
20
|
+
const confirmInit = await (0, prompts_1.confirmAsync)({
|
|
21
|
+
message: `Would you like us to run 'git init' in the current directory for you?`,
|
|
22
|
+
});
|
|
23
|
+
if (!confirmInit) {
|
|
24
|
+
throw new Error('A git repository is required for building your project. Initialize it and run this command again.');
|
|
25
|
+
}
|
|
26
|
+
await (0, spawn_async_1.default)('git', ['init']);
|
|
27
|
+
log_1.default.log("We're going to make an initial commit for your repository.");
|
|
28
|
+
const { message } = await (0, prompts_1.promptAsync)({
|
|
29
|
+
type: 'text',
|
|
30
|
+
name: 'message',
|
|
31
|
+
message: 'Commit message:',
|
|
32
|
+
initial: 'Initial commit',
|
|
33
|
+
validate: (input) => input !== '',
|
|
34
|
+
});
|
|
35
|
+
await this.commitAsync({ commitAllFiles: true, commitMessage: message });
|
|
36
|
+
}
|
|
37
|
+
async commitAsync({ commitMessage, commitAllFiles, }) {
|
|
38
|
+
if (commitAllFiles) {
|
|
39
|
+
await (0, spawn_async_1.default)('git', ['add', '-A']);
|
|
40
|
+
}
|
|
41
|
+
await (0, spawn_async_1.default)('git', ['add', '-u']);
|
|
42
|
+
await (0, spawn_async_1.default)('git', ['commit', '-m', commitMessage]);
|
|
43
|
+
}
|
|
44
|
+
async isCommitRequiredAsync() {
|
|
45
|
+
return await this.hasUncommittedChangesAsync();
|
|
46
|
+
}
|
|
47
|
+
async hasUncommittedChangesAsync() {
|
|
48
|
+
const changes = await (0, git_1.gitStatusAsync)({ showUntracked: true });
|
|
49
|
+
return changes.length > 0;
|
|
50
|
+
}
|
|
51
|
+
async getRootPathAsync() {
|
|
52
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--show-toplevel'])).stdout.trim();
|
|
53
|
+
}
|
|
54
|
+
async makeShallowCopyAsync(destinationPath) {
|
|
55
|
+
if (await this.hasUncommittedChangesAsync()) {
|
|
56
|
+
// it should already be checked before this function is called, but in case it wasn't
|
|
57
|
+
// we want to ensure that any changes were introduced by call to `setGitCaseSensitivityAsync`
|
|
58
|
+
throw new Error('You have some uncommitted changes in your repository.');
|
|
59
|
+
}
|
|
60
|
+
let gitRepoUri;
|
|
61
|
+
if (process.platform === 'win32') {
|
|
62
|
+
// getRootDirectoryAsync() will return C:/path/to/repo on Windows and path
|
|
63
|
+
// prefix should be file:///
|
|
64
|
+
gitRepoUri = `file:///${await this.getRootPathAsync()}`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// getRootDirectoryAsync() will /path/to/repo, and path prefix should be
|
|
68
|
+
// file:/// so only file:// needs to be prepended
|
|
69
|
+
gitRepoUri = `file://${await this.getRootPathAsync()}`;
|
|
70
|
+
}
|
|
71
|
+
const isCaseSensitive = await isGitCaseSensitiveAsync();
|
|
72
|
+
await setGitCaseSensitivityAsync(true);
|
|
73
|
+
try {
|
|
74
|
+
if (await this.hasUncommittedChangesAsync()) {
|
|
75
|
+
log_1.default.error('Detected inconsistent filename casing between your local filesystem and git.');
|
|
76
|
+
log_1.default.error('This will likely cause your build to fail. Impacted files:');
|
|
77
|
+
await (0, spawn_async_1.default)('git', ['status', '--short'], { stdio: 'inherit' });
|
|
78
|
+
log_1.default.newLine();
|
|
79
|
+
log_1.default.error(`Error: Resolve filename casing inconsistencies before proceeding. ${(0, log_1.learnMore)('https://expo.fyi/macos-ignorecase')}`);
|
|
80
|
+
throw new Error('You have some uncommitted changes in your repository.');
|
|
81
|
+
}
|
|
82
|
+
await (0, spawn_async_1.default)('git', [
|
|
83
|
+
'clone',
|
|
84
|
+
'--no-hardlinks',
|
|
85
|
+
'--depth',
|
|
86
|
+
'1',
|
|
87
|
+
gitRepoUri,
|
|
88
|
+
destinationPath,
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await setGitCaseSensitivityAsync(isCaseSensitive);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async getCommitHashAsync() {
|
|
96
|
+
try {
|
|
97
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', 'HEAD'])).stdout.trim();
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async trackFileAsync(file) {
|
|
104
|
+
await (0, spawn_async_1.default)('git', ['add', '--intent-to-add', file]);
|
|
105
|
+
}
|
|
106
|
+
async getBranchNameAsync() {
|
|
107
|
+
try {
|
|
108
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim();
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async getLastCommitMessageAsync() {
|
|
115
|
+
try {
|
|
116
|
+
return (await (0, spawn_async_1.default)('git', ['--no-pager', 'log', '-1', '--pretty=%B'])).stdout.trim();
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async showDiffAsync() {
|
|
123
|
+
const outputTooLarge = (await (0, git_1.getGitDiffOutputAsync)()).split(/\r\n|\r|\n/).length > 100;
|
|
124
|
+
await (0, git_1.gitDiffAsync)({ withPager: outputTooLarge });
|
|
125
|
+
}
|
|
126
|
+
async isFileUntrackedAsync(path) {
|
|
127
|
+
const withUntrackedFiles = await (0, git_1.gitStatusAsync)({ showUntracked: true });
|
|
128
|
+
const trackedFiles = await (0, git_1.gitStatusAsync)({ showUntracked: false });
|
|
129
|
+
const pathWithoutLeadingDot = path.replace(/^\.\//, ''); // remove leading './' from path
|
|
130
|
+
return (withUntrackedFiles.includes(pathWithoutLeadingDot) &&
|
|
131
|
+
!trackedFiles.includes(pathWithoutLeadingDot));
|
|
132
|
+
}
|
|
133
|
+
async isFileIgnoredAsync(filePath) {
|
|
134
|
+
try {
|
|
135
|
+
await (0, spawn_async_1.default)('git', ['check-ignore', '-q', filePath]);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.default = GitClient;
|
|
144
|
+
/**
|
|
145
|
+
* Checks if git is configured to be case sensitive
|
|
146
|
+
* @returns {boolean | undefined}
|
|
147
|
+
* - boolean - is git case sensitive
|
|
148
|
+
* - undefined - case sensitivity is not configured and git is using default behavior
|
|
149
|
+
*/
|
|
150
|
+
async function isGitCaseSensitiveAsync() {
|
|
151
|
+
if (process.platform !== 'darwin') {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const result = await (0, spawn_async_1.default)('git', ['config', '--get', 'core.ignorecase']);
|
|
156
|
+
const isIgnoreCaseEnabled = result.stdout.trim();
|
|
157
|
+
if (isIgnoreCaseEnabled === '') {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
else if (isIgnoreCaseEnabled === 'true') {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.isGitCaseSensitiveAsync = isGitCaseSensitiveAsync;
|
|
172
|
+
async function setGitCaseSensitivityAsync(enable) {
|
|
173
|
+
// we are assuming that if someone sets that on non-macos device then
|
|
174
|
+
// they know what they are doing
|
|
175
|
+
if (process.platform !== 'darwin') {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (enable === undefined) {
|
|
179
|
+
await (0, spawn_async_1.default)('git', ['config', '--unset', 'core.ignorecase']);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
await (0, spawn_async_1.default)('git', ['config', 'core.ignorecase', String(!enable)]);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import GitClient from './git';
|
|
2
|
+
export default class GitNoCommitClient extends GitClient {
|
|
3
|
+
isCommitRequiredAsync(): Promise<boolean>;
|
|
4
|
+
getRootPathAsync(): Promise<string>;
|
|
5
|
+
makeShallowCopyAsync(destinationPath: string): Promise<void>;
|
|
6
|
+
isFileIgnoredAsync(filePath: string): Promise<boolean>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const spawn_async_1 = (0, tslib_1.__importDefault)(require("@expo/spawn-async"));
|
|
5
|
+
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
6
|
+
const local_1 = require("../local");
|
|
7
|
+
const git_1 = (0, tslib_1.__importDefault)(require("./git"));
|
|
8
|
+
class GitNoCommitClient extends git_1.default {
|
|
9
|
+
async isCommitRequiredAsync() {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
async getRootPathAsync() {
|
|
13
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--show-toplevel'])).stdout.trim();
|
|
14
|
+
}
|
|
15
|
+
async makeShallowCopyAsync(destinationPath) {
|
|
16
|
+
// normalize converts C:/some/path to C:\some\path on windows
|
|
17
|
+
const srcPath = path_1.default.normalize(await this.getRootPathAsync());
|
|
18
|
+
await (0, local_1.makeShallowCopyAsync)(srcPath, destinationPath);
|
|
19
|
+
}
|
|
20
|
+
async isFileIgnoredAsync(filePath) {
|
|
21
|
+
// normalize converts C:/some/path to C:\some\path on windows
|
|
22
|
+
const ignore = new local_1.Ignore(await this.getRootPathAsync());
|
|
23
|
+
await ignore.initIgnoreAsync();
|
|
24
|
+
return ignore.ignores(filePath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = GitNoCommitClient;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const local_1 = require("../local");
|
|
4
|
+
const vcs_1 = require("../vcs");
|
|
5
|
+
class NoVcsClient extends vcs_1.Client {
|
|
6
|
+
async getRootPathAsync() {
|
|
7
|
+
return (0, local_1.getRootPath)();
|
|
8
|
+
}
|
|
9
|
+
async makeShallowCopyAsync(destinationPath) {
|
|
10
|
+
const srcPath = (0, local_1.getRootPath)();
|
|
11
|
+
await (0, local_1.makeShallowCopyAsync)(srcPath, destinationPath);
|
|
12
|
+
}
|
|
13
|
+
async isFileIgnoredAsync(filePath) {
|
|
14
|
+
const ignore = new local_1.Ignore((0, local_1.getRootPath)());
|
|
15
|
+
await ignore.initIgnoreAsync();
|
|
16
|
+
return ignore.ignores(filePath);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.default = NoVcsClient;
|
package/build/vcs/git.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
commitMessage: string;
|
|
6
|
-
commitAllFiles?: boolean;
|
|
7
|
-
}): Promise<void>;
|
|
8
|
-
hasUncommittedChangesAsync(): Promise<boolean>;
|
|
9
|
-
getRootPathAsync(): Promise<string>;
|
|
10
|
-
makeShallowCopyAsync(destinationPath: string): Promise<void>;
|
|
11
|
-
getCommitHashAsync(): Promise<string | undefined>;
|
|
12
|
-
trackFileAsync(file: string): Promise<void>;
|
|
13
|
-
getBranchNameAsync(): Promise<string | null>;
|
|
14
|
-
getLastCommitMessageAsync(): Promise<string | null>;
|
|
15
|
-
showDiffAsync(): Promise<void>;
|
|
16
|
-
isFileUntrackedAsync(path: string): Promise<boolean>;
|
|
17
|
-
isFileIgnoredAsync(filePath: string): Promise<boolean>;
|
|
1
|
+
export declare function isGitInstalledAsync(): Promise<boolean>;
|
|
2
|
+
export declare function doesGitRepoExistAsync(): Promise<boolean>;
|
|
3
|
+
interface GitStatusOptions {
|
|
4
|
+
showUntracked?: boolean;
|
|
18
5
|
}
|
|
6
|
+
export declare function gitStatusAsync({ showUntracked }?: GitStatusOptions): Promise<string>;
|
|
7
|
+
export declare function getGitDiffOutputAsync(): Promise<string>;
|
|
8
|
+
export declare function gitDiffAsync({ withPager, }?: {
|
|
9
|
+
withPager?: boolean;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export {};
|