eas-cli 0.55.1 → 0.58.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 +58 -49
- package/build/branch/queries.d.ts +5 -0
- package/build/branch/queries.js +87 -0
- package/build/build/android/build.js +17 -3
- package/build/build/android/graphql.js +2 -0
- package/build/build/android/prepareJob.js +5 -0
- package/build/build/android/syncProjectConfiguration.d.ts +3 -4
- package/build/build/android/syncProjectConfiguration.js +2 -3
- package/build/build/android/version.d.ts +16 -0
- package/build/build/android/version.js +86 -9
- package/build/build/build.js +8 -3
- package/build/build/context.d.ts +7 -3
- package/build/build/createContext.d.ts +5 -2
- package/build/build/createContext.js +9 -1
- package/build/build/ios/build.js +18 -17
- package/build/build/ios/graphql.js +2 -0
- package/build/build/ios/prepareJob.js +5 -0
- package/build/build/ios/syncProjectConfiguration.d.ts +5 -6
- package/build/build/ios/syncProjectConfiguration.js +3 -4
- package/build/build/ios/version.d.ts +23 -3
- package/build/build/ios/version.js +128 -28
- package/build/build/local.d.ts +2 -2
- package/build/build/local.js +7 -7
- package/build/build/metadata.d.ts +1 -0
- package/build/build/metadata.js +32 -6
- package/build/build/runBuildAndSubmit.d.ts +1 -0
- package/build/build/runBuildAndSubmit.js +29 -7
- package/build/build/utils/printBuildInfo.d.ts +1 -1
- package/build/build/utils/printBuildInfo.js +7 -13
- package/build/commandUtils/pagination.d.ts +13 -0
- package/build/commandUtils/pagination.js +42 -0
- package/build/commands/branch/list.d.ts +3 -4
- package/build/commands/branch/list.js +6 -69
- package/build/commands/branch/view.d.ts +3 -0
- package/build/commands/branch/view.js +15 -63
- package/build/commands/build/index.d.ts +1 -0
- package/build/commands/build/index.js +9 -0
- package/build/commands/build/version/set.d.ts +9 -0
- package/build/commands/build/version/set.js +81 -0
- package/build/commands/build/version/sync.d.ts +11 -0
- package/build/commands/build/version/sync.js +123 -0
- package/build/commands/submit.js +4 -1
- package/build/commands/update/index.d.ts +2 -2
- package/build/commands/update/index.js +24 -6
- package/build/commands/update/list.js +13 -18
- package/build/credentials/ios/actions/SetUpAdhocProvisioningProfile.js +2 -2
- package/build/credentials/ios/types.d.ts +2 -0
- package/build/devices/actions/create/action.d.ts +5 -2
- package/build/devices/actions/create/action.js +12 -2
- package/build/devices/actions/create/developerPortalMethod.d.ts +6 -0
- package/build/devices/actions/create/developerPortalMethod.js +90 -0
- package/build/devices/manager.js +4 -4
- package/build/graphql/generated.d.ts +501 -59
- package/build/graphql/generated.js +10 -1
- package/build/graphql/mutations/AppVersionMutation.d.ts +11 -0
- package/build/graphql/mutations/AppVersionMutation.js +28 -0
- package/build/graphql/mutations/PublishMutation.d.ts +2 -4
- package/build/graphql/queries/AppVersionQuery.d.ts +4 -0
- package/build/graphql/queries/AppVersionQuery.js +37 -0
- package/build/graphql/queries/BranchQuery.d.ts +2 -1
- package/build/graphql/queries/BranchQuery.js +26 -0
- package/build/graphql/queries/BuildQuery.d.ts +4 -1
- package/build/graphql/queries/BuildQuery.js +19 -0
- package/build/graphql/queries/PublishQuery.d.ts +2 -1
- package/build/graphql/queries/PublishQuery.js +16 -0
- package/build/graphql/queries/UpdateQuery.d.ts +6 -8
- package/build/graphql/queries/UpdateQuery.js +27 -23
- package/build/graphql/types/Build.d.ts +1 -0
- package/build/graphql/types/Build.js +16 -1
- package/build/metadata/apple/config/reader.d.ts +3 -2
- package/build/metadata/apple/config/reader.js +22 -5
- package/build/metadata/apple/config/writer.d.ts +3 -2
- package/build/metadata/apple/config/writer.js +22 -6
- package/build/metadata/apple/tasks/app-version.d.ts +5 -1
- package/build/metadata/apple/tasks/app-version.js +109 -8
- package/build/metadata/apple/tasks/index.d.ts +6 -1
- package/build/metadata/apple/tasks/index.js +7 -2
- package/build/metadata/apple/types.d.ts +3 -7
- package/build/metadata/upload.js +6 -1
- package/build/platform.d.ts +1 -0
- package/build/platform.js +17 -1
- package/build/project/android/applicationId.js +2 -2
- package/build/project/android/versions.d.ts +3 -0
- package/build/project/android/versions.js +23 -0
- package/build/project/applicationIdentifier.d.ts +4 -0
- package/build/project/applicationIdentifier.js +37 -0
- package/build/project/ios/bundleIdentifier.js +2 -2
- package/build/project/ios/target.js +14 -1
- package/build/project/ios/versions.d.ts +3 -0
- package/build/project/ios/versions.js +17 -0
- package/build/project/publish.d.ts +3 -2
- package/build/project/publish.js +23 -18
- package/build/project/remoteVersionSource.d.ts +8 -0
- package/build/project/remoteVersionSource.js +61 -0
- package/build/submit/submit.d.ts +2 -1
- package/build/submit/submit.js +3 -2
- package/build/submit/utils/files.d.ts +0 -6
- package/build/submit/utils/files.js +3 -16
- package/build/update/queries.d.ts +3 -0
- package/build/update/queries.js +72 -0
- package/build/update/utils.d.ts +14 -0
- package/build/update/utils.js +26 -9
- package/build/uploads.d.ts +8 -2
- package/build/uploads.js +19 -4
- package/build/utils/expodash/chunk.d.ts +1 -0
- package/build/utils/expodash/chunk.js +16 -0
- package/build/utils/queries.d.ts +25 -0
- package/build/utils/queries.js +67 -0
- package/build/vcs/clients/gitNoCommit.d.ts +1 -0
- package/build/vcs/clients/gitNoCommit.js +14 -0
- package/oclif.manifest.json +1 -1
- package/package.json +10 -5
- package/schema/metadata-0.json +38 -233
|
@@ -11,12 +11,13 @@ const retry_1 = require("../../utils/retry");
|
|
|
11
11
|
const task_1 = require("../task");
|
|
12
12
|
class AppVersionTask extends task_1.AppleTask {
|
|
13
13
|
constructor(options = {}) {
|
|
14
|
-
var _a, _b;
|
|
14
|
+
var _a, _b, _c;
|
|
15
15
|
super();
|
|
16
16
|
this.name = () => (this.options.editLive ? 'live app version' : 'editable app version');
|
|
17
17
|
this.options = {
|
|
18
18
|
platform: (_a = options.platform) !== null && _a !== void 0 ? _a : apple_utils_1.Platform.IOS,
|
|
19
19
|
editLive: (_b = options.editLive) !== null && _b !== void 0 ? _b : false,
|
|
20
|
+
version: (_c = options.version) !== null && _c !== void 0 ? _c : null,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
async prepareAsync({ context }) {
|
|
@@ -26,24 +27,39 @@ class AppVersionTask extends task_1.AppleTask {
|
|
|
26
27
|
context.versionIsFirst = versionIsFirst;
|
|
27
28
|
context.versionIsLive = versionIsLive;
|
|
28
29
|
context.versionLocales = await version.getLocalizationsAsync();
|
|
30
|
+
context.versionPhasedRelease = await version.getPhasedReleaseAsync();
|
|
29
31
|
}
|
|
30
32
|
async downloadAsync({ config, context }) {
|
|
33
|
+
var _a;
|
|
31
34
|
(0, assert_1.default)(context.version, `App version not initialized, can't download version`);
|
|
32
35
|
config.setVersion(context.version.attributes);
|
|
33
|
-
config.
|
|
36
|
+
config.setVersionReleaseType(context.version.attributes);
|
|
37
|
+
config.setVersionReleasePhased((_a = context.versionPhasedRelease) === null || _a === void 0 ? void 0 : _a.attributes);
|
|
34
38
|
for (const locale of context.versionLocales) {
|
|
35
39
|
config.setVersionLocale(locale.attributes);
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
async uploadAsync({ config, context }) {
|
|
39
|
-
(0, assert_1.default)(context.version, `App version not initialized, can't update version`);
|
|
40
43
|
const version = config.getVersion();
|
|
41
|
-
|
|
44
|
+
if (!context.version && (version === null || version === void 0 ? void 0 : version.versionString)) {
|
|
45
|
+
context.version = await (0, log_2.logAsync)(() => {
|
|
46
|
+
return context.app.createVersionAsync({
|
|
47
|
+
versionString: version.versionString,
|
|
48
|
+
platform: this.options.platform,
|
|
49
|
+
});
|
|
50
|
+
}, {
|
|
51
|
+
pending: `Creating new version ${chalk_1.default.bold(version.versionString)}...`,
|
|
52
|
+
success: `Created new version ${chalk_1.default.bold(version.versionString)}`,
|
|
53
|
+
failure: `Failed creating new version ${chalk_1.default.bold(version.versionString)}`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
(0, assert_1.default)(context.version, `App version not initialized, can't update version`);
|
|
57
|
+
const { versionString } = context.version.attributes;
|
|
58
|
+
const release = config.getVersionReleaseType();
|
|
42
59
|
if (!version && !release) {
|
|
43
60
|
log_1.default.log((0, chalk_1.default) `{dim - Skipped version and release update, not configured}`);
|
|
44
61
|
}
|
|
45
62
|
else {
|
|
46
|
-
const { versionString } = context.version.attributes;
|
|
47
63
|
const description = [version && 'version', release && 'release']
|
|
48
64
|
.filter(Boolean)
|
|
49
65
|
.join(' and ');
|
|
@@ -53,6 +69,24 @@ class AppVersionTask extends task_1.AppleTask {
|
|
|
53
69
|
failure: `Failed updating ${description} info for ${chalk_1.default.bold(versionString)}`,
|
|
54
70
|
});
|
|
55
71
|
}
|
|
72
|
+
const phasedRelease = config.getVersionReleasePhased();
|
|
73
|
+
if (!phasedRelease && shouldDeletePhasedRelease(context.versionPhasedRelease)) {
|
|
74
|
+
// if phased release was enabled, but now disabled, we need to remove it
|
|
75
|
+
await (0, log_2.logAsync)(() => context.versionPhasedRelease.deleteAsync(), {
|
|
76
|
+
pending: `Disabling phased release for ${chalk_1.default.bold(versionString)}...`,
|
|
77
|
+
success: `Disabled phased release for ${chalk_1.default.bold(versionString)}`,
|
|
78
|
+
failure: `Failed disabling phased release for ${chalk_1.default.bold(versionString)}`,
|
|
79
|
+
});
|
|
80
|
+
context.versionPhasedRelease = null;
|
|
81
|
+
}
|
|
82
|
+
else if (phasedRelease && !context.versionPhasedRelease) {
|
|
83
|
+
// if phased release was not yet set, but now enabled, we need to create it
|
|
84
|
+
context.versionPhasedRelease = await (0, log_2.logAsync)(() => context.version.createPhasedReleaseAsync({ state: phasedRelease.phasedReleaseState }), {
|
|
85
|
+
pending: `Enabling phased release for ${chalk_1.default.bold(versionString)}...`,
|
|
86
|
+
success: `Enabled phased release for ${chalk_1.default.bold(versionString)}`,
|
|
87
|
+
failure: `Failed enabling phased release for ${chalk_1.default.bold(versionString)}`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
56
90
|
const locales = config.getLocales();
|
|
57
91
|
if (locales.length <= 0) {
|
|
58
92
|
log_1.default.log((0, chalk_1.default) `{dim - Skipped localized version update, no locales configured}`);
|
|
@@ -80,13 +114,23 @@ class AppVersionTask extends task_1.AppleTask {
|
|
|
80
114
|
}
|
|
81
115
|
exports.AppVersionTask = AppVersionTask;
|
|
82
116
|
/**
|
|
83
|
-
* Resolve the AppStoreVersion instance, either from live or editable version.
|
|
117
|
+
* Resolve the AppStoreVersion instance, either from the store config, live, or editable version.
|
|
84
118
|
* This also checks if this is the first version, which disallow release notes.
|
|
85
119
|
*/
|
|
86
|
-
async function resolveVersionAsync(app, { editLive, platform }) {
|
|
120
|
+
async function resolveVersionAsync(app, { editLive, platform, version: versionString }) {
|
|
87
121
|
let version = null;
|
|
88
122
|
let versionIsLive = false;
|
|
89
|
-
if (
|
|
123
|
+
if (versionString) {
|
|
124
|
+
version = await findEditAppStoreVersionAsync(app, { platform, version: versionString });
|
|
125
|
+
if (!version) {
|
|
126
|
+
version = await createOrUpdateEditAppStoreVersionAsync(app, {
|
|
127
|
+
platform,
|
|
128
|
+
version: versionString,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
versionIsLive = (version === null || version === void 0 ? void 0 : version.attributes.appStoreState) === apple_utils_1.AppStoreState.READY_FOR_SALE;
|
|
132
|
+
}
|
|
133
|
+
if (!version && editLive) {
|
|
90
134
|
version = await app.getLiveAppStoreVersionAsync({ platform });
|
|
91
135
|
versionIsLive = !!version;
|
|
92
136
|
}
|
|
@@ -102,3 +146,60 @@ async function resolveVersionAsync(app, { editLive, platform }) {
|
|
|
102
146
|
versionIsFirst: versions.length === 1,
|
|
103
147
|
};
|
|
104
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Determine if we can, and should, delete the phased release instance.
|
|
151
|
+
* This returns true if the instance exist, and has one of the states below:
|
|
152
|
+
* - PhasedReleaseState.INACTIVE
|
|
153
|
+
* - PhasedReleaseState.ACTIVE
|
|
154
|
+
* - PhasedReleaseState.PAUSED
|
|
155
|
+
*/
|
|
156
|
+
function shouldDeletePhasedRelease(phasedRelease) {
|
|
157
|
+
if (!phasedRelease ||
|
|
158
|
+
phasedRelease.attributes.phasedReleaseState === apple_utils_1.PhasedReleaseState.COMPLETE) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
/*
|
|
164
|
+
* Search for editable app store versions that matches the `versionString` option.
|
|
165
|
+
* When nothing is found, it will return `null`, and a new version should be created.
|
|
166
|
+
*/
|
|
167
|
+
async function findEditAppStoreVersionAsync(app, options) {
|
|
168
|
+
if (options.version) {
|
|
169
|
+
const versions = await app.getAppStoreVersionsAsync({
|
|
170
|
+
query: {
|
|
171
|
+
limit: 200,
|
|
172
|
+
filter: {
|
|
173
|
+
platform: options.platform,
|
|
174
|
+
appStoreState: [
|
|
175
|
+
apple_utils_1.AppStoreState.PREPARE_FOR_SUBMISSION,
|
|
176
|
+
apple_utils_1.AppStoreState.DEVELOPER_REJECTED,
|
|
177
|
+
apple_utils_1.AppStoreState.REJECTED,
|
|
178
|
+
apple_utils_1.AppStoreState.METADATA_REJECTED,
|
|
179
|
+
apple_utils_1.AppStoreState.WAITING_FOR_REVIEW,
|
|
180
|
+
apple_utils_1.AppStoreState.INVALID_BINARY,
|
|
181
|
+
].join(','),
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
const version = versions.find(model => model.attributes.versionString === options.version);
|
|
186
|
+
if (version) {
|
|
187
|
+
return version;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Check if we can reuse an existing editable app version that has not been published yet.
|
|
194
|
+
* If not, it creates a new version based on the version string.
|
|
195
|
+
*/
|
|
196
|
+
async function createOrUpdateEditAppStoreVersionAsync(app, options) {
|
|
197
|
+
const version = await app.getEditAppStoreVersionAsync({ platform: options.platform });
|
|
198
|
+
if (version) {
|
|
199
|
+
return await version.updateAsync({ versionString: options.version });
|
|
200
|
+
}
|
|
201
|
+
return await app.createVersionAsync({
|
|
202
|
+
versionString: options.version,
|
|
203
|
+
platform: options.platform,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { MetadataContext } from '../../context';
|
|
2
2
|
import { AppleTask } from '../task';
|
|
3
|
+
import { AppVersionOptions } from './app-version';
|
|
4
|
+
declare type AppleTaskOptions = {
|
|
5
|
+
version?: AppVersionOptions['version'];
|
|
6
|
+
};
|
|
3
7
|
/**
|
|
4
8
|
* List of all eligible tasks to sync local store configuration to the App store.
|
|
5
9
|
*/
|
|
6
|
-
export declare function createAppleTasks(_ctx: MetadataContext): AppleTask[];
|
|
10
|
+
export declare function createAppleTasks(_ctx: MetadataContext, { version }?: AppleTaskOptions): AppleTask[];
|
|
11
|
+
export {};
|
|
@@ -8,7 +8,12 @@ const app_version_1 = require("./app-version");
|
|
|
8
8
|
/**
|
|
9
9
|
* List of all eligible tasks to sync local store configuration to the App store.
|
|
10
10
|
*/
|
|
11
|
-
function createAppleTasks(_ctx) {
|
|
12
|
-
return [
|
|
11
|
+
function createAppleTasks(_ctx, { version } = {}) {
|
|
12
|
+
return [
|
|
13
|
+
new app_version_1.AppVersionTask({ version }),
|
|
14
|
+
new app_info_1.AppInfoTask(),
|
|
15
|
+
new age_rating_1.AgeRatingTask(),
|
|
16
|
+
new app_review_detail_1.AppReviewDetailTask(),
|
|
17
|
+
];
|
|
13
18
|
}
|
|
14
19
|
exports.createAppleTasks = createAppleTasks;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { AgeRatingDeclarationProps } from '@expo/apple-utils';
|
|
3
3
|
export declare type AppleLocale = string;
|
|
4
4
|
export interface AppleMetadata {
|
|
5
|
+
version?: string;
|
|
5
6
|
copyright?: string;
|
|
6
7
|
info?: Record<AppleLocale, AppleInfo>;
|
|
7
8
|
categories?: AppleCategory;
|
|
@@ -14,13 +15,8 @@ export declare type AppleAdvisory = Partial<AgeRatingDeclarationProps>;
|
|
|
14
15
|
/** Apps can define up to two categories, or categories with up to two subcategories */
|
|
15
16
|
export declare type AppleCategory = (string | string[])[];
|
|
16
17
|
export interface AppleRelease {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
autoReleaseDate?: number | string;
|
|
20
|
-
automaticRelease?: boolean;
|
|
21
|
-
usesThirdPartyContent?: boolean;
|
|
22
|
-
/** Alternative to setting `ITSAppUsesNonExemptEncryption` in the binary's `Info.plist`. */
|
|
23
|
-
usesNonExemptEncryption?: boolean;
|
|
18
|
+
automaticRelease?: boolean | string;
|
|
19
|
+
phasedRelease?: boolean;
|
|
24
20
|
}
|
|
25
21
|
export interface AppleInfo {
|
|
26
22
|
title: string;
|
package/build/metadata/upload.js
CHANGED
|
@@ -17,6 +17,7 @@ const telemetry_1 = require("./utils/telemetry");
|
|
|
17
17
|
* Note, only App Store is supported at this time.
|
|
18
18
|
*/
|
|
19
19
|
async function uploadMetadataAsync(metadataCtx) {
|
|
20
|
+
var _a;
|
|
20
21
|
const filePath = path_1.default.resolve(metadataCtx.projectDir, metadataCtx.metadataPath);
|
|
21
22
|
if (!(await fs_extra_1.default.pathExists(filePath))) {
|
|
22
23
|
throw new errors_1.MetadataValidationError(`Store configuration file not found "${filePath}"`);
|
|
@@ -41,7 +42,11 @@ async function uploadMetadataAsync(metadataCtx) {
|
|
|
41
42
|
log_1.default.log('Uploading App Store configuration...');
|
|
42
43
|
const errors = [];
|
|
43
44
|
const config = (0, config_1.createAppleReader)(fileData);
|
|
44
|
-
const tasks = (0, tasks_1.createAppleTasks)(metadataCtx
|
|
45
|
+
const tasks = (0, tasks_1.createAppleTasks)(metadataCtx, {
|
|
46
|
+
// We need to resolve a different version as soon as possible.
|
|
47
|
+
// This version is the parent model of all changes we are going to push.
|
|
48
|
+
version: (_a = config.getVersion()) === null || _a === void 0 ? void 0 : _a.versionString,
|
|
49
|
+
});
|
|
45
50
|
const taskCtx = { app };
|
|
46
51
|
for (const task of tasks) {
|
|
47
52
|
try {
|
package/build/platform.d.ts
CHANGED
|
@@ -12,4 +12,5 @@ export declare enum RequestedPlatform {
|
|
|
12
12
|
}
|
|
13
13
|
export declare const requestedPlatformDisplayNames: Record<RequestedPlatform, string>;
|
|
14
14
|
export declare function selectRequestedPlatformAsync(platform?: string): Promise<RequestedPlatform>;
|
|
15
|
+
export declare function selectPlatformAsync(platform?: string): Promise<Platform>;
|
|
15
16
|
export declare function toPlatforms(requestedPlatform: RequestedPlatform): Platform[];
|
package/build/platform.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toPlatforms = exports.selectRequestedPlatformAsync = exports.requestedPlatformDisplayNames = exports.RequestedPlatform = exports.appPlatformEmojis = exports.appPlatformDisplayNames = void 0;
|
|
3
|
+
exports.toPlatforms = exports.selectPlatformAsync = exports.selectRequestedPlatformAsync = exports.requestedPlatformDisplayNames = exports.RequestedPlatform = exports.appPlatformEmojis = exports.appPlatformDisplayNames = void 0;
|
|
4
4
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
5
5
|
const generated_1 = require("./graphql/generated");
|
|
6
6
|
const prompts_1 = require("./prompts");
|
|
@@ -42,6 +42,22 @@ async function selectRequestedPlatformAsync(platform) {
|
|
|
42
42
|
return requestedPlatform;
|
|
43
43
|
}
|
|
44
44
|
exports.selectRequestedPlatformAsync = selectRequestedPlatformAsync;
|
|
45
|
+
async function selectPlatformAsync(platform) {
|
|
46
|
+
if (platform && Object.values(eas_build_job_1.Platform).includes(platform.toLowerCase())) {
|
|
47
|
+
return platform.toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
const { resolvedPlatform } = await (0, prompts_1.promptAsync)({
|
|
50
|
+
type: 'select',
|
|
51
|
+
message: 'Select platform',
|
|
52
|
+
name: 'resolvedPlatform',
|
|
53
|
+
choices: [
|
|
54
|
+
{ title: 'Android', value: eas_build_job_1.Platform.ANDROID },
|
|
55
|
+
{ title: 'iOS', value: eas_build_job_1.Platform.IOS },
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
return resolvedPlatform;
|
|
59
|
+
}
|
|
60
|
+
exports.selectPlatformAsync = selectPlatformAsync;
|
|
45
61
|
function toPlatforms(requestedPlatform) {
|
|
46
62
|
if (requestedPlatform === RequestedPlatform.All) {
|
|
47
63
|
return [eas_build_job_1.Platform.ANDROID, eas_build_job_1.Platform.IOS];
|
|
@@ -120,8 +120,8 @@ exports.isApplicationIdValid = isApplicationIdValid;
|
|
|
120
120
|
let warnPrinted = false;
|
|
121
121
|
function warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject(projectDir, exp) {
|
|
122
122
|
if (config_plugins_1.AndroidConfig.Package.getPackage(exp) && !warnPrinted) {
|
|
123
|
-
log_1.default.warn(`
|
|
124
|
-
'EAS Build
|
|
123
|
+
log_1.default.warn(`Specified value for "android.package" in ${(0, projectUtils_1.getProjectConfigDescription)(projectDir)} is ignored because an ${chalk_1.default.bold('android')} directory was detected in the project.\n` +
|
|
124
|
+
'EAS Build will use the value found in the native code.');
|
|
125
125
|
warnPrinted = true;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNextVersionCode = exports.isValidVersionCode = exports.VERSION_CODE_REQUIREMENTS = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const MAX_VERSION_CODE = 2000000000;
|
|
7
|
+
exports.VERSION_CODE_REQUIREMENTS = `versionCode needs to be a positive integer smaller or equal to ${MAX_VERSION_CODE}`;
|
|
8
|
+
function isValidVersionCode(versionCode) {
|
|
9
|
+
const numericVersionCode = typeof versionCode === 'string' ? Number(versionCode) : versionCode;
|
|
10
|
+
return (Number.isInteger(numericVersionCode) &&
|
|
11
|
+
numericVersionCode <= MAX_VERSION_CODE &&
|
|
12
|
+
numericVersionCode > 0);
|
|
13
|
+
}
|
|
14
|
+
exports.isValidVersionCode = isValidVersionCode;
|
|
15
|
+
function getNextVersionCode(versionCode) {
|
|
16
|
+
(0, assert_1.default)(isValidVersionCode(versionCode), `Invalid versionCode ${versionCode}`);
|
|
17
|
+
const numericVersionCode = typeof versionCode === 'string' ? Number(versionCode) : versionCode;
|
|
18
|
+
if (numericVersionCode >= MAX_VERSION_CODE) {
|
|
19
|
+
throw new Error(`Invalid value: ${exports.VERSION_CODE_REQUIREMENTS}.`);
|
|
20
|
+
}
|
|
21
|
+
return numericVersionCode + 1;
|
|
22
|
+
}
|
|
23
|
+
exports.getNextVersionCode = getNextVersionCode;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ExpoConfig } from '@expo/config';
|
|
2
|
+
import { Platform } from '@expo/eas-build-job';
|
|
3
|
+
import { BuildProfile } from '@expo/eas-json';
|
|
4
|
+
export declare function getApplicationIdentifierAsync(projectDir: string, exp: ExpoConfig, buildProfile: BuildProfile, platform: Platform): Promise<string>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getApplicationIdentifierAsync = void 0;
|
|
4
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
5
|
+
const applicationId_1 = require("./android/applicationId");
|
|
6
|
+
const gradle_1 = require("./android/gradle");
|
|
7
|
+
const bundleIdentifier_1 = require("./ios/bundleIdentifier");
|
|
8
|
+
const scheme_1 = require("./ios/scheme");
|
|
9
|
+
const target_1 = require("./ios/target");
|
|
10
|
+
const workflow_1 = require("./workflow");
|
|
11
|
+
async function getApplicationIdentifierAsync(projectDir, exp, buildProfile, platform) {
|
|
12
|
+
if (platform === eas_build_job_1.Platform.ANDROID) {
|
|
13
|
+
const profile = buildProfile;
|
|
14
|
+
const workflow = await (0, workflow_1.resolveWorkflowAsync)(projectDir, eas_build_job_1.Platform.ANDROID);
|
|
15
|
+
const gradleContext = await (0, gradle_1.resolveGradleBuildContextAsync)(projectDir, profile);
|
|
16
|
+
if (workflow === eas_build_job_1.Workflow.MANAGED) {
|
|
17
|
+
await (0, applicationId_1.ensureApplicationIdIsDefinedForManagedProjectAsync)(projectDir, exp);
|
|
18
|
+
}
|
|
19
|
+
return await (0, applicationId_1.getApplicationIdAsync)(projectDir, exp, gradleContext);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const profile = buildProfile;
|
|
23
|
+
const xcodeBuildContext = await (0, scheme_1.resolveXcodeBuildContextAsync)({ exp, projectDir, nonInteractive: false }, profile);
|
|
24
|
+
const targets = await (0, target_1.resolveTargetsAsync)({
|
|
25
|
+
projectDir,
|
|
26
|
+
exp,
|
|
27
|
+
xcodeBuildContext,
|
|
28
|
+
env: profile.env,
|
|
29
|
+
});
|
|
30
|
+
const applicationTarget = (0, target_1.findApplicationTarget)(targets);
|
|
31
|
+
return await (0, bundleIdentifier_1.getBundleIdentifierAsync)(projectDir, exp, {
|
|
32
|
+
targetName: applicationTarget.targetName,
|
|
33
|
+
buildConfiguration: applicationTarget.buildConfiguration,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.getApplicationIdentifierAsync = getApplicationIdentifierAsync;
|
|
@@ -104,8 +104,8 @@ exports.isBundleIdentifierValid = isBundleIdentifierValid;
|
|
|
104
104
|
let warnPrinted = false;
|
|
105
105
|
function warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject(projectDir, exp) {
|
|
106
106
|
if (config_plugins_1.IOSConfig.BundleIdentifier.getBundleIdentifier(exp) && !warnPrinted) {
|
|
107
|
-
log_1.default.warn(`
|
|
108
|
-
'EAS Build
|
|
107
|
+
log_1.default.warn(`Specified value for "ios.bundleIdentifier" in ${(0, projectUtils_1.getProjectConfigDescription)(projectDir)} is ignored because an ${chalk_1.default.bold('ios')} directory was detected in the project.\n` +
|
|
108
|
+
'EAS Build will use the value found in the native code.');
|
|
109
109
|
warnPrinted = true;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -55,6 +55,7 @@ exports.resolveMangedProjectTargetsAsync = resolveMangedProjectTargetsAsync;
|
|
|
55
55
|
async function resolveBareProjectTargetsAsync({ exp, projectDir, xcodeBuildContext, }) {
|
|
56
56
|
const { buildScheme, buildConfiguration } = xcodeBuildContext;
|
|
57
57
|
const result = [];
|
|
58
|
+
const pbxProject = config_plugins_1.IOSConfig.XcodeUtils.getPbxproj(projectDir);
|
|
58
59
|
const applicationTarget = await config_plugins_1.IOSConfig.Target.findApplicationTargetWithDependenciesAsync(projectDir, buildScheme);
|
|
59
60
|
const bundleIdentifier = await (0, bundleIdentifier_1.getBundleIdentifierAsync)(projectDir, exp, {
|
|
60
61
|
targetName: applicationTarget.name,
|
|
@@ -69,6 +70,7 @@ async function resolveBareProjectTargetsAsync({ exp, projectDir, xcodeBuildConte
|
|
|
69
70
|
bundleIdentifier,
|
|
70
71
|
buildConfiguration,
|
|
71
72
|
entitlements: entitlements !== null && entitlements !== void 0 ? entitlements : {},
|
|
73
|
+
buildSettings: resolveBareProjectBuildSettings(pbxProject, applicationTarget.name, buildConfiguration),
|
|
72
74
|
});
|
|
73
75
|
const dependencies = await resolveBareProjectDependenciesAsync({
|
|
74
76
|
exp,
|
|
@@ -76,6 +78,7 @@ async function resolveBareProjectTargetsAsync({ exp, projectDir, xcodeBuildConte
|
|
|
76
78
|
buildConfiguration,
|
|
77
79
|
target: applicationTarget,
|
|
78
80
|
bundleIdentifier,
|
|
81
|
+
pbxProject,
|
|
79
82
|
});
|
|
80
83
|
if (dependencies.length > 0) {
|
|
81
84
|
result.push(...dependencies);
|
|
@@ -96,7 +99,7 @@ async function resolveTargetsAsync(opts) {
|
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
exports.resolveTargetsAsync = resolveTargetsAsync;
|
|
99
|
-
async function resolveBareProjectDependenciesAsync({ exp, projectDir, buildConfiguration, target, bundleIdentifier, }) {
|
|
102
|
+
async function resolveBareProjectDependenciesAsync({ exp, projectDir, buildConfiguration, target, bundleIdentifier, pbxProject, }) {
|
|
100
103
|
const result = [];
|
|
101
104
|
if (target.dependencies && target.dependencies.length > 0) {
|
|
102
105
|
for (const dependency of target.dependencies) {
|
|
@@ -114,6 +117,7 @@ async function resolveBareProjectDependenciesAsync({ exp, projectDir, buildConfi
|
|
|
114
117
|
bundleIdentifier: dependencyBundleIdentifier,
|
|
115
118
|
parentBundleIdentifier: bundleIdentifier,
|
|
116
119
|
entitlements: entitlements !== null && entitlements !== void 0 ? entitlements : {},
|
|
120
|
+
buildSettings: resolveBareProjectBuildSettings(pbxProject, dependency.name, buildConfiguration),
|
|
117
121
|
});
|
|
118
122
|
const dependencyDependencies = await resolveBareProjectDependenciesAsync({
|
|
119
123
|
exp,
|
|
@@ -121,6 +125,7 @@ async function resolveBareProjectDependenciesAsync({ exp, projectDir, buildConfi
|
|
|
121
125
|
buildConfiguration,
|
|
122
126
|
target: dependency,
|
|
123
127
|
bundleIdentifier: dependencyBundleIdentifier,
|
|
128
|
+
pbxProject,
|
|
124
129
|
});
|
|
125
130
|
if (dependencyDependencies.length > 0) {
|
|
126
131
|
result.push(...dependencyDependencies);
|
|
@@ -145,3 +150,11 @@ function findTargetByName(targets, name) {
|
|
|
145
150
|
return target;
|
|
146
151
|
}
|
|
147
152
|
exports.findTargetByName = findTargetByName;
|
|
153
|
+
function resolveBareProjectBuildSettings(project, targetName, buildConfiguration) {
|
|
154
|
+
var _a;
|
|
155
|
+
const xcBuildConfiguration = config_plugins_1.IOSConfig.Target.getXCBuildConfigurationFromPbxproj(project, {
|
|
156
|
+
targetName,
|
|
157
|
+
buildConfiguration,
|
|
158
|
+
});
|
|
159
|
+
return (_a = xcBuildConfiguration === null || xcBuildConfiguration === void 0 ? void 0 : xcBuildConfiguration.buildSettings) !== null && _a !== void 0 ? _a : {};
|
|
160
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const BUILD_NUMBER_REQUIREMENTS = "buildNumber needs to consist only of up to 3 dot-separated positive integers";
|
|
2
|
+
export declare function isValidBuildNumber(buildNumber: string): boolean;
|
|
3
|
+
export declare function getNextBuildNumber(buildNumber: string): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNextBuildNumber = exports.isValidBuildNumber = exports.BUILD_NUMBER_REQUIREMENTS = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
exports.BUILD_NUMBER_REQUIREMENTS = `buildNumber needs to consist only of up to 3 dot-separated positive integers`;
|
|
7
|
+
function isValidBuildNumber(buildNumber) {
|
|
8
|
+
return !!buildNumber.match(/^\d+(\.\d+)?(\.\d+)?$/);
|
|
9
|
+
}
|
|
10
|
+
exports.isValidBuildNumber = isValidBuildNumber;
|
|
11
|
+
function getNextBuildNumber(buildNumber) {
|
|
12
|
+
(0, assert_1.default)(isValidBuildNumber(buildNumber), `Invalid buildNumber ${buildNumber}`);
|
|
13
|
+
const comps = buildNumber.split('.');
|
|
14
|
+
comps[comps.length - 1] = String(Number(comps[comps.length - 1]) + 1);
|
|
15
|
+
return comps.join('.');
|
|
16
|
+
}
|
|
17
|
+
exports.getNextBuildNumber = getNextBuildNumber;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { ExpoConfig, Platform } from '@expo/config';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import { PartialManifestAsset } from '../graphql/generated';
|
|
5
|
-
export declare const TIMEOUT_LIMIT = 60000;
|
|
6
5
|
export declare type PublishPlatform = Extract<'android' | 'ios', Platform>;
|
|
7
6
|
declare type Metadata = {
|
|
8
7
|
version: number;
|
|
@@ -77,6 +76,8 @@ declare type AssetUploadResult = {
|
|
|
77
76
|
assetCount: number;
|
|
78
77
|
uniqueAssetCount: number;
|
|
79
78
|
uniqueUploadedAssetCount: number;
|
|
79
|
+
assetLimitPerUpdateGroup: number;
|
|
80
80
|
};
|
|
81
|
-
export declare function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAssets, updateSpinnerText?: (
|
|
81
|
+
export declare function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAssets, projectId: string, updateSpinnerText?: (totalAssets: number, missingAssets: number) => void): Promise<AssetUploadResult>;
|
|
82
|
+
export declare function isUploadedAssetCountAboveWarningThreshold(uploadedAssetCount: number, assetLimitPerUpdateGroup: number): boolean;
|
|
82
83
|
export {};
|
package/build/project/publish.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi =
|
|
3
|
+
exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const json_file_1 = tslib_1.__importDefault(require("@expo/json-file"));
|
|
6
6
|
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
@@ -15,7 +15,6 @@ const PublishQuery_1 = require("../graphql/queries/PublishQuery");
|
|
|
15
15
|
const uploads_1 = require("../uploads");
|
|
16
16
|
const expoCli_1 = require("../utils/expoCli");
|
|
17
17
|
const uniqBy_1 = tslib_1.__importDefault(require("../utils/expodash/uniqBy"));
|
|
18
|
-
exports.TIMEOUT_LIMIT = 60000; // 1 minute
|
|
19
18
|
const fileMetadataJoi = joi_1.default.object({
|
|
20
19
|
assets: joi_1.default.array()
|
|
21
20
|
.required()
|
|
@@ -113,6 +112,7 @@ async function buildBundlesAsync({ projectDir, inputDir, }) {
|
|
|
113
112
|
inputDir,
|
|
114
113
|
'--experimental-bundle',
|
|
115
114
|
'--non-interactive',
|
|
115
|
+
'--dump-sourcemap',
|
|
116
116
|
]);
|
|
117
117
|
}
|
|
118
118
|
exports.buildBundlesAsync = buildBundlesAsync;
|
|
@@ -184,7 +184,7 @@ async function filterOutAssetsThatAlreadyExistAsync(uniqueAssetsWithStorageKey)
|
|
|
184
184
|
return missingAssets;
|
|
185
185
|
}
|
|
186
186
|
exports.filterOutAssetsThatAlreadyExistAsync = filterOutAssetsThatAlreadyExistAsync;
|
|
187
|
-
async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
|
|
187
|
+
async function uploadAssetsAsync(assetsForUpdateInfoGroup, projectId, updateSpinnerText) {
|
|
188
188
|
let assets = [];
|
|
189
189
|
let platform;
|
|
190
190
|
for (platform in assetsForUpdateInfoGroup) {
|
|
@@ -194,7 +194,6 @@ async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
|
|
|
194
194
|
...assetsForUpdateInfoGroup[platform].assets,
|
|
195
195
|
];
|
|
196
196
|
}
|
|
197
|
-
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(`${assets.length} ${assets.length === 1 ? 'asset' : 'assets'} present`);
|
|
198
197
|
const assetsWithStorageKey = await Promise.all(assets.map(async (asset) => {
|
|
199
198
|
return {
|
|
200
199
|
...asset,
|
|
@@ -202,34 +201,40 @@ async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
|
|
|
202
201
|
};
|
|
203
202
|
}));
|
|
204
203
|
const uniqueAssets = (0, uniqBy_1.default)(assetsWithStorageKey, asset => asset.storageKey);
|
|
205
|
-
|
|
204
|
+
const totalAssets = uniqueAssets.length;
|
|
205
|
+
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(totalAssets, totalAssets);
|
|
206
206
|
let missingAssets = await filterOutAssetsThatAlreadyExistAsync(uniqueAssets);
|
|
207
207
|
const uniqueUploadedAssetCount = missingAssets.length;
|
|
208
208
|
const { specifications } = await PublishMutation_1.PublishMutation.getUploadURLsAsync(missingAssets.map(ma => ma.contentType));
|
|
209
|
+
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(totalAssets, missingAssets.length);
|
|
209
210
|
const assetUploadPromiseLimit = (0, promise_limit_1.default)(15);
|
|
210
|
-
await Promise.all(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
211
|
+
const [assetLimitPerUpdateGroup] = await Promise.all([
|
|
212
|
+
PublishQuery_1.PublishQuery.getAssetLimitPerUpdateGroupAsync(projectId),
|
|
213
|
+
missingAssets.map((missingAsset, i) => {
|
|
214
|
+
assetUploadPromiseLimit(async () => {
|
|
215
|
+
const presignedPost = JSON.parse(specifications[i]);
|
|
216
|
+
await (0, uploads_1.uploadWithPresignedPostAsync)(missingAsset.path, presignedPost);
|
|
217
|
+
});
|
|
218
|
+
}),
|
|
219
|
+
]);
|
|
219
220
|
let timeout = 1;
|
|
220
221
|
while (missingAssets.length > 0) {
|
|
221
|
-
const timeoutPromise = new Promise(resolve => setTimeout(resolve, timeout * 1000)); // linear backoff
|
|
222
|
+
const timeoutPromise = new Promise(resolve => setTimeout(resolve, Math.min(timeout * 1000, 5000))); // linear backoff
|
|
222
223
|
missingAssets = await filterOutAssetsThatAlreadyExistAsync(missingAssets);
|
|
223
224
|
await timeoutPromise; // await after filterOutAssetsThatAlreadyExistAsync for easy mocking with jest.runAllTimers
|
|
224
225
|
timeout += 1;
|
|
225
|
-
|
|
226
|
-
throw new Error('Asset upload timed out. Please try again.');
|
|
227
|
-
}
|
|
226
|
+
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(totalAssets, missingAssets.length);
|
|
228
227
|
}
|
|
229
228
|
return {
|
|
230
229
|
assetCount: assets.length,
|
|
231
230
|
uniqueAssetCount: uniqueAssets.length,
|
|
232
231
|
uniqueUploadedAssetCount,
|
|
232
|
+
assetLimitPerUpdateGroup,
|
|
233
233
|
};
|
|
234
234
|
}
|
|
235
235
|
exports.uploadAssetsAsync = uploadAssetsAsync;
|
|
236
|
+
function isUploadedAssetCountAboveWarningThreshold(uploadedAssetCount, assetLimitPerUpdateGroup) {
|
|
237
|
+
const warningThreshold = Math.floor(assetLimitPerUpdateGroup * 0.75);
|
|
238
|
+
return uploadedAssetCount > warningThreshold;
|
|
239
|
+
}
|
|
240
|
+
exports.isUploadedAssetCountAboveWarningThreshold = isUploadedAssetCountAboveWarningThreshold;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ExpoConfig } from '@expo/config';
|
|
2
|
+
import { Platform } from '@expo/eas-build-job';
|
|
3
|
+
import { EasJson, EasJsonReader } from '@expo/eas-json';
|
|
4
|
+
import { ProfileData } from '../utils/profiles';
|
|
5
|
+
export declare function ensureVersionSourceIsRemoteAsync(projectDir: string, easJsonReader: EasJsonReader): Promise<void>;
|
|
6
|
+
export declare function validateBuildProfileVersionSettings(profileInfo: ProfileData<'build'>, cliConfig: EasJson['cli']): void;
|
|
7
|
+
export declare function validateAppConfigForRemoteVersionSource(exp: ExpoConfig, platform: Platform): void;
|
|
8
|
+
export declare function getBuildVersionName(platform: Platform): string;
|