eas-cli 0.55.1 → 0.56.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 +44 -44
- package/build/build/android/version.d.ts +5 -0
- package/build/build/android/version.js +16 -9
- package/build/build/build.js +7 -2
- package/build/build/context.d.ts +2 -3
- package/build/build/createContext.d.ts +3 -2
- package/build/build/createContext.js +2 -1
- package/build/build/ios/build.js +1 -16
- package/build/build/ios/syncProjectConfiguration.d.ts +3 -3
- package/build/build/ios/syncProjectConfiguration.js +2 -2
- package/build/build/ios/version.d.ts +10 -3
- package/build/build/ios/version.js +57 -28
- package/build/build/metadata.js +1 -1
- package/build/build/runBuildAndSubmit.js +7 -4
- package/build/commands/build/version/set.d.ts +10 -0
- package/build/commands/build/version/set.js +82 -0
- package/build/commands/build/version/sync.d.ts +12 -0
- package/build/commands/build/version/sync.js +124 -0
- package/build/commands/update/index.js +3 -1
- package/build/credentials/ios/types.d.ts +2 -0
- package/build/graphql/generated.d.ts +87 -2
- package/build/graphql/generated.js +1 -0
- package/build/graphql/mutations/AppVersionMutation.d.ts +11 -0
- package/build/graphql/mutations/AppVersionMutation.js +28 -0
- package/build/graphql/queries/AppVersionQuery.d.ts +4 -0
- package/build/graphql/queries/AppVersionQuery.js +37 -0
- 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 +1 -2
- package/build/project/publish.js +7 -11
- package/build/project/remoteVersionSource.d.ts +6 -0
- package/build/project/remoteVersionSource.js +52 -0
- package/build/submit/utils/files.d.ts +0 -6
- package/build/submit/utils/files.js +3 -16
- package/build/uploads.d.ts +8 -2
- package/build/uploads.js +19 -4
- package/oclif.manifest.json +1 -1
- package/package.json +8 -4
|
@@ -114,6 +114,7 @@ var BuildPriority;
|
|
|
114
114
|
(function (BuildPriority) {
|
|
115
115
|
BuildPriority["High"] = "HIGH";
|
|
116
116
|
BuildPriority["Normal"] = "NORMAL";
|
|
117
|
+
BuildPriority["NormalPlus"] = "NORMAL_PLUS";
|
|
117
118
|
})(BuildPriority = exports.BuildPriority || (exports.BuildPriority = {}));
|
|
118
119
|
var BuildResourceClass;
|
|
119
120
|
(function (BuildResourceClass) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AppPlatform } from '../generated';
|
|
2
|
+
export declare const AppVersionMutation: {
|
|
3
|
+
createAppVersionAsync(appVersionInput: {
|
|
4
|
+
appId: string;
|
|
5
|
+
platform: AppPlatform;
|
|
6
|
+
applicationIdentifier: string;
|
|
7
|
+
storeVersion: string;
|
|
8
|
+
buildVersion: string;
|
|
9
|
+
runtimeVersion?: string;
|
|
10
|
+
}): Promise<string>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppVersionMutation = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
|
|
7
|
+
const client_1 = require("../client");
|
|
8
|
+
exports.AppVersionMutation = {
|
|
9
|
+
async createAppVersionAsync(appVersionInput) {
|
|
10
|
+
var _a;
|
|
11
|
+
const data = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
|
|
12
|
+
.mutation((0, graphql_tag_1.default) `
|
|
13
|
+
mutation CreateAppVersionMutation($appVersionInput: AppVersionInput!) {
|
|
14
|
+
appVersion {
|
|
15
|
+
createAppVersion(appVersionInput: $appVersionInput) {
|
|
16
|
+
id
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`, {
|
|
21
|
+
appVersionInput,
|
|
22
|
+
})
|
|
23
|
+
.toPromise());
|
|
24
|
+
const appVersionId = (_a = data.appVersion) === null || _a === void 0 ? void 0 : _a.createAppVersion.id;
|
|
25
|
+
(0, assert_1.default)(appVersionId, 'AppVersion ID must be defined');
|
|
26
|
+
return appVersionId;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppVersionQuery = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
|
|
6
|
+
const client_1 = require("../client");
|
|
7
|
+
exports.AppVersionQuery = {
|
|
8
|
+
async latestVersionAsync(appId, platform, applicationIdentifier) {
|
|
9
|
+
var _a;
|
|
10
|
+
const data = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
|
|
11
|
+
.query((0, graphql_tag_1.default) `
|
|
12
|
+
query LatestAppVersion(
|
|
13
|
+
$appId: String!
|
|
14
|
+
$platform: AppPlatform!
|
|
15
|
+
$applicationIdentifier: String!
|
|
16
|
+
) {
|
|
17
|
+
app {
|
|
18
|
+
byId(appId: $appId) {
|
|
19
|
+
id
|
|
20
|
+
latestAppVersionByPlatformAndApplicationIdentifier(
|
|
21
|
+
platform: $platform
|
|
22
|
+
applicationIdentifier: $applicationIdentifier
|
|
23
|
+
) {
|
|
24
|
+
id
|
|
25
|
+
storeVersion
|
|
26
|
+
buildVersion
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`, { appId, applicationIdentifier, platform }, {
|
|
32
|
+
additionalTypenames: ['App', 'AppVersion'],
|
|
33
|
+
})
|
|
34
|
+
.toPromise());
|
|
35
|
+
return (_a = data.app.byId.latestAppVersionByPlatformAndApplicationIdentifier) !== null && _a !== void 0 ? _a : null;
|
|
36
|
+
},
|
|
37
|
+
};
|
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;
|
|
@@ -78,5 +77,5 @@ declare type AssetUploadResult = {
|
|
|
78
77
|
uniqueAssetCount: number;
|
|
79
78
|
uniqueUploadedAssetCount: number;
|
|
80
79
|
};
|
|
81
|
-
export declare function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAssets, updateSpinnerText?: (
|
|
80
|
+
export declare function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAssets, updateSpinnerText?: (totalAssets: number, missingAssets: number) => void): Promise<AssetUploadResult>;
|
|
82
81
|
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.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;
|
|
@@ -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,10 +201,12 @@ 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
211
|
await Promise.all(missingAssets.map((missingAsset, i) => {
|
|
211
212
|
assetUploadPromiseLimit(async () => {
|
|
@@ -213,18 +214,13 @@ async function uploadAssetsAsync(assetsForUpdateInfoGroup, updateSpinnerText) {
|
|
|
213
214
|
await (0, uploads_1.uploadWithPresignedPostAsync)(missingAsset.path, presignedPost);
|
|
214
215
|
});
|
|
215
216
|
}));
|
|
216
|
-
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(`${missingAssets.length} new ${missingAssets.length === 1 ? 'asset' : 'assets'} uploading`);
|
|
217
|
-
// Wait up to TIMEOUT_LIMIT for assets to be uploaded and processed
|
|
218
|
-
const start = Date.now();
|
|
219
217
|
let timeout = 1;
|
|
220
218
|
while (missingAssets.length > 0) {
|
|
221
|
-
const timeoutPromise = new Promise(resolve => setTimeout(resolve, timeout * 1000)); // linear backoff
|
|
219
|
+
const timeoutPromise = new Promise(resolve => setTimeout(resolve, Math.min(timeout * 1000, 5000))); // linear backoff
|
|
222
220
|
missingAssets = await filterOutAssetsThatAlreadyExistAsync(missingAssets);
|
|
223
221
|
await timeoutPromise; // await after filterOutAssetsThatAlreadyExistAsync for easy mocking with jest.runAllTimers
|
|
224
222
|
timeout += 1;
|
|
225
|
-
|
|
226
|
-
throw new Error('Asset upload timed out. Please try again.');
|
|
227
|
-
}
|
|
223
|
+
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(totalAssets, missingAssets.length);
|
|
228
224
|
}
|
|
229
225
|
return {
|
|
230
226
|
assetCount: assets.length,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ExpoConfig } from '@expo/config';
|
|
2
|
+
import { Platform } from '@expo/eas-build-job';
|
|
3
|
+
import { EasJsonReader } from '@expo/eas-json';
|
|
4
|
+
export declare function ensureRemoteVersionPolicyAsync(projectDir: string, easJsonReader: EasJsonReader): Promise<void>;
|
|
5
|
+
export declare function validateAppConfigForRemoteVersionPolicyAsync(exp: ExpoConfig): Promise<void>;
|
|
6
|
+
export declare function getBuildVersionName(platform: Platform): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBuildVersionName = exports.validateAppConfigForRemoteVersionPolicyAsync = exports.ensureRemoteVersionPolicyAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
|
+
const eas_json_1 = require("@expo/eas-json");
|
|
7
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
9
|
+
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
10
|
+
const prompts_1 = require("../prompts");
|
|
11
|
+
async function ensureRemoteVersionPolicyAsync(projectDir, easJsonReader) {
|
|
12
|
+
const easJsonCliConfig = await easJsonReader.getCliConfigAsync();
|
|
13
|
+
if ((easJsonCliConfig === null || easJsonCliConfig === void 0 ? void 0 : easJsonCliConfig.appVersionSource) === eas_json_1.AppVersionSource.REMOTE) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
log_1.default.log(`The app version source defines whether the app version is stored locally in your project source (e.g. in app.json, Info.plist, or build.gradle) or remotely on EAS servers and only applied to the project at build time. To use this command, you will need to enable the remote version policy by adding ${chalk_1.default.bold('{"cli": { "appVersionSource": "remote" }}')} in eas.json.`);
|
|
17
|
+
// TODO: add link to docs
|
|
18
|
+
const confirm = await (0, prompts_1.confirmAsync)({
|
|
19
|
+
message: 'Do you want to set app version source to remote now?',
|
|
20
|
+
});
|
|
21
|
+
if (!confirm) {
|
|
22
|
+
throw new Error('Aborting...');
|
|
23
|
+
}
|
|
24
|
+
const easJsonPath = eas_json_1.EasJsonReader.formatEasJsonPath(projectDir);
|
|
25
|
+
const easJson = await fs_extra_1.default.readJSON(easJsonPath);
|
|
26
|
+
easJson.cli = { ...easJson === null || easJson === void 0 ? void 0 : easJson.cli, appVersionSource: eas_json_1.AppVersionSource.REMOTE };
|
|
27
|
+
await fs_extra_1.default.writeFile(easJsonPath, `${JSON.stringify(easJson, null, 2)}\n`);
|
|
28
|
+
log_1.default.withTick('Updated eas.json');
|
|
29
|
+
}
|
|
30
|
+
exports.ensureRemoteVersionPolicyAsync = ensureRemoteVersionPolicyAsync;
|
|
31
|
+
async function validateAppConfigForRemoteVersionPolicyAsync(exp) {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
if (typeof exp.runtimeVersion === 'object' && ((_a = exp.runtimeVersion) === null || _a === void 0 ? void 0 : _a.policy) === 'nativeVersion') {
|
|
34
|
+
throw new Error(`${chalk_1.default.bold('nativeVersion')} policy for ${chalk_1.default.bold('runtimeVersion')} is currently not supported when version source is set to remote. Switch policy e.g. to ${chalk_1.default.bold('appVersion')} or define version explicitly.`);
|
|
35
|
+
}
|
|
36
|
+
if (((_b = exp.ios) === null || _b === void 0 ? void 0 : _b.buildNumber) !== undefined) {
|
|
37
|
+
throw new Error(`${chalk_1.default.bold('ios.buildNumber')} field in app config is not supported when version source is set to remote, remove it and re-run the command.`);
|
|
38
|
+
}
|
|
39
|
+
if (((_c = exp.android) === null || _c === void 0 ? void 0 : _c.versionCode) !== undefined) {
|
|
40
|
+
throw new Error(`${chalk_1.default.bold('android.versionCode')} field in app config is not supported when version source is set to remote, remove it and re-run the command.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.validateAppConfigForRemoteVersionPolicyAsync = validateAppConfigForRemoteVersionPolicyAsync;
|
|
44
|
+
function getBuildVersionName(platform) {
|
|
45
|
+
if (platform === eas_build_job_1.Platform.ANDROID) {
|
|
46
|
+
return 'versionCode';
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return 'buildNumber';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.getBuildVersionName = getBuildVersionName;
|
|
@@ -1,8 +1,2 @@
|
|
|
1
1
|
export declare function isExistingFileAsync(filePath: string): Promise<boolean>;
|
|
2
2
|
export declare function uploadAppArchiveAsync(path: string): Promise<string>;
|
|
3
|
-
/**
|
|
4
|
-
* S3 returns broken URLs, sth like:
|
|
5
|
-
* https://submission-service-archives.s3.amazonaws.com/production%2Fdc98ca84-1473-4cb3-ae81-8c7b291cb27e%2F4424aa95-b985-4e2f-8755-9507b1037c1c
|
|
6
|
-
* This function replaces %2F with /.
|
|
7
|
-
*/
|
|
8
|
-
export declare function fixArchiveUrl(archiveUrl: string): string;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.uploadAppArchiveAsync = exports.isExistingFileAsync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
6
|
-
const url_1 = require("url");
|
|
7
6
|
const generated_1 = require("../../graphql/generated");
|
|
8
7
|
const uploads_1 = require("../../uploads");
|
|
9
8
|
const progress_1 = require("../../utils/progress");
|
|
@@ -19,23 +18,11 @@ async function isExistingFileAsync(filePath) {
|
|
|
19
18
|
exports.isExistingFileAsync = isExistingFileAsync;
|
|
20
19
|
async function uploadAppArchiveAsync(path) {
|
|
21
20
|
const fileSize = (await fs_extra_1.default.stat(path)).size;
|
|
22
|
-
const {
|
|
21
|
+
const { url } = await (0, uploads_1.uploadFileAtPathToS3Async)(generated_1.UploadSessionType.EasSubmitAppArchive, path, (0, progress_1.createProgressTracker)({
|
|
23
22
|
total: fileSize,
|
|
24
23
|
message: 'Uploading to EAS Submit',
|
|
25
24
|
completedMessage: 'Uploaded to EAS Submit',
|
|
26
25
|
}));
|
|
27
|
-
|
|
28
|
-
return fixArchiveUrl(String(url));
|
|
26
|
+
return url;
|
|
29
27
|
}
|
|
30
28
|
exports.uploadAppArchiveAsync = uploadAppArchiveAsync;
|
|
31
|
-
/**
|
|
32
|
-
* S3 returns broken URLs, sth like:
|
|
33
|
-
* https://submission-service-archives.s3.amazonaws.com/production%2Fdc98ca84-1473-4cb3-ae81-8c7b291cb27e%2F4424aa95-b985-4e2f-8755-9507b1037c1c
|
|
34
|
-
* This function replaces %2F with /.
|
|
35
|
-
*/
|
|
36
|
-
function fixArchiveUrl(archiveUrl) {
|
|
37
|
-
const parsed = new url_1.URL(archiveUrl);
|
|
38
|
-
parsed.pathname = decodeURIComponent(parsed.pathname);
|
|
39
|
-
return parsed.toString();
|
|
40
|
-
}
|
|
41
|
-
exports.fixArchiveUrl = fixArchiveUrl;
|
package/build/uploads.d.ts
CHANGED
|
@@ -2,8 +2,14 @@ import { Response } from 'node-fetch';
|
|
|
2
2
|
import { UploadSessionType } from './graphql/generated';
|
|
3
3
|
import { PresignedPost } from './graphql/mutations/UploadSessionMutation';
|
|
4
4
|
import { ProgressHandler } from './utils/progress';
|
|
5
|
-
export declare function
|
|
6
|
-
|
|
5
|
+
export declare function uploadFileAtPathToS3Async(type: UploadSessionType, path: string, handleProgressEvent: ProgressHandler): Promise<{
|
|
6
|
+
url: string;
|
|
7
7
|
bucketKey: string;
|
|
8
8
|
}>;
|
|
9
9
|
export declare function uploadWithPresignedPostAsync(file: string, presignedPost: PresignedPost, handleProgressEvent?: ProgressHandler): Promise<Response>;
|
|
10
|
+
/**
|
|
11
|
+
* S3 returns broken URLs, sth like:
|
|
12
|
+
* https://submission-service-archives.s3.amazonaws.com/production%2Fdc98ca84-1473-4cb3-ae81-8c7b291cb27e%2F4424aa95-b985-4e2f-8755-9507b1037c1c
|
|
13
|
+
* This function replaces %2F with /.
|
|
14
|
+
*/
|
|
15
|
+
export declare function fixS3Url(archiveUrl: string): string;
|
package/build/uploads.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uploadWithPresignedPostAsync = exports.
|
|
3
|
+
exports.fixS3Url = exports.uploadWithPresignedPostAsync = exports.uploadFileAtPathToS3Async = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
const form_data_1 = tslib_1.__importDefault(require("form-data"));
|
|
7
7
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
8
|
+
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
|
|
9
|
+
const url_1 = require("url");
|
|
8
10
|
const fetch_1 = tslib_1.__importDefault(require("./fetch"));
|
|
9
11
|
const UploadSessionMutation_1 = require("./graphql/mutations/UploadSessionMutation");
|
|
10
|
-
async function
|
|
12
|
+
async function uploadFileAtPathToS3Async(type, path, handleProgressEvent) {
|
|
11
13
|
const presignedPost = await UploadSessionMutation_1.UploadSessionMutation.createUploadSessionAsync(type);
|
|
12
14
|
(0, assert_1.default)(presignedPost.fields.key, 'key is not specified in in presigned post');
|
|
13
15
|
const response = await uploadWithPresignedPostAsync(path, presignedPost, handleProgressEvent);
|
|
14
|
-
|
|
16
|
+
const location = (0, nullthrows_1.default)(response.headers.get('location'), `location does not exist in response headers (make sure you're uploading to AWS S3)`);
|
|
17
|
+
const url = fixS3Url(location);
|
|
18
|
+
return { url, bucketKey: presignedPost.fields.key };
|
|
15
19
|
}
|
|
16
|
-
exports.
|
|
20
|
+
exports.uploadFileAtPathToS3Async = uploadFileAtPathToS3Async;
|
|
17
21
|
async function uploadWithPresignedPostAsync(file, presignedPost, handleProgressEvent) {
|
|
18
22
|
const fileStat = await fs_extra_1.default.stat(file);
|
|
19
23
|
const fileSize = fileStat.size;
|
|
@@ -57,3 +61,14 @@ async function uploadWithPresignedPostAsync(file, presignedPost, handleProgressE
|
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
exports.uploadWithPresignedPostAsync = uploadWithPresignedPostAsync;
|
|
64
|
+
/**
|
|
65
|
+
* S3 returns broken URLs, sth like:
|
|
66
|
+
* https://submission-service-archives.s3.amazonaws.com/production%2Fdc98ca84-1473-4cb3-ae81-8c7b291cb27e%2F4424aa95-b985-4e2f-8755-9507b1037c1c
|
|
67
|
+
* This function replaces %2F with /.
|
|
68
|
+
*/
|
|
69
|
+
function fixS3Url(archiveUrl) {
|
|
70
|
+
const parsed = new url_1.URL(archiveUrl);
|
|
71
|
+
parsed.pathname = decodeURIComponent(parsed.pathname);
|
|
72
|
+
return parsed.toString();
|
|
73
|
+
}
|
|
74
|
+
exports.fixS3Url = fixS3Url;
|