eas-cli 0.30.0 → 0.32.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 +26 -26
- package/build/build/android/prepareJob.js +3 -3
- package/build/build/ios/prepareJob.js +3 -14
- package/build/build/utils/printBuildInfo.js +1 -1
- package/build/build/utils/updates.js +1 -1
- package/build/commands/branch/create.js +1 -4
- package/build/commands/branch/delete.js +1 -4
- package/build/commands/branch/list.js +1 -4
- package/build/commands/branch/publish.js +1 -4
- package/build/commands/branch/rename.js +1 -4
- package/build/commands/branch/view.js +1 -4
- package/build/commands/build/cancel.js +1 -2
- package/build/commands/build/configure.js +2 -2
- package/build/commands/build/index.js +3 -3
- package/build/commands/build/list.js +1 -2
- package/build/commands/build/view.js +1 -2
- package/build/commands/channel/create.js +1 -4
- package/build/commands/channel/edit.js +1 -4
- package/build/commands/channel/list.js +1 -4
- package/build/commands/channel/rollout.js +1 -4
- package/build/commands/channel/view.js +1 -4
- package/build/commands/config.js +1 -2
- package/build/commands/device/list.js +1 -2
- package/build/commands/device/view.js +1 -2
- package/build/commands/project/info.js +1 -4
- package/build/commands/project/init.js +1 -4
- package/build/commands/secret/create.js +1 -2
- package/build/commands/secret/delete.js +1 -2
- package/build/commands/secret/list.js +1 -2
- package/build/commands/submit.js +2 -5
- package/build/commands/webhook/create.js +1 -4
- package/build/commands/webhook/delete.js +1 -4
- package/build/commands/webhook/list.js +1 -4
- package/build/credentials/android/actions/SetupGoogleServiceAccountKey.js +3 -3
- package/build/credentials/android/credentials.d.ts +2 -0
- package/build/credentials/android/utils/googleServiceAccountKey.js +1 -0
- package/build/credentials/context.d.ts +1 -1
- package/build/credentials/context.js +5 -5
- package/build/credentials/errors.d.ts +3 -0
- package/build/credentials/errors.js +7 -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/DistributionCertificateUtils.js +5 -5
- package/build/credentials/ios/actions/SetupAdhocProvisioningProfile.d.ts +1 -0
- package/build/credentials/ios/actions/SetupAdhocProvisioningProfile.js +48 -4
- 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/ios/utils/printCredentials.js +12 -7
- package/build/devices/context.js +1 -1
- package/build/graphql/generated.d.ts +24 -1
- package/build/graphql/generated.js +2 -0
- package/build/log.d.ts +11 -1
- package/build/log.js +21 -10
- package/build/project/projectUtils.d.ts +4 -1
- package/build/project/projectUtils.js +13 -3
- package/build/submit/ArchiveSource.d.ts +7 -2
- package/build/submit/ArchiveSource.js +91 -8
- package/build/submit/android/AndroidSubmitCommand.js +3 -8
- package/build/submit/android/AndroidSubmitter.js +31 -9
- package/build/submit/android/ServiceAccountSource.d.ts +24 -5
- package/build/submit/android/ServiceAccountSource.js +54 -75
- package/build/submit/context.d.ts +4 -0
- package/build/submit/context.js +7 -1
- 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 +51 -3
- package/build/submit/ios/IosSubmitter.d.ts +3 -1
- package/build/submit/ios/IosSubmitter.js +48 -4
- 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/utils/json.js +2 -6
- package/oclif.manifest.json +1 -1
- package/package.json +8 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.provisioningProfileSchema = exports.pushKeySchema = exports.distributionCertificateSchema = exports.getAppLookupParams = void 0;
|
|
3
|
+
exports.provisioningProfileSchema = exports.pushKeySchema = exports.ascApiKeyMetadataSchema = exports.distributionCertificateSchema = exports.getAppLookupParams = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
|
|
6
6
|
const p12Certificate_1 = require("./utils/p12Certificate");
|
|
@@ -50,6 +50,21 @@ exports.distributionCertificateSchema = {
|
|
|
50
50
|
return answers;
|
|
51
51
|
},
|
|
52
52
|
};
|
|
53
|
+
exports.ascApiKeyMetadataSchema = {
|
|
54
|
+
name: 'App Store Connect API Key',
|
|
55
|
+
questions: [
|
|
56
|
+
{
|
|
57
|
+
field: 'keyId',
|
|
58
|
+
type: 'string',
|
|
59
|
+
question: 'Key ID:',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
field: 'issuerId',
|
|
63
|
+
type: 'string',
|
|
64
|
+
question: 'Issuer ID:',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
53
68
|
exports.pushKeySchema = {
|
|
54
69
|
name: 'Apple Push Notifications service key',
|
|
55
70
|
questions: [
|
|
@@ -99,10 +99,9 @@ function displayProjectCredentials(app, appBuildCredentials, targets) {
|
|
|
99
99
|
}, {});
|
|
100
100
|
const isMultitarget = targets.length > 1;
|
|
101
101
|
log_1.default.addNewLineIfNone();
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
];
|
|
102
|
+
log_1.default.log(chalk_1.default.cyan.bold('Project Credentials Configuration'));
|
|
103
|
+
log_1.default.newLine();
|
|
104
|
+
const fields = [{ label: 'Project', value: projectFullName }];
|
|
106
105
|
for (const [targetName, buildCredentials] of Object.entries(appBuildCredentials)) {
|
|
107
106
|
if (isMultitarget) {
|
|
108
107
|
fields.push({ label: '', value: '' });
|
|
@@ -115,10 +114,12 @@ function displayProjectCredentials(app, appBuildCredentials, targets) {
|
|
|
115
114
|
}
|
|
116
115
|
exports.displayProjectCredentials = displayProjectCredentials;
|
|
117
116
|
function displayIosAppBuildCredentials(buildCredentials, fields) {
|
|
117
|
+
fields.push({ label: '', value: '' });
|
|
118
118
|
fields.push({
|
|
119
119
|
label: `${prettyIosDistributionType(buildCredentials.iosDistributionType)} Configuration`,
|
|
120
120
|
value: '',
|
|
121
121
|
});
|
|
122
|
+
fields.push({ label: '', value: '' });
|
|
122
123
|
const maybeDistCert = buildCredentials.distributionCertificate;
|
|
123
124
|
fields.push({ label: 'Distribution Certificate', value: '' });
|
|
124
125
|
if (maybeDistCert) {
|
|
@@ -158,9 +159,13 @@ function displayIosAppBuildCredentials(buildCredentials, fields) {
|
|
|
158
159
|
});
|
|
159
160
|
}
|
|
160
161
|
if (appleDevices && appleDevices.length > 0) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
const [firstAppleDevice, ...rest] = appleDevices;
|
|
163
|
+
fields.push({
|
|
164
|
+
label: 'Provisioned devices',
|
|
165
|
+
value: `- ${formatAppleDevice(firstAppleDevice)}`,
|
|
166
|
+
});
|
|
167
|
+
for (const appleDevice of rest) {
|
|
168
|
+
fields.push({ label: '', value: `- ${formatAppleDevice(appleDevice)}` });
|
|
164
169
|
}
|
|
165
170
|
}
|
|
166
171
|
fields.push({ label: 'Updated', value: `${(0, date_1.fromNow)(new Date(updatedAt))} ago` });
|
package/build/devices/context.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.createContextAsync = void 0;
|
|
|
4
4
|
const config_1 = require("@expo/config");
|
|
5
5
|
const projectUtils_1 = require("../project/projectUtils");
|
|
6
6
|
async function createContextAsync({ appStore, cwd, user, }) {
|
|
7
|
-
const projectDir = await (0, projectUtils_1.findProjectRootAsync)(cwd);
|
|
7
|
+
const projectDir = await (0, projectUtils_1.findProjectRootAsync)({ cwd });
|
|
8
8
|
let exp = null;
|
|
9
9
|
if (projectDir) {
|
|
10
10
|
const config = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
|
|
@@ -312,12 +312,15 @@ export declare type Offer = {
|
|
|
312
312
|
trialLength?: Maybe<Scalars['Int']>;
|
|
313
313
|
type: OfferType;
|
|
314
314
|
features?: Maybe<Array<Maybe<Feature>>>;
|
|
315
|
+
prerequisite?: Maybe<OfferPrerequisite>;
|
|
315
316
|
};
|
|
316
317
|
export declare enum OfferType {
|
|
317
318
|
/** Term subscription */
|
|
318
319
|
Subscription = "SUBSCRIPTION",
|
|
319
320
|
/** Advanced Purchase of Paid Resource */
|
|
320
|
-
Prepaid = "PREPAID"
|
|
321
|
+
Prepaid = "PREPAID",
|
|
322
|
+
/** Addon, or supplementary subscription */
|
|
323
|
+
Addon = "ADDON"
|
|
321
324
|
}
|
|
322
325
|
export declare enum Feature {
|
|
323
326
|
/** Top Tier Support */
|
|
@@ -329,6 +332,11 @@ export declare enum Feature {
|
|
|
329
332
|
/** Funds support for open source development */
|
|
330
333
|
OpenSource = "OPEN_SOURCE"
|
|
331
334
|
}
|
|
335
|
+
export declare type OfferPrerequisite = {
|
|
336
|
+
__typename?: 'OfferPrerequisite';
|
|
337
|
+
type: Scalars['String'];
|
|
338
|
+
stripeIds: Array<Scalars['String']>;
|
|
339
|
+
};
|
|
332
340
|
export declare type Snack = Project & {
|
|
333
341
|
__typename?: 'Snack';
|
|
334
342
|
id: Scalars['ID'];
|
|
@@ -1206,6 +1214,7 @@ export declare type UserPermission = {
|
|
|
1206
1214
|
};
|
|
1207
1215
|
export declare type Billing = {
|
|
1208
1216
|
__typename?: 'Billing';
|
|
1217
|
+
id: Scalars['ID'];
|
|
1209
1218
|
payment?: Maybe<PaymentDetails>;
|
|
1210
1219
|
subscription?: Maybe<SubscriptionDetails>;
|
|
1211
1220
|
/** History of invoices */
|
|
@@ -1236,6 +1245,8 @@ export declare type Address = {
|
|
|
1236
1245
|
export declare type SubscriptionDetails = {
|
|
1237
1246
|
__typename?: 'SubscriptionDetails';
|
|
1238
1247
|
id: Scalars['ID'];
|
|
1248
|
+
planId?: Maybe<Scalars['String']>;
|
|
1249
|
+
addons: Array<AddonDetails>;
|
|
1239
1250
|
name?: Maybe<Scalars['String']>;
|
|
1240
1251
|
nextInvoice?: Maybe<Scalars['DateTime']>;
|
|
1241
1252
|
cancelledAt?: Maybe<Scalars['DateTime']>;
|
|
@@ -1244,6 +1255,12 @@ export declare type SubscriptionDetails = {
|
|
|
1244
1255
|
trialEnd?: Maybe<Scalars['DateTime']>;
|
|
1245
1256
|
status?: Maybe<Scalars['String']>;
|
|
1246
1257
|
};
|
|
1258
|
+
export declare type AddonDetails = {
|
|
1259
|
+
__typename?: 'AddonDetails';
|
|
1260
|
+
id: Scalars['ID'];
|
|
1261
|
+
planId: Scalars['String'];
|
|
1262
|
+
name: Scalars['String'];
|
|
1263
|
+
};
|
|
1247
1264
|
export declare type Charge = {
|
|
1248
1265
|
__typename?: 'Charge';
|
|
1249
1266
|
id: Scalars['ID'];
|
|
@@ -2473,10 +2490,16 @@ export declare type CreateIosSubmissionInput = {
|
|
|
2473
2490
|
export declare type IosSubmissionConfigInput = {
|
|
2474
2491
|
appleAppSpecificPasswordId?: Maybe<Scalars['String']>;
|
|
2475
2492
|
appleAppSpecificPassword?: Maybe<Scalars['String']>;
|
|
2493
|
+
ascApiKey?: Maybe<AscApiKeyInput>;
|
|
2476
2494
|
archiveUrl?: Maybe<Scalars['String']>;
|
|
2477
2495
|
appleIdUsername: Scalars['String'];
|
|
2478
2496
|
ascAppIdentifier: Scalars['String'];
|
|
2479
2497
|
};
|
|
2498
|
+
export declare type AscApiKeyInput = {
|
|
2499
|
+
keyP8: Scalars['String'];
|
|
2500
|
+
keyIdentifier: Scalars['String'];
|
|
2501
|
+
issuerIdentifier: Scalars['String'];
|
|
2502
|
+
};
|
|
2480
2503
|
export declare type CreateAndroidSubmissionInput = {
|
|
2481
2504
|
appId: Scalars['ID'];
|
|
2482
2505
|
config: AndroidSubmissionConfigInput;
|
|
@@ -13,6 +13,8 @@ var OfferType;
|
|
|
13
13
|
OfferType["Subscription"] = "SUBSCRIPTION";
|
|
14
14
|
/** Advanced Purchase of Paid Resource */
|
|
15
15
|
OfferType["Prepaid"] = "PREPAID";
|
|
16
|
+
/** Addon, or supplementary subscription */
|
|
17
|
+
OfferType["Addon"] = "ADDON";
|
|
16
18
|
})(OfferType = exports.OfferType || (exports.OfferType = {}));
|
|
17
19
|
var Feature;
|
|
18
20
|
(function (Feature) {
|
package/build/log.d.ts
CHANGED
|
@@ -18,10 +18,20 @@ export default class Log {
|
|
|
18
18
|
private static updateIsLastLineNewLine;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
+
* Prints a link for given URL, using text if provided, otherwise text is just the URL.
|
|
22
|
+
* Format links as dim (unless disabled) and with an underline.
|
|
23
|
+
*
|
|
24
|
+
* @example https://expo.dev
|
|
25
|
+
*/
|
|
26
|
+
export declare function link(url: string, { text, dim }?: {
|
|
27
|
+
text?: string;
|
|
28
|
+
dim?: boolean;
|
|
29
|
+
}): string;
|
|
30
|
+
/**
|
|
31
|
+
* Provide a consistent "Learn more" link experience.
|
|
21
32
|
* Format links as dim (unless disabled) with an underline.
|
|
22
33
|
*
|
|
23
34
|
* @example Learn more: https://expo.dev
|
|
24
|
-
* @param url
|
|
25
35
|
*/
|
|
26
36
|
export declare function learnMore(url: string, { learnMoreMessage: maybeLearnMoreMessage, dim, }?: {
|
|
27
37
|
learnMoreMessage?: string;
|
package/build/log.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.learnMore = void 0;
|
|
3
|
+
exports.learnMore = exports.link = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
6
6
|
const figures_1 = (0, tslib_1.__importDefault)(require("figures"));
|
|
@@ -79,19 +79,30 @@ exports.default = Log;
|
|
|
79
79
|
Log.isDebug = (0, getenv_1.boolish)('EXPO_DEBUG', false);
|
|
80
80
|
Log.isLastLineNewLine = false;
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
82
|
+
* Prints a link for given URL, using text if provided, otherwise text is just the URL.
|
|
83
|
+
* Format links as dim (unless disabled) and with an underline.
|
|
83
84
|
*
|
|
84
|
-
* @example
|
|
85
|
-
* @param url
|
|
85
|
+
* @example https://expo.dev
|
|
86
86
|
*/
|
|
87
|
-
function
|
|
87
|
+
function link(url, { text = url, dim = true } = {}) {
|
|
88
|
+
let output;
|
|
88
89
|
// Links can be disabled via env variables https://github.com/jamestalmage/supports-hyperlinks/blob/master/index.js
|
|
89
90
|
if (terminal_link_1.default.isSupported) {
|
|
90
|
-
|
|
91
|
-
return dim ? chalk_1.default.dim(text) : text;
|
|
91
|
+
output = (0, terminal_link_1.default)(text, url);
|
|
92
92
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
else {
|
|
94
|
+
output = `${text === url ? '' : text + ': '}${chalk_1.default.underline(url)}`;
|
|
95
|
+
}
|
|
96
|
+
return dim ? chalk_1.default.dim(output) : output;
|
|
97
|
+
}
|
|
98
|
+
exports.link = link;
|
|
99
|
+
/**
|
|
100
|
+
* Provide a consistent "Learn more" link experience.
|
|
101
|
+
* Format links as dim (unless disabled) with an underline.
|
|
102
|
+
*
|
|
103
|
+
* @example Learn more: https://expo.dev
|
|
104
|
+
*/
|
|
105
|
+
function learnMore(url, { learnMoreMessage: maybeLearnMoreMessage, dim = true, } = {}) {
|
|
106
|
+
return link(url, { text: maybeLearnMoreMessage !== null && maybeLearnMoreMessage !== void 0 ? maybeLearnMoreMessage : 'Learn more', dim });
|
|
96
107
|
}
|
|
97
108
|
exports.learnMore = learnMore;
|
|
@@ -5,7 +5,10 @@ import { Actor } from '../user/User';
|
|
|
5
5
|
export declare function getProjectAccountName(exp: ExpoConfig, user: Actor): string;
|
|
6
6
|
export declare function getUsername(exp: ExpoConfig, user: Actor): string | undefined;
|
|
7
7
|
export declare function getProjectAccountNameAsync(exp: ExpoConfig): Promise<string>;
|
|
8
|
-
export declare function findProjectRootAsync(cwd
|
|
8
|
+
export declare function findProjectRootAsync({ cwd, defaultToProcessCwd, }?: {
|
|
9
|
+
cwd?: string;
|
|
10
|
+
defaultToProcessCwd?: boolean;
|
|
11
|
+
}): Promise<string>;
|
|
9
12
|
export declare function setProjectIdAsync(projectDir: string, options?: {
|
|
10
13
|
env?: Env;
|
|
11
14
|
}): Promise<ExpoConfig | undefined>;
|
|
@@ -45,9 +45,19 @@ async function getProjectAccountNameAsync(exp) {
|
|
|
45
45
|
return getProjectAccountName(exp, user);
|
|
46
46
|
}
|
|
47
47
|
exports.getProjectAccountNameAsync = getProjectAccountNameAsync;
|
|
48
|
-
async function findProjectRootAsync(cwd) {
|
|
48
|
+
async function findProjectRootAsync({ cwd, defaultToProcessCwd = false, } = {}) {
|
|
49
49
|
const projectRootDir = await (0, pkg_dir_1.default)(cwd);
|
|
50
|
-
|
|
50
|
+
if (!projectRootDir) {
|
|
51
|
+
if (!defaultToProcessCwd) {
|
|
52
|
+
throw new Error('Please run this command inside a project directory.');
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
return process.cwd();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return projectRootDir;
|
|
60
|
+
}
|
|
51
61
|
}
|
|
52
62
|
exports.findProjectRootAsync = findProjectRootAsync;
|
|
53
63
|
async function setProjectIdAsync(projectDir, options = {}) {
|
|
@@ -106,7 +116,7 @@ async function getProjectIdAsync(exp, options = {}) {
|
|
|
106
116
|
return localProjectId;
|
|
107
117
|
}
|
|
108
118
|
// Set the project ID if it is missing.
|
|
109
|
-
const projectDir = await findProjectRootAsync(
|
|
119
|
+
const projectDir = await findProjectRootAsync();
|
|
110
120
|
if (!projectDir) {
|
|
111
121
|
throw new Error('Please run this command inside a project directory.');
|
|
112
122
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Platform } from '@expo/eas-build-job';
|
|
2
2
|
import { BuildFragment } from '../graphql/generated';
|
|
3
|
+
export declare const BUILD_LIST_ITEM_COUNT = 4;
|
|
3
4
|
export declare enum ArchiveSourceType {
|
|
4
5
|
url = 0,
|
|
5
6
|
latest = 1,
|
|
6
7
|
path = 2,
|
|
7
8
|
buildId = 3,
|
|
8
|
-
|
|
9
|
+
buildList = 4,
|
|
10
|
+
prompt = 5
|
|
9
11
|
}
|
|
10
12
|
interface ArchiveSourceBase {
|
|
11
13
|
sourceType: ArchiveSourceType;
|
|
@@ -28,6 +30,9 @@ interface ArchiveBuildIdSource extends ArchiveSourceBase {
|
|
|
28
30
|
sourceType: ArchiveSourceType.buildId;
|
|
29
31
|
id: string;
|
|
30
32
|
}
|
|
33
|
+
interface ArchiveBuildListSource extends ArchiveSourceBase {
|
|
34
|
+
sourceType: ArchiveSourceType.buildList;
|
|
35
|
+
}
|
|
31
36
|
interface ArchivePromptSource extends ArchiveSourceBase {
|
|
32
37
|
sourceType: ArchiveSourceType.prompt;
|
|
33
38
|
}
|
|
@@ -36,7 +41,7 @@ export interface Archive {
|
|
|
36
41
|
source: ArchiveSource;
|
|
37
42
|
url?: string;
|
|
38
43
|
}
|
|
39
|
-
export declare type ArchiveSource = ArchiveUrlSource | ArchiveLatestSource | ArchivePathSource | ArchiveBuildIdSource | ArchivePromptSource;
|
|
44
|
+
export declare type ArchiveSource = ArchiveUrlSource | ArchiveLatestSource | ArchivePathSource | ArchiveBuildIdSource | ArchiveBuildListSource | ArchivePromptSource;
|
|
40
45
|
export declare function getArchiveAsync(source: ArchiveSource): Promise<Archive>;
|
|
41
46
|
export declare function isUuidV4(s: string): boolean;
|
|
42
47
|
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isUuidV4 = exports.getArchiveAsync = exports.ArchiveSourceType = void 0;
|
|
3
|
+
exports.isUuidV4 = exports.getArchiveAsync = exports.ArchiveSourceType = exports.BUILD_LIST_ITEM_COUNT = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
6
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
7
7
|
const url_1 = require("url");
|
|
8
8
|
const uuid = (0, tslib_1.__importStar)(require("uuid"));
|
|
9
|
+
const generated_1 = require("../graphql/generated");
|
|
9
10
|
const BuildQuery_1 = require("../graphql/queries/BuildQuery");
|
|
10
11
|
const AppPlatform_1 = require("../graphql/types/AppPlatform");
|
|
11
12
|
const log_1 = (0, tslib_1.__importStar)(require("../log"));
|
|
@@ -13,13 +14,15 @@ const platform_1 = require("../platform");
|
|
|
13
14
|
const prompts_1 = require("../prompts");
|
|
14
15
|
const builds_1 = require("./utils/builds");
|
|
15
16
|
const files_1 = require("./utils/files");
|
|
17
|
+
exports.BUILD_LIST_ITEM_COUNT = 4;
|
|
16
18
|
var ArchiveSourceType;
|
|
17
19
|
(function (ArchiveSourceType) {
|
|
18
20
|
ArchiveSourceType[ArchiveSourceType["url"] = 0] = "url";
|
|
19
21
|
ArchiveSourceType[ArchiveSourceType["latest"] = 1] = "latest";
|
|
20
22
|
ArchiveSourceType[ArchiveSourceType["path"] = 2] = "path";
|
|
21
23
|
ArchiveSourceType[ArchiveSourceType["buildId"] = 3] = "buildId";
|
|
22
|
-
ArchiveSourceType[ArchiveSourceType["
|
|
24
|
+
ArchiveSourceType[ArchiveSourceType["buildList"] = 4] = "buildList";
|
|
25
|
+
ArchiveSourceType[ArchiveSourceType["prompt"] = 5] = "prompt";
|
|
23
26
|
})(ArchiveSourceType = exports.ArchiveSourceType || (exports.ArchiveSourceType = {}));
|
|
24
27
|
async function getArchiveAsync(source) {
|
|
25
28
|
switch (source.sourceType) {
|
|
@@ -38,6 +41,9 @@ async function getArchiveAsync(source) {
|
|
|
38
41
|
case ArchiveSourceType.buildId: {
|
|
39
42
|
return await handleBuildIdSourceAsync(source);
|
|
40
43
|
}
|
|
44
|
+
case ArchiveSourceType.buildList: {
|
|
45
|
+
return await handleBuildListSourceAsync(source);
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
exports.getArchiveAsync = getArchiveAsync;
|
|
@@ -67,7 +73,7 @@ async function handleUrlSourceAsync(source) {
|
|
|
67
73
|
}
|
|
68
74
|
async function handleLatestSourceAsync(source) {
|
|
69
75
|
try {
|
|
70
|
-
const latestBuild = await (0, builds_1.
|
|
76
|
+
const [latestBuild] = await (0, builds_1.getRecentBuildsForSubmissionAsync)((0, AppPlatform_1.toAppPlatform)(source.platform), source.projectId);
|
|
71
77
|
if (!latestBuild) {
|
|
72
78
|
log_1.default.error(chalk_1.default.bold("Couldn't find any builds for this project on EAS servers. It looks like you haven't run 'eas build' yet."));
|
|
73
79
|
return getArchiveAsync({
|
|
@@ -128,6 +134,83 @@ async function handleBuildIdSourceAsync(source) {
|
|
|
128
134
|
});
|
|
129
135
|
}
|
|
130
136
|
}
|
|
137
|
+
async function handleBuildListSourceAsync(source) {
|
|
138
|
+
try {
|
|
139
|
+
const appPlatform = (0, AppPlatform_1.toAppPlatform)(source.platform);
|
|
140
|
+
const expiryDate = new Date(); // artifacts expire after 30 days
|
|
141
|
+
expiryDate.setDate(expiryDate.getDate() - 30);
|
|
142
|
+
const recentBuilds = await (0, builds_1.getRecentBuildsForSubmissionAsync)(appPlatform, source.projectId, {
|
|
143
|
+
limit: exports.BUILD_LIST_ITEM_COUNT,
|
|
144
|
+
});
|
|
145
|
+
if (recentBuilds.length < 1) {
|
|
146
|
+
log_1.default.error(chalk_1.default.bold(`Couldn't find any ${platform_1.appPlatformDisplayNames[appPlatform]} builds for this project on EAS servers. ` +
|
|
147
|
+
"It looks like you haven't run 'eas build' yet."));
|
|
148
|
+
return getArchiveAsync({
|
|
149
|
+
...source,
|
|
150
|
+
sourceType: ArchiveSourceType.prompt,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (recentBuilds.every(it => new Date(it.updatedAt) < expiryDate)) {
|
|
154
|
+
log_1.default.error(chalk_1.default.bold('It looks like all of your build artifacts have expired. ' +
|
|
155
|
+
'EAS keeps your build artifacts only for 30 days.'));
|
|
156
|
+
return getArchiveAsync({
|
|
157
|
+
...source,
|
|
158
|
+
sourceType: ArchiveSourceType.prompt,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const choices = recentBuilds.map(build => formatBuildChoice(build, expiryDate));
|
|
162
|
+
choices.push({
|
|
163
|
+
title: 'None of the above (select another option)',
|
|
164
|
+
value: null,
|
|
165
|
+
});
|
|
166
|
+
const { selectedBuild } = await (0, prompts_1.promptAsync)({
|
|
167
|
+
name: 'selectedBuild',
|
|
168
|
+
type: 'select',
|
|
169
|
+
message: 'Which build would you like to submit?',
|
|
170
|
+
choices: choices.map(choice => ({ ...choice, title: `- ${choice.title}` })),
|
|
171
|
+
// @ts-expect-error field documented in npm, but not defined in typescript
|
|
172
|
+
warn: 'This artifact has expired',
|
|
173
|
+
});
|
|
174
|
+
if (selectedBuild == null) {
|
|
175
|
+
return getArchiveAsync({
|
|
176
|
+
...source,
|
|
177
|
+
sourceType: ArchiveSourceType.prompt,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
build: selectedBuild,
|
|
182
|
+
source,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
log_1.default.error(err);
|
|
187
|
+
throw err;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function formatBuildChoice(build, expiryDate) {
|
|
191
|
+
const { id, platform, updatedAt, appVersion, sdkVersion, runtimeVersion, buildProfile, appBuildVersion, releaseChannel, } = build;
|
|
192
|
+
const formatValue = (field) => field ? chalk_1.default.bold(field) : chalk_1.default.dim('Unknown');
|
|
193
|
+
const buildDate = new Date(updatedAt);
|
|
194
|
+
const maybeRuntimeVersion = runtimeVersion ? `Runtime: ${formatValue(runtimeVersion)}` : null;
|
|
195
|
+
const maybeSdkVersion = sdkVersion ? `SDK: ${formatValue(sdkVersion)}` : null;
|
|
196
|
+
const appBuildVersionString = `${platform === generated_1.AppPlatform.Android ? 'Version code' : 'Build number'}: ${formatValue(appBuildVersion)}`;
|
|
197
|
+
const title = [
|
|
198
|
+
`ID: ${chalk_1.default.dim(id)}, Finished at: ${chalk_1.default.bold(buildDate.toLocaleString())}`,
|
|
199
|
+
[
|
|
200
|
+
`\tApp version: ${formatValue(appVersion)}, ${appBuildVersionString}`,
|
|
201
|
+
maybeRuntimeVersion,
|
|
202
|
+
maybeSdkVersion,
|
|
203
|
+
]
|
|
204
|
+
.filter(it => it != null)
|
|
205
|
+
.join(', '),
|
|
206
|
+
`\tProfile: ${formatValue(buildProfile)}, Release channel: ${formatValue(releaseChannel)}`,
|
|
207
|
+
].join('\n');
|
|
208
|
+
return {
|
|
209
|
+
title,
|
|
210
|
+
value: build,
|
|
211
|
+
disabled: buildDate < expiryDate,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
131
214
|
async function handlePromptSourceAsync(source) {
|
|
132
215
|
const { sourceType: sourceTypeRaw } = await (0, prompts_1.promptAsync)({
|
|
133
216
|
name: 'sourceType',
|
|
@@ -135,8 +218,8 @@ async function handlePromptSourceAsync(source) {
|
|
|
135
218
|
message: 'What would you like to submit?',
|
|
136
219
|
choices: [
|
|
137
220
|
{
|
|
138
|
-
title: '
|
|
139
|
-
value: ArchiveSourceType.
|
|
221
|
+
title: 'Selected build from EAS',
|
|
222
|
+
value: ArchiveSourceType.buildList,
|
|
140
223
|
},
|
|
141
224
|
{ title: 'I have a url to the app archive', value: ArchiveSourceType.url },
|
|
142
225
|
{
|
|
@@ -167,10 +250,10 @@ async function handlePromptSourceAsync(source) {
|
|
|
167
250
|
path,
|
|
168
251
|
});
|
|
169
252
|
}
|
|
170
|
-
case ArchiveSourceType.
|
|
253
|
+
case ArchiveSourceType.buildList: {
|
|
171
254
|
return getArchiveAsync({
|
|
172
255
|
...source,
|
|
173
|
-
sourceType: ArchiveSourceType.
|
|
256
|
+
sourceType: ArchiveSourceType.buildList,
|
|
174
257
|
});
|
|
175
258
|
}
|
|
176
259
|
case ArchiveSourceType.buildId: {
|
|
@@ -181,7 +264,7 @@ async function handlePromptSourceAsync(source) {
|
|
|
181
264
|
id,
|
|
182
265
|
});
|
|
183
266
|
}
|
|
184
|
-
|
|
267
|
+
default:
|
|
185
268
|
throw new Error('This should never happen');
|
|
186
269
|
}
|
|
187
270
|
}
|
|
@@ -120,14 +120,9 @@ class AndroidSubmitCommand {
|
|
|
120
120
|
path: serviceAccountKeyPath,
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
return (0, results_1.result)({
|
|
128
|
-
sourceType: ServiceAccountSource_1.ServiceAccountSourceType.detect,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
123
|
+
return (0, results_1.result)({
|
|
124
|
+
sourceType: ServiceAccountSource_1.ServiceAccountSourceType.credentialsService,
|
|
125
|
+
});
|
|
131
126
|
}
|
|
132
127
|
}
|
|
133
128
|
exports.default = AndroidSubmitCommand;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
4
|
+
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
5
5
|
const SubmissionMutation_1 = require("../../graphql/mutations/SubmissionMutation");
|
|
6
|
+
const formatFields_1 = (0, tslib_1.__importDefault)(require("../../utils/formatFields"));
|
|
6
7
|
const ArchiveSource_1 = require("../ArchiveSource");
|
|
7
8
|
const BaseSubmitter_1 = (0, tslib_1.__importDefault)(require("../BaseSubmitter"));
|
|
8
9
|
const summary_1 = require("../utils/summary");
|
|
@@ -30,15 +31,14 @@ class AndroidSubmitter extends BaseSubmitter_1.default {
|
|
|
30
31
|
async resolveSourceOptionsAsync() {
|
|
31
32
|
const androidPackage = await (0, AndroidPackageSource_1.getAndroidPackageAsync)(this.options.androidPackageSource);
|
|
32
33
|
const archive = await (0, ArchiveSource_1.getArchiveAsync)(this.options.archiveSource);
|
|
33
|
-
const
|
|
34
|
+
const serviceAccountKeyResult = await (0, ServiceAccountSource_1.getServiceAccountKeyResultAsync)(this.ctx, this.options.serviceAccountSource, androidPackage);
|
|
34
35
|
return {
|
|
35
36
|
androidPackage,
|
|
36
37
|
archive,
|
|
37
|
-
|
|
38
|
+
serviceAccountKeyResult,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
async formatSubmissionConfigAsync(options, { archive, androidPackage,
|
|
41
|
-
const serviceAccount = await fs_extra_1.default.readFile(serviceAccountPath, 'utf-8');
|
|
41
|
+
async formatSubmissionConfigAsync(options, { archive, androidPackage, serviceAccountKeyResult }) {
|
|
42
42
|
const { track, releaseStatus, changesNotSentForReview } = options;
|
|
43
43
|
return {
|
|
44
44
|
applicationIdentifier: androidPackage,
|
|
@@ -46,10 +46,10 @@ class AndroidSubmitter extends BaseSubmitter_1.default {
|
|
|
46
46
|
track,
|
|
47
47
|
changesNotSentForReview,
|
|
48
48
|
releaseStatus,
|
|
49
|
-
|
|
49
|
+
...serviceAccountKeyResult.result,
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
prepareSummaryData(options, { archive, androidPackage,
|
|
52
|
+
prepareSummaryData(options, { archive, androidPackage, serviceAccountKeyResult }) {
|
|
53
53
|
const { projectId, track, releaseStatus, changesNotSentForReview } = options;
|
|
54
54
|
// structuring order affects table rows order
|
|
55
55
|
return {
|
|
@@ -58,7 +58,7 @@ class AndroidSubmitter extends BaseSubmitter_1.default {
|
|
|
58
58
|
track,
|
|
59
59
|
changesNotSentForReview: changesNotSentForReview !== null && changesNotSentForReview !== void 0 ? changesNotSentForReview : undefined,
|
|
60
60
|
releaseStatus: releaseStatus !== null && releaseStatus !== void 0 ? releaseStatus : undefined,
|
|
61
|
-
|
|
61
|
+
formattedServiceAccount: formatServiceAccountSummary(serviceAccountKeyResult),
|
|
62
62
|
...(0, summary_1.formatArchiveSourceSummary)(archive),
|
|
63
63
|
};
|
|
64
64
|
}
|
|
@@ -70,8 +70,30 @@ const SummaryHumanReadableKeys = {
|
|
|
70
70
|
archiveUrl: 'Download URL',
|
|
71
71
|
changesNotSentForReview: 'Changes not sent for a review',
|
|
72
72
|
formattedBuild: 'Build',
|
|
73
|
+
formattedServiceAccount: 'Google Service Account Key',
|
|
73
74
|
projectId: 'Project ID',
|
|
74
75
|
releaseStatus: 'Release status',
|
|
75
|
-
serviceAccountPath: 'Google Service Key',
|
|
76
76
|
track: 'Release track',
|
|
77
77
|
};
|
|
78
|
+
function formatServiceAccountSummary({ summary }) {
|
|
79
|
+
const { email: serviceAccountEmail, path: serviceAccountKeyPath, source: serviceAccountKeySource, } = summary;
|
|
80
|
+
const fields = [
|
|
81
|
+
{
|
|
82
|
+
label: 'Key Source',
|
|
83
|
+
value: serviceAccountKeySource,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: 'Key Path',
|
|
87
|
+
value: serviceAccountKeyPath,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
label: 'Account E-mail',
|
|
91
|
+
value: serviceAccountEmail,
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
const filteredFields = fields.filter(({ value }) => value !== undefined && value !== null);
|
|
95
|
+
return ('\n' +
|
|
96
|
+
(0, formatFields_1.default)(filteredFields, {
|
|
97
|
+
labelFormat: label => ` ${chalk_1.default.dim(label)}:`,
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { Platform } from '@expo/eas-build-job';
|
|
2
|
+
import { SubmissionContext } from '../context';
|
|
1
3
|
export declare enum ServiceAccountSourceType {
|
|
2
4
|
path = 0,
|
|
3
5
|
prompt = 1,
|
|
4
|
-
|
|
6
|
+
credentialsService = 2
|
|
5
7
|
}
|
|
6
8
|
interface ServiceAccountSourceBase {
|
|
7
9
|
sourceType: ServiceAccountSourceType;
|
|
@@ -13,9 +15,26 @@ interface ServiceAccountPathSource extends ServiceAccountSourceBase {
|
|
|
13
15
|
interface ServiceAccountPromptSource extends ServiceAccountSourceBase {
|
|
14
16
|
sourceType: ServiceAccountSourceType.prompt;
|
|
15
17
|
}
|
|
16
|
-
interface
|
|
17
|
-
sourceType: ServiceAccountSourceType.
|
|
18
|
+
export interface ServiceAccountCredentialsServiceSource extends ServiceAccountSourceBase {
|
|
19
|
+
sourceType: ServiceAccountSourceType.credentialsService;
|
|
18
20
|
}
|
|
19
|
-
export declare type
|
|
20
|
-
|
|
21
|
+
export declare type ServiceAccountKeyResult = {
|
|
22
|
+
result: ServiceAccountKeyFile | ServiceAccountKeyFromExpoServers;
|
|
23
|
+
summary: ServiceAccountKeySummary;
|
|
24
|
+
};
|
|
25
|
+
declare type ServiceAccountKeySummary = {
|
|
26
|
+
source: 'local' | 'EAS servers';
|
|
27
|
+
path?: string;
|
|
28
|
+
email: string;
|
|
29
|
+
};
|
|
30
|
+
declare type ServiceAccountKeyFile = {
|
|
31
|
+
googleServiceAccountKeyJson: string;
|
|
32
|
+
};
|
|
33
|
+
declare type ServiceAccountKeyFromExpoServers = {
|
|
34
|
+
googleServiceAccountKeyId: string;
|
|
35
|
+
};
|
|
36
|
+
export declare type ServiceAccountSource = ServiceAccountPathSource | ServiceAccountPromptSource | ServiceAccountCredentialsServiceSource;
|
|
37
|
+
export declare function getServiceAccountKeyResultAsync(ctx: SubmissionContext<Platform.ANDROID>, source: ServiceAccountSource, androidApplicationIdentifier: string): Promise<ServiceAccountKeyResult>;
|
|
38
|
+
export declare function getServiceAccountKeyPathAsync(source: ServiceAccountSource): Promise<string>;
|
|
39
|
+
export declare function getServiceAccountFromCredentialsServiceAsync(ctx: SubmissionContext<Platform.ANDROID>, androidApplicationIdentifier: string): Promise<ServiceAccountKeyResult>;
|
|
21
40
|
export {};
|