eas-cli 3.6.0 → 3.7.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 +52 -102
- package/build/analytics/AnalyticsManager.js +2 -1
- package/build/build/android/build.js +2 -1
- package/build/build/android/graphql.js +2 -0
- package/build/build/android/prepareJob.js +15 -6
- package/build/build/graphql.d.ts +1 -1
- package/build/build/graphql.js +8 -1
- package/build/build/ios/credentials.js +2 -1
- package/build/build/ios/graphql.js +3 -1
- package/build/build/ios/prepareJob.js +29 -19
- package/build/build/metadata.js +1 -0
- package/build/build/queries.js +19 -9
- package/build/build/runBuildAndSubmit.js +2 -0
- package/build/build/utils/printBuildInfo.d.ts +1 -1
- package/build/build/utils/printBuildInfo.js +43 -11
- package/build/build/utils/url.d.ts +1 -1
- package/build/build/utils/url.js +2 -2
- package/build/commandUtils/context/contextUtils/getProjectIdAsync.js +7 -1
- package/build/commands/build/index.js +6 -0
- package/build/commands/update/index.js +21 -4
- package/build/graphql/generated.d.ts +37 -45
- package/build/graphql/generated.js +3 -0
- package/build/log.d.ts +2 -1
- package/build/log.js +2 -2
- package/build/project/android/gradleUtils.js +1 -1
- package/build/project/customBuildConfig.d.ts +4 -0
- package/build/project/customBuildConfig.js +22 -0
- package/build/project/publish.d.ts +22 -0
- package/build/project/publish.js +51 -6
- package/build/submit/ArchiveSource.js +21 -12
- package/oclif.manifest.json +1 -1
- package/package.json +6 -5
|
@@ -6,6 +6,7 @@ const eas_build_job_1 = require("@expo/eas-build-job");
|
|
|
6
6
|
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
|
|
7
7
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
8
8
|
const slash_1 = tslib_1.__importDefault(require("slash"));
|
|
9
|
+
const customBuildConfig_1 = require("../../project/customBuildConfig");
|
|
9
10
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
10
11
|
const vcs_1 = require("../../vcs");
|
|
11
12
|
const cacheDefaults = {
|
|
@@ -15,8 +16,9 @@ const cacheDefaults = {
|
|
|
15
16
|
};
|
|
16
17
|
async function prepareJobAsync(ctx, jobData) {
|
|
17
18
|
var _a;
|
|
18
|
-
const projectRootDirectory = (0, slash_1.default)(path_1.default.relative(await (0, vcs_1.getVcsClient)().getRootPathAsync(), ctx.projectDir)) || '.';
|
|
19
19
|
const username = (0, projectUtils_1.getUsername)(ctx.exp, ctx.user);
|
|
20
|
+
const buildProfile = ctx.buildProfile;
|
|
21
|
+
const projectRootDirectory = (0, slash_1.default)(path_1.default.relative(await (0, vcs_1.getVcsClient)().getRootPathAsync(), ctx.projectDir)) || '.';
|
|
20
22
|
const buildCredentials = {};
|
|
21
23
|
if (jobData.credentials) {
|
|
22
24
|
const targetNames = Object.keys(jobData.credentials);
|
|
@@ -24,37 +26,40 @@ async function prepareJobAsync(ctx, jobData) {
|
|
|
24
26
|
buildCredentials[targetName] = prepareTargetCredentials(jobData.credentials[targetName]);
|
|
25
27
|
}
|
|
26
28
|
}
|
|
29
|
+
const maybeCustomBuildConfigPath = buildProfile.config
|
|
30
|
+
? (0, customBuildConfig_1.getCustomBuildConfigPath)(buildProfile.config)
|
|
31
|
+
: undefined;
|
|
27
32
|
const job = {
|
|
28
33
|
type: ctx.workflow,
|
|
29
34
|
platform: eas_build_job_1.Platform.IOS,
|
|
30
35
|
projectArchive: jobData.projectArchive,
|
|
31
36
|
projectRootDirectory,
|
|
32
37
|
builderEnvironment: {
|
|
33
|
-
image:
|
|
34
|
-
node:
|
|
35
|
-
yarn:
|
|
36
|
-
bundler:
|
|
37
|
-
cocoapods:
|
|
38
|
-
fastlane:
|
|
39
|
-
expoCli:
|
|
40
|
-
env:
|
|
38
|
+
image: buildProfile.image,
|
|
39
|
+
node: buildProfile.node,
|
|
40
|
+
yarn: buildProfile.yarn,
|
|
41
|
+
bundler: buildProfile.bundler,
|
|
42
|
+
cocoapods: buildProfile.cocoapods,
|
|
43
|
+
fastlane: buildProfile.fastlane,
|
|
44
|
+
expoCli: buildProfile.expoCli,
|
|
45
|
+
env: buildProfile.env,
|
|
41
46
|
},
|
|
42
47
|
cache: {
|
|
43
48
|
...cacheDefaults,
|
|
44
|
-
...
|
|
49
|
+
...buildProfile.cache,
|
|
45
50
|
clear: ctx.clearCache,
|
|
46
51
|
},
|
|
47
52
|
secrets: {
|
|
48
53
|
buildCredentials,
|
|
49
54
|
},
|
|
50
|
-
releaseChannel:
|
|
51
|
-
updates: { channel:
|
|
52
|
-
developmentClient:
|
|
53
|
-
simulator:
|
|
55
|
+
releaseChannel: buildProfile.releaseChannel,
|
|
56
|
+
updates: { channel: buildProfile.channel },
|
|
57
|
+
developmentClient: buildProfile.developmentClient,
|
|
58
|
+
simulator: buildProfile.simulator,
|
|
54
59
|
scheme: jobData.buildScheme,
|
|
55
|
-
buildConfiguration:
|
|
56
|
-
applicationArchivePath: (_a =
|
|
57
|
-
buildArtifactPaths:
|
|
60
|
+
buildConfiguration: buildProfile.buildConfiguration,
|
|
61
|
+
applicationArchivePath: (_a = buildProfile.applicationArchivePath) !== null && _a !== void 0 ? _a : buildProfile.artifactPath,
|
|
62
|
+
buildArtifactPaths: buildProfile.buildArtifactPaths,
|
|
58
63
|
username,
|
|
59
64
|
...(ctx.ios.buildNumberOverride && {
|
|
60
65
|
version: {
|
|
@@ -62,10 +67,15 @@ async function prepareJobAsync(ctx, jobData) {
|
|
|
62
67
|
},
|
|
63
68
|
}),
|
|
64
69
|
experimental: {
|
|
65
|
-
prebuildCommand:
|
|
70
|
+
prebuildCommand: buildProfile.prebuildCommand,
|
|
66
71
|
},
|
|
67
|
-
mode: eas_build_job_1.BuildMode.BUILD,
|
|
72
|
+
mode: buildProfile.config ? eas_build_job_1.BuildMode.CUSTOM : eas_build_job_1.BuildMode.BUILD,
|
|
68
73
|
triggeredBy: eas_build_job_1.BuildTrigger.EAS_CLI,
|
|
74
|
+
...(maybeCustomBuildConfigPath && {
|
|
75
|
+
customBuildConfig: {
|
|
76
|
+
path: maybeCustomBuildConfigPath,
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
69
79
|
};
|
|
70
80
|
return (0, eas_build_job_1.sanitizeJob)(job);
|
|
71
81
|
}
|
package/build/build/metadata.js
CHANGED
|
@@ -45,6 +45,7 @@ async function collectMetadataAsync(ctx) {
|
|
|
45
45
|
}),
|
|
46
46
|
runWithNoWaitFlag: ctx.noWait,
|
|
47
47
|
runFromCI: ctx.runFromCI,
|
|
48
|
+
buildMode: ctx.buildProfile.config ? eas_build_job_1.BuildMode.CUSTOM : eas_build_job_1.BuildMode.BUILD,
|
|
48
49
|
};
|
|
49
50
|
return (0, eas_build_job_1.sanitizeMetadata)(metadata);
|
|
50
51
|
}
|
package/build/build/queries.js
CHANGED
|
@@ -66,23 +66,33 @@ async function listAndSelectBuildOnAppAsync(graphqlClient, { projectId, title, f
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
exports.listAndSelectBuildOnAppAsync = listAndSelectBuildOnAppAsync;
|
|
69
|
-
function formatBuildChoiceValue(value) {
|
|
70
|
-
return value ? chalk_1.default.bold(value) : 'Unknown';
|
|
71
|
-
}
|
|
72
69
|
function createBuildToPartialChoiceMaker(selectPromptDisabledFunction) {
|
|
73
70
|
return (build) => {
|
|
74
71
|
var _a;
|
|
75
72
|
const splitCommitMessage = (_a = build.gitCommitMessage) === null || _a === void 0 ? void 0 : _a.split('\n');
|
|
76
73
|
const formattedCommitData = build.gitCommitHash && splitCommitMessage && splitCommitMessage.length > 0
|
|
77
74
|
? `${build.gitCommitHash.slice(0, 7)} "${chalk_1.default.bold(splitCommitMessage[0] + (splitCommitMessage.length > 1 ? '…' : ''))}"`
|
|
78
|
-
:
|
|
75
|
+
: null;
|
|
76
|
+
const descriptionItems = [
|
|
77
|
+
{ name: 'Version', value: build.appVersion ? chalk_1.default.bold(build.appVersion) : null },
|
|
78
|
+
{ name: 'Commit', value: formattedCommitData },
|
|
79
|
+
{
|
|
80
|
+
name: 'Message',
|
|
81
|
+
value: build.message
|
|
82
|
+
? chalk_1.default.bold(build.message.length > 200 ? `${build.message.slice(0, 200)}...` : build.message)
|
|
83
|
+
: null,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: build.platform === generated_1.AppPlatform.Ios ? 'Build number' : 'Version code',
|
|
87
|
+
value: build.appBuildVersion ? chalk_1.default.bold(build.appBuildVersion) : null,
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
const filteredDescriptionArray = descriptionItems
|
|
91
|
+
.filter(item => item.value)
|
|
92
|
+
.map(item => `${chalk_1.default.bold(item.name)}: ${item.value}`);
|
|
79
93
|
return {
|
|
80
94
|
title: `${chalk_1.default.bold(`ID:`)} ${build.id} (${chalk_1.default.bold(`${(0, date_1.fromNow)(new Date(build.completedAt))} ago`)})`,
|
|
81
|
-
description:
|
|
82
|
-
`\t${chalk_1.default.bold(`Version:`)} ${formatBuildChoiceValue(build.appVersion)}`,
|
|
83
|
-
`\t${chalk_1.default.bold(build.platform === generated_1.AppPlatform.Ios ? 'Build number:' : 'Version code:')} ${formatBuildChoiceValue(build.appBuildVersion)}`,
|
|
84
|
-
`\t${chalk_1.default.bold(`Commit:`)} ${formattedCommitData}`,
|
|
85
|
-
].join('\n'),
|
|
95
|
+
description: filteredDescriptionArray.length > 0 ? filteredDescriptionArray.join('\n') : '',
|
|
86
96
|
disabled: selectPromptDisabledFunction === null || selectPromptDisabledFunction === void 0 ? void 0 : selectPromptDisabledFunction(build),
|
|
87
97
|
};
|
|
88
98
|
};
|
|
@@ -12,6 +12,7 @@ const BuildQuery_1 = require("../graphql/queries/BuildQuery");
|
|
|
12
12
|
const AppPlatform_1 = require("../graphql/types/AppPlatform");
|
|
13
13
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
14
14
|
const platform_1 = require("../platform");
|
|
15
|
+
const customBuildConfig_1 = require("../project/customBuildConfig");
|
|
15
16
|
const expoSdk_1 = require("../project/expoSdk");
|
|
16
17
|
const metroConfig_1 = require("../project/metroConfig");
|
|
17
18
|
const projectUtils_1 = require("../project/projectUtils");
|
|
@@ -62,6 +63,7 @@ async function runBuildAndSubmitAsync(graphqlClient, analytics, projectDir, flag
|
|
|
62
63
|
});
|
|
63
64
|
for (const buildProfile of buildProfiles) {
|
|
64
65
|
(0, remoteVersionSource_1.validateBuildProfileVersionSettings)(buildProfile, easJsonCliConfig);
|
|
66
|
+
await (0, customBuildConfig_1.validateCustomBuildConfigAsync)(projectDir, buildProfile.profile);
|
|
65
67
|
}
|
|
66
68
|
const startedBuilds = [];
|
|
67
69
|
const buildCtxByPlatform = {};
|
|
@@ -2,4 +2,4 @@ import { BuildError, BuildFragment, EasBuildDeprecationInfo } from '../../graphq
|
|
|
2
2
|
export declare function printLogsUrls(builds: BuildFragment[]): void;
|
|
3
3
|
export declare function printBuildResults(builds: (BuildFragment | null)[]): void;
|
|
4
4
|
export declare function printDeprecationWarnings(deprecationInfo?: EasBuildDeprecationInfo | null): void;
|
|
5
|
-
export declare function printUserError(error: BuildError): void;
|
|
5
|
+
export declare function printUserError(error: BuildError, build: BuildFragment): void;
|
|
@@ -9,6 +9,22 @@ const generated_1 = require("../../graphql/generated");
|
|
|
9
9
|
const log_1 = tslib_1.__importStar(require("../../log"));
|
|
10
10
|
const platform_1 = require("../../platform");
|
|
11
11
|
const url_1 = require("./url");
|
|
12
|
+
function terminalLinkFallback(url, text) {
|
|
13
|
+
return `${text} (${url})`;
|
|
14
|
+
}
|
|
15
|
+
const errorCodeToErrorMessageOverride = {
|
|
16
|
+
EAS_BUILD_UNKNOWN_FASTLANE_ERROR: build => `The ${(0, log_1.link)((0, url_1.getBuildLogsUrl)(build, 'run-fastlane'), {
|
|
17
|
+
text: '"Run fastlane"',
|
|
18
|
+
fallback: terminalLinkFallback((0, url_1.getBuildLogsUrl)(build, 'run-fastlane'), '"Run fastlane"'),
|
|
19
|
+
})} step failed with an unknown error. Refer to the ${(0, log_1.link)((0, url_1.getBuildLogsUrl)(build, 'xcode-logs'), {
|
|
20
|
+
text: '"Xcode logs"',
|
|
21
|
+
fallback: terminalLinkFallback((0, url_1.getBuildLogsUrl)(build, 'xcode-logs'), '"Xcode logs"'),
|
|
22
|
+
})} phase for additional, more detailed logs`,
|
|
23
|
+
EAS_BUILD_UNKNOWN_GRADLE_ERROR: build => `Gradle build failed with unknown error. See logs for the ${(0, log_1.link)((0, url_1.getBuildLogsUrl)(build, 'run-gradlew'), {
|
|
24
|
+
text: '"Run gradlew"',
|
|
25
|
+
fallback: terminalLinkFallback((0, url_1.getBuildLogsUrl)(build, 'run-gradlew'), '"Run gradlew"'),
|
|
26
|
+
})} phase for more information.`,
|
|
27
|
+
};
|
|
12
28
|
function printLogsUrls(builds) {
|
|
13
29
|
if (builds.length === 1) {
|
|
14
30
|
log_1.default.log(`Build details: ${(0, log_1.link)((0, url_1.getBuildLogsUrl)(builds[0]))}`);
|
|
@@ -22,7 +38,6 @@ function printLogsUrls(builds) {
|
|
|
22
38
|
}
|
|
23
39
|
exports.printLogsUrls = printLogsUrls;
|
|
24
40
|
function printBuildResults(builds) {
|
|
25
|
-
log_1.default.newLine();
|
|
26
41
|
if (builds.length === 1) {
|
|
27
42
|
const [build] = builds;
|
|
28
43
|
(0, assert_1.default)(build, 'Build should be defined');
|
|
@@ -34,21 +49,23 @@ function printBuildResults(builds) {
|
|
|
34
49
|
}
|
|
35
50
|
exports.printBuildResults = printBuildResults;
|
|
36
51
|
function printBuildResult(build) {
|
|
37
|
-
var _a
|
|
38
|
-
log_1.default.addNewLineIfNone();
|
|
52
|
+
var _a;
|
|
39
53
|
if (build.status === generated_1.BuildStatus.Errored) {
|
|
54
|
+
log_1.default.addNewLineIfNone();
|
|
40
55
|
const userError = build.error;
|
|
41
56
|
log_1.default.error(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} build failed${userError ? ':' : ''}`);
|
|
42
57
|
if (userError) {
|
|
43
|
-
printUserError(userError);
|
|
58
|
+
printUserError(userError, build);
|
|
44
59
|
}
|
|
45
60
|
return;
|
|
46
61
|
}
|
|
47
62
|
if (build.status === generated_1.BuildStatus.Canceled) {
|
|
63
|
+
log_1.default.addNewLineIfNone();
|
|
48
64
|
log_1.default.error(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} build was canceled`);
|
|
49
65
|
return;
|
|
50
66
|
}
|
|
51
67
|
if (build.distribution === generated_1.DistributionType.Internal) {
|
|
68
|
+
log_1.default.addNewLineIfNone();
|
|
52
69
|
const logsUrl = (0, url_1.getBuildLogsUrl)(build);
|
|
53
70
|
// It's tricky to install the .apk file directly on Android so let's fallback
|
|
54
71
|
// to the build details page and let people press the button to download there
|
|
@@ -60,9 +77,12 @@ function printBuildResult(build) {
|
|
|
60
77
|
else {
|
|
61
78
|
// TODO: it looks like buildUrl could possibly be undefined, based on the code below.
|
|
62
79
|
// we should account for this case better if it is possible
|
|
63
|
-
const url = (
|
|
64
|
-
|
|
65
|
-
|
|
80
|
+
const url = (_a = build.artifacts) === null || _a === void 0 ? void 0 : _a.buildUrl;
|
|
81
|
+
if (url) {
|
|
82
|
+
log_1.default.addNewLineIfNone();
|
|
83
|
+
log_1.default.log(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} app:`);
|
|
84
|
+
log_1.default.log((0, log_1.link)(url));
|
|
85
|
+
}
|
|
66
86
|
}
|
|
67
87
|
}
|
|
68
88
|
function printDeprecationWarnings(deprecationInfo) {
|
|
@@ -84,10 +104,22 @@ function printDeprecationWarnings(deprecationInfo) {
|
|
|
84
104
|
}
|
|
85
105
|
}
|
|
86
106
|
exports.printDeprecationWarnings = printDeprecationWarnings;
|
|
87
|
-
function printUserError(error) {
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
log_1.default.error(
|
|
107
|
+
function printUserError(error, build) {
|
|
108
|
+
const maybeErrorMessageOverride = maybeGetErrorMessageOverride(error, build);
|
|
109
|
+
if (maybeErrorMessageOverride) {
|
|
110
|
+
log_1.default.error(maybeErrorMessageOverride);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
log_1.default.error(error.message);
|
|
114
|
+
if (error.docsUrl) {
|
|
115
|
+
log_1.default.error((0, log_1.learnMore)(error.docsUrl, { dim: false }));
|
|
116
|
+
}
|
|
91
117
|
}
|
|
92
118
|
}
|
|
93
119
|
exports.printUserError = printUserError;
|
|
120
|
+
function maybeGetErrorMessageOverride(error, build) {
|
|
121
|
+
if (!(error.errorCode in errorCodeToErrorMessageOverride)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return errorCodeToErrorMessageOverride[error.errorCode](build);
|
|
125
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BuildFragment } from '../../graphql/generated';
|
|
2
2
|
export declare function getProjectDashboardUrl(accountName: string, projectName: string): string;
|
|
3
|
-
export declare function getBuildLogsUrl(build: BuildFragment): string;
|
|
3
|
+
export declare function getBuildLogsUrl(build: BuildFragment, hash?: string): string;
|
|
4
4
|
export declare function getArtifactUrl(artifactId: string): string;
|
|
5
5
|
export declare function getInternalDistributionInstallUrl(build: BuildFragment): string;
|
|
6
6
|
export declare function getUpdateGroupUrl(accountName: string, projectName: string, updateGroupId: string): string;
|
package/build/build/utils/url.js
CHANGED
|
@@ -9,11 +9,11 @@ function getProjectDashboardUrl(accountName, projectName) {
|
|
|
9
9
|
return new URL(`/accounts/${accountName}/projects/${projectName}`, (0, api_1.getExpoWebsiteBaseUrl)()).toString();
|
|
10
10
|
}
|
|
11
11
|
exports.getProjectDashboardUrl = getProjectDashboardUrl;
|
|
12
|
-
function getBuildLogsUrl(build) {
|
|
12
|
+
function getBuildLogsUrl(build, hash) {
|
|
13
13
|
const { project } = build;
|
|
14
14
|
const url = project.__typename !== 'App'
|
|
15
15
|
? `/builds/${build.id}`
|
|
16
|
-
: `/accounts/${project.ownerAccount.name}/projects/${project.slug}/builds/${build.id}`;
|
|
16
|
+
: `/accounts/${project.ownerAccount.name}/projects/${project.slug}/builds/${build.id}${hash ? `#${hash}` : ''}`;
|
|
17
17
|
return new URL(url, (0, api_1.getExpoWebsiteBaseUrl)()).toString();
|
|
18
18
|
}
|
|
19
19
|
exports.getBuildLogsUrl = getBuildLogsUrl;
|
|
@@ -73,7 +73,13 @@ async function getProjectIdAsync(sessionManager, exp, options) {
|
|
|
73
73
|
}
|
|
74
74
|
const actorUsername = (0, User_1.getActorUsername)(actor);
|
|
75
75
|
if (!exp.owner && appForProjectId.ownerAccount.name !== actorUsername) {
|
|
76
|
-
|
|
76
|
+
if (actorUsername) {
|
|
77
|
+
throw new Error(`Project config: Owner of project identified by "extra.eas.projectId" (${appForProjectId.ownerAccount.name}) does not match the logged in user (${actorUsername}) and the "owner" field is not specified. To ensure all libraries work correctly, "owner": "${appForProjectId.ownerAccount.name}" should be added to the project config, which can be done automatically by re-running "eas init". ${(0, log_1.learnMore)('https://expo.fyi/eas-project-id')}`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// robot caller
|
|
81
|
+
throw new Error(`Project config: Owner of project identified by "extra.eas.projectId" (${appForProjectId.ownerAccount.name}) must be specified in "owner" field when using a robot access token. To ensure all libraries work correctly, "owner": "${appForProjectId.ownerAccount.name}" should be added to the project config, which can be done automatically by re-running "eas init". ${(0, log_1.learnMore)('https://expo.fyi/eas-project-id')}`);
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
if (exp.slug && exp.slug !== appForProjectId.slug) {
|
|
79
85
|
throw new Error(`Project config: Slug for project identified by "extra.eas.projectId" (${appForProjectId.slug}) does not match the "slug" field (${exp.slug}). ${(0, log_1.learnMore)('https://expo.fyi/eas-project-id')}`);
|
|
@@ -104,6 +104,12 @@ class Build extends EasCommand_1.default {
|
|
|
104
104
|
else if (process.platform !== 'darwin' && requestedPlatform === platform_1.RequestedPlatform.Ios) {
|
|
105
105
|
core_1.Errors.error('Unsupported platform, macOS is required to build apps for iOS', { exit: 1 });
|
|
106
106
|
}
|
|
107
|
+
else if (!['linux', 'darwin'].includes(process.platform) &&
|
|
108
|
+
requestedPlatform === platform_1.RequestedPlatform.Android) {
|
|
109
|
+
core_1.Errors.error('Unsupported platform, macOS or Linux is required to build apps for Android', {
|
|
110
|
+
exit: 1,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
107
113
|
}
|
|
108
114
|
return {
|
|
109
115
|
...flags,
|
|
@@ -164,10 +164,27 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
164
164
|
uploadedAssetCount = uploadResults.uniqueUploadedAssetCount;
|
|
165
165
|
assetLimitPerUpdateGroup = uploadResults.assetLimitPerUpdateGroup;
|
|
166
166
|
unsortedUpdateInfoGroups = await (0, publish_1.buildUnsortedUpdateInfoGroupAsync)(assets, exp);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
// NOTE(cedric): we assume that bundles are always uploaded, and always are part of
|
|
168
|
+
// `uploadedAssetCount`, perferably we don't assume. For that, we need to refactor the
|
|
169
|
+
// `uploadAssetsAsync` and be able to determine asset type from the uploaded assets.
|
|
170
|
+
const uploadedBundleCount = uploadResults.launchAssetCount;
|
|
171
|
+
const uploadedNormalAssetCount = Math.max(0, uploadedAssetCount - uploadedBundleCount);
|
|
172
|
+
const reusedNormalAssetCount = uploadResults.uniqueAssetCount - uploadedNormalAssetCount;
|
|
173
|
+
assetSpinner.stop();
|
|
174
|
+
log_1.default.withTick(`Uploaded ${uploadedBundleCount} app ${uploadedBundleCount === 1 ? 'bundle' : 'bundles'}`);
|
|
175
|
+
if (uploadedNormalAssetCount === 0) {
|
|
176
|
+
log_1.default.withTick(`Uploading assets skipped - no new assets found`);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
let message = `Uploaded ${uploadedNormalAssetCount} ${uploadedNormalAssetCount === 1 ? 'asset' : 'assets'}`;
|
|
180
|
+
if (reusedNormalAssetCount > 0) {
|
|
181
|
+
message += ` (reused ${reusedNormalAssetCount} ${reusedNormalAssetCount === 1 ? 'asset' : 'assets'})`;
|
|
182
|
+
}
|
|
183
|
+
log_1.default.withTick(message);
|
|
184
|
+
}
|
|
185
|
+
for (const uploadedAssetPath of uploadResults.uniqueUploadedAssetPaths) {
|
|
186
|
+
log_1.default.debug(chalk_1.default.dim(`- ${uploadedAssetPath}`));
|
|
187
|
+
}
|
|
171
188
|
}
|
|
172
189
|
catch (e) {
|
|
173
190
|
assetSpinner.fail('Failed to upload');
|
|
@@ -123,11 +123,15 @@ export type Account = {
|
|
|
123
123
|
subscription?: Maybe<SubscriptionDetails>;
|
|
124
124
|
/** @deprecated No longer needed */
|
|
125
125
|
subscriptionChangesPending?: Maybe<Scalars['Boolean']>;
|
|
126
|
+
/** Coalesced project activity for an app using pagination */
|
|
127
|
+
timelineActivity: TimelineActivityConnection;
|
|
126
128
|
/** @deprecated See isCurrent */
|
|
127
129
|
unlimitedBuilds: Scalars['Boolean'];
|
|
128
130
|
updatedAt: Scalars['DateTime'];
|
|
129
131
|
/** Account query object for querying EAS usage metrics */
|
|
130
132
|
usageMetrics: AccountUsageMetrics;
|
|
133
|
+
/** Owning UserActor of this account if personal account */
|
|
134
|
+
userActorOwner?: Maybe<UserActor>;
|
|
131
135
|
/** Pending user invitations for this account */
|
|
132
136
|
userInvitations: Array<UserInvitation>;
|
|
133
137
|
/** Actors associated with this account and permissions they hold */
|
|
@@ -234,6 +238,17 @@ export type AccountSnacksArgs = {
|
|
|
234
238
|
limit: Scalars['Int'];
|
|
235
239
|
offset: Scalars['Int'];
|
|
236
240
|
};
|
|
241
|
+
/**
|
|
242
|
+
* An account is a container owning projects, credentials, billing and other organization
|
|
243
|
+
* data and settings. Actors may own and be members of accounts.
|
|
244
|
+
*/
|
|
245
|
+
export type AccountTimelineActivityArgs = {
|
|
246
|
+
after?: InputMaybe<Scalars['String']>;
|
|
247
|
+
before?: InputMaybe<Scalars['String']>;
|
|
248
|
+
filter?: InputMaybe<TimelineActivityFilterInput>;
|
|
249
|
+
first?: InputMaybe<Scalars['Int']>;
|
|
250
|
+
last?: InputMaybe<Scalars['Int']>;
|
|
251
|
+
};
|
|
237
252
|
export type AccountDataInput = {
|
|
238
253
|
name: Scalars['String'];
|
|
239
254
|
};
|
|
@@ -666,6 +681,7 @@ export type AndroidJobInput = {
|
|
|
666
681
|
buildType?: InputMaybe<AndroidBuildType>;
|
|
667
682
|
builderEnvironment?: InputMaybe<AndroidBuilderEnvironmentInput>;
|
|
668
683
|
cache?: InputMaybe<BuildCacheInput>;
|
|
684
|
+
customBuildConfig?: InputMaybe<CustomBuildConfigInput>;
|
|
669
685
|
developmentClient?: InputMaybe<Scalars['Boolean']>;
|
|
670
686
|
experimental?: InputMaybe<Scalars['JSONObject']>;
|
|
671
687
|
gradleCommand?: InputMaybe<Scalars['String']>;
|
|
@@ -794,10 +810,8 @@ export type App = Project & {
|
|
|
794
810
|
/** Classic update release channel names that have at least one build */
|
|
795
811
|
buildsReleaseChannels: Array<Scalars['String']>;
|
|
796
812
|
deployment?: Maybe<Deployment>;
|
|
797
|
-
deploymentNew?: Maybe<DeploymentNew>;
|
|
798
813
|
/** Deployments associated with this app */
|
|
799
|
-
deployments:
|
|
800
|
-
deploymentsNew: DeploymentsConnection;
|
|
814
|
+
deployments: DeploymentsConnection;
|
|
801
815
|
description: Scalars['String'];
|
|
802
816
|
/** Environment secrets for an app */
|
|
803
817
|
environmentSecrets: Array<EnvironmentSecret>;
|
|
@@ -909,23 +923,11 @@ export type AppBuildsArgs = {
|
|
|
909
923
|
};
|
|
910
924
|
/** Represents an Exponent App (or Experience in legacy terms) */
|
|
911
925
|
export type AppDeploymentArgs = {
|
|
912
|
-
channel: Scalars['String'];
|
|
913
|
-
options?: InputMaybe<DeploymentOptions>;
|
|
914
|
-
runtimeVersion: Scalars['String'];
|
|
915
|
-
};
|
|
916
|
-
/** Represents an Exponent App (or Experience in legacy terms) */
|
|
917
|
-
export type AppDeploymentNewArgs = {
|
|
918
926
|
channel: Scalars['String'];
|
|
919
927
|
runtimeVersion: Scalars['String'];
|
|
920
928
|
};
|
|
921
929
|
/** Represents an Exponent App (or Experience in legacy terms) */
|
|
922
930
|
export type AppDeploymentsArgs = {
|
|
923
|
-
limit: Scalars['Int'];
|
|
924
|
-
mostRecentlyUpdatedAt?: InputMaybe<Scalars['DateTime']>;
|
|
925
|
-
options?: InputMaybe<DeploymentOptions>;
|
|
926
|
-
};
|
|
927
|
-
/** Represents an Exponent App (or Experience in legacy terms) */
|
|
928
|
-
export type AppDeploymentsNewArgs = {
|
|
929
931
|
after?: InputMaybe<Scalars['String']>;
|
|
930
932
|
before?: InputMaybe<Scalars['String']>;
|
|
931
933
|
first?: InputMaybe<Scalars['Int']>;
|
|
@@ -1606,6 +1608,7 @@ export declare enum BuildIosEnterpriseProvisioning {
|
|
|
1606
1608
|
/** Represents an Standalone App build job */
|
|
1607
1609
|
export type BuildJob = ActivityTimelineProjectActivity & BuildOrBuildJob & {
|
|
1608
1610
|
__typename?: 'BuildJob';
|
|
1611
|
+
accountUserActor?: Maybe<UserActor>;
|
|
1609
1612
|
activityTimestamp: Scalars['DateTime'];
|
|
1610
1613
|
actor?: Maybe<Actor>;
|
|
1611
1614
|
app?: Maybe<App>;
|
|
@@ -1701,6 +1704,7 @@ export type BuildMetrics = {
|
|
|
1701
1704
|
};
|
|
1702
1705
|
export declare enum BuildMode {
|
|
1703
1706
|
Build = "BUILD",
|
|
1707
|
+
Custom = "CUSTOM",
|
|
1704
1708
|
Resign = "RESIGN"
|
|
1705
1709
|
}
|
|
1706
1710
|
export type BuildMutation = {
|
|
@@ -1846,6 +1850,8 @@ export declare enum BuildResourceClass {
|
|
|
1846
1850
|
IosLarge = "IOS_LARGE",
|
|
1847
1851
|
IosM1Large = "IOS_M1_LARGE",
|
|
1848
1852
|
IosM1Medium = "IOS_M1_MEDIUM",
|
|
1853
|
+
IosM2Medium = "IOS_M2_MEDIUM",
|
|
1854
|
+
IosM2ProMedium = "IOS_M2_PRO_MEDIUM",
|
|
1849
1855
|
IosMedium = "IOS_MEDIUM",
|
|
1850
1856
|
Legacy = "LEGACY"
|
|
1851
1857
|
}
|
|
@@ -1981,6 +1987,9 @@ export type CreateSubmissionResult = {
|
|
|
1981
1987
|
/** Created submission */
|
|
1982
1988
|
submission: Submission;
|
|
1983
1989
|
};
|
|
1990
|
+
export type CustomBuildConfigInput = {
|
|
1991
|
+
path: Scalars['String'];
|
|
1992
|
+
};
|
|
1984
1993
|
export type DeleteAccessTokenResult = {
|
|
1985
1994
|
__typename?: 'DeleteAccessTokenResult';
|
|
1986
1995
|
id: Scalars['ID'];
|
|
@@ -2052,16 +2061,17 @@ export type DeployServerlessFunctionResult = {
|
|
|
2052
2061
|
/** Represents a Deployment - a set of Builds with the same Runtime Version and Channel */
|
|
2053
2062
|
export type Deployment = {
|
|
2054
2063
|
__typename?: 'Deployment';
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
* The name of this deployment's associated channel. It is specified separately from the `channel`
|
|
2058
|
-
* field to allow specifying a deployment before an EAS Update channel has been created.
|
|
2059
|
-
*/
|
|
2060
|
-
channelName: Scalars['String'];
|
|
2064
|
+
builds: DeploymentBuildsConnection;
|
|
2065
|
+
channel: UpdateChannel;
|
|
2061
2066
|
id: Scalars['ID'];
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2067
|
+
runtime: Runtime;
|
|
2068
|
+
};
|
|
2069
|
+
/** Represents a Deployment - a set of Builds with the same Runtime Version and Channel */
|
|
2070
|
+
export type DeploymentBuildsArgs = {
|
|
2071
|
+
after?: InputMaybe<Scalars['String']>;
|
|
2072
|
+
before?: InputMaybe<Scalars['String']>;
|
|
2073
|
+
first?: InputMaybe<Scalars['Int']>;
|
|
2074
|
+
last?: InputMaybe<Scalars['Int']>;
|
|
2065
2075
|
};
|
|
2066
2076
|
export type DeploymentBuildEdge = {
|
|
2067
2077
|
__typename?: 'DeploymentBuildEdge';
|
|
@@ -2077,28 +2087,9 @@ export type DeploymentBuildsConnection = {
|
|
|
2077
2087
|
export type DeploymentEdge = {
|
|
2078
2088
|
__typename?: 'DeploymentEdge';
|
|
2079
2089
|
cursor: Scalars['String'];
|
|
2080
|
-
node:
|
|
2081
|
-
};
|
|
2082
|
-
/** Represents a Deployment - a set of Builds with the same Runtime Version and Channel */
|
|
2083
|
-
export type DeploymentNew = {
|
|
2084
|
-
__typename?: 'DeploymentNew';
|
|
2085
|
-
builds: DeploymentBuildsConnection;
|
|
2086
|
-
channel: UpdateChannel;
|
|
2087
|
-
id: Scalars['ID'];
|
|
2088
|
-
runtime: Runtime;
|
|
2089
|
-
};
|
|
2090
|
-
/** Represents a Deployment - a set of Builds with the same Runtime Version and Channel */
|
|
2091
|
-
export type DeploymentNewBuildsArgs = {
|
|
2092
|
-
after?: InputMaybe<Scalars['String']>;
|
|
2093
|
-
before?: InputMaybe<Scalars['String']>;
|
|
2094
|
-
first?: InputMaybe<Scalars['Int']>;
|
|
2095
|
-
last?: InputMaybe<Scalars['Int']>;
|
|
2096
|
-
};
|
|
2097
|
-
export type DeploymentOptions = {
|
|
2098
|
-
/** Max number of associated builds to return */
|
|
2099
|
-
buildListMaxSize?: InputMaybe<Scalars['Int']>;
|
|
2090
|
+
node: Deployment;
|
|
2100
2091
|
};
|
|
2101
|
-
/** Represents the connection over the
|
|
2092
|
+
/** Represents the connection over the deployments edge of an App */
|
|
2102
2093
|
export type DeploymentsConnection = {
|
|
2103
2094
|
__typename?: 'DeploymentsConnection';
|
|
2104
2095
|
edges: Array<DeploymentEdge>;
|
|
@@ -2604,6 +2595,7 @@ export type IosJobInput = {
|
|
|
2604
2595
|
buildType?: InputMaybe<IosBuildType>;
|
|
2605
2596
|
builderEnvironment?: InputMaybe<IosBuilderEnvironmentInput>;
|
|
2606
2597
|
cache?: InputMaybe<BuildCacheInput>;
|
|
2598
|
+
customBuildConfig?: InputMaybe<CustomBuildConfigInput>;
|
|
2607
2599
|
developmentClient?: InputMaybe<Scalars['Boolean']>;
|
|
2608
2600
|
/** @deprecated */
|
|
2609
2601
|
distribution?: InputMaybe<DistributionType>;
|
|
@@ -118,6 +118,7 @@ var BuildJobStatus;
|
|
|
118
118
|
var BuildMode;
|
|
119
119
|
(function (BuildMode) {
|
|
120
120
|
BuildMode["Build"] = "BUILD";
|
|
121
|
+
BuildMode["Custom"] = "CUSTOM";
|
|
121
122
|
BuildMode["Resign"] = "RESIGN";
|
|
122
123
|
})(BuildMode = exports.BuildMode || (exports.BuildMode = {}));
|
|
123
124
|
var BuildPriority;
|
|
@@ -137,6 +138,8 @@ var BuildResourceClass;
|
|
|
137
138
|
BuildResourceClass["IosLarge"] = "IOS_LARGE";
|
|
138
139
|
BuildResourceClass["IosM1Large"] = "IOS_M1_LARGE";
|
|
139
140
|
BuildResourceClass["IosM1Medium"] = "IOS_M1_MEDIUM";
|
|
141
|
+
BuildResourceClass["IosM2Medium"] = "IOS_M2_MEDIUM";
|
|
142
|
+
BuildResourceClass["IosM2ProMedium"] = "IOS_M2_PRO_MEDIUM";
|
|
140
143
|
BuildResourceClass["IosMedium"] = "IOS_MEDIUM";
|
|
141
144
|
BuildResourceClass["Legacy"] = "LEGACY";
|
|
142
145
|
})(BuildResourceClass = exports.BuildResourceClass || (exports.BuildResourceClass = {}));
|
package/build/log.d.ts
CHANGED
|
@@ -22,9 +22,10 @@ export default class Log {
|
|
|
22
22
|
*
|
|
23
23
|
* @example https://expo.dev
|
|
24
24
|
*/
|
|
25
|
-
export declare function link(url: string, { text, dim }?: {
|
|
25
|
+
export declare function link(url: string, { text, fallback, dim }?: {
|
|
26
26
|
text?: string;
|
|
27
27
|
dim?: boolean;
|
|
28
|
+
fallback?: string;
|
|
28
29
|
}): string;
|
|
29
30
|
/**
|
|
30
31
|
* Provide a consistent "Learn more" link experience.
|
package/build/log.js
CHANGED
|
@@ -77,10 +77,10 @@ Log.isLastLineNewLine = false;
|
|
|
77
77
|
*
|
|
78
78
|
* @example https://expo.dev
|
|
79
79
|
*/
|
|
80
|
-
function link(url, { text = url, dim = true } = {}) {
|
|
80
|
+
function link(url, { text = url, fallback, dim = true } = {}) {
|
|
81
81
|
// Links can be disabled via env variables https://github.com/jamestalmage/supports-hyperlinks/blob/master/index.js
|
|
82
82
|
const output = (0, terminal_link_1.default)(text, url, {
|
|
83
|
-
fallback: () => (text === url ? chalk_1.default.underline(url) : `${text}: ${chalk_1.default.underline(url)}`),
|
|
83
|
+
fallback: () => fallback !== null && fallback !== void 0 ? fallback : (text === url ? chalk_1.default.underline(url) : `${text}: ${chalk_1.default.underline(url)}`),
|
|
84
84
|
});
|
|
85
85
|
return dim ? chalk_1.default.dim(output) : output;
|
|
86
86
|
}
|
|
@@ -43,7 +43,7 @@ function parseGradleCommand(cmd, buildGradle) {
|
|
|
43
43
|
// separate moduleName and rest of the definition
|
|
44
44
|
const splitCmd = rawCmd.split(':');
|
|
45
45
|
const [moduleName, taskName] = splitCmd.length > 1 ? [splitCmd[0], splitCmd[1]] : [undefined, splitCmd[0]];
|
|
46
|
-
const matchResult = taskName.match(/(build|bundle|assemble)(.*)(Release|Debug)/);
|
|
46
|
+
const matchResult = taskName.match(/(build|bundle|assemble|package)(.*)(Release|Debug)/);
|
|
47
47
|
if (!matchResult) {
|
|
48
48
|
throw new Error(`Failed to parse gradle command: ${cmd}`);
|
|
49
49
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Platform } from '@expo/eas-build-job';
|
|
2
|
+
import { BuildProfile } from '@expo/eas-json';
|
|
3
|
+
export declare function validateCustomBuildConfigAsync(projectDir: string, profile: BuildProfile<Platform>): Promise<void>;
|
|
4
|
+
export declare function getCustomBuildConfigPath(configFilename: string): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCustomBuildConfigPath = exports.validateCustomBuildConfigAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
7
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
8
|
+
async function validateCustomBuildConfigAsync(projectDir, profile) {
|
|
9
|
+
if (!profile.config) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const relativeBuildConfigPath = getCustomBuildConfigPath(profile.config);
|
|
13
|
+
const buildConfigPath = path_1.default.join(projectDir, relativeBuildConfigPath);
|
|
14
|
+
if (!(await fs_extra_1.default.pathExists(buildConfigPath))) {
|
|
15
|
+
throw new Error(`Custom build configuration file ${chalk_1.default.bold(relativeBuildConfigPath)} does not exist.`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.validateCustomBuildConfigAsync = validateCustomBuildConfigAsync;
|
|
19
|
+
function getCustomBuildConfigPath(configFilename) {
|
|
20
|
+
return path_1.default.join('.eas/build', configFilename);
|
|
21
|
+
}
|
|
22
|
+
exports.getCustomBuildConfigPath = getCustomBuildConfigPath;
|