eas-cli 3.6.1 → 3.7.1
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 -52
- 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/runBuildAndSubmit.js +2 -0
- package/build/build/utils/printBuildInfo.js +10 -6
- 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/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/oclif.manifest.json +1 -1
- package/package.json +5 -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
|
}
|
|
@@ -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 = {};
|
|
@@ -38,7 +38,6 @@ function printLogsUrls(builds) {
|
|
|
38
38
|
}
|
|
39
39
|
exports.printLogsUrls = printLogsUrls;
|
|
40
40
|
function printBuildResults(builds) {
|
|
41
|
-
log_1.default.newLine();
|
|
42
41
|
if (builds.length === 1) {
|
|
43
42
|
const [build] = builds;
|
|
44
43
|
(0, assert_1.default)(build, 'Build should be defined');
|
|
@@ -50,9 +49,9 @@ function printBuildResults(builds) {
|
|
|
50
49
|
}
|
|
51
50
|
exports.printBuildResults = printBuildResults;
|
|
52
51
|
function printBuildResult(build) {
|
|
53
|
-
var _a
|
|
54
|
-
log_1.default.addNewLineIfNone();
|
|
52
|
+
var _a;
|
|
55
53
|
if (build.status === generated_1.BuildStatus.Errored) {
|
|
54
|
+
log_1.default.addNewLineIfNone();
|
|
56
55
|
const userError = build.error;
|
|
57
56
|
log_1.default.error(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} build failed${userError ? ':' : ''}`);
|
|
58
57
|
if (userError) {
|
|
@@ -61,10 +60,12 @@ function printBuildResult(build) {
|
|
|
61
60
|
return;
|
|
62
61
|
}
|
|
63
62
|
if (build.status === generated_1.BuildStatus.Canceled) {
|
|
63
|
+
log_1.default.addNewLineIfNone();
|
|
64
64
|
log_1.default.error(`${platform_1.appPlatformEmojis[build.platform]} ${platform_1.appPlatformDisplayNames[build.platform]} build was canceled`);
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
if (build.distribution === generated_1.DistributionType.Internal) {
|
|
68
|
+
log_1.default.addNewLineIfNone();
|
|
68
69
|
const logsUrl = (0, url_1.getBuildLogsUrl)(build);
|
|
69
70
|
// It's tricky to install the .apk file directly on Android so let's fallback
|
|
70
71
|
// to the build details page and let people press the button to download there
|
|
@@ -76,9 +77,12 @@ function printBuildResult(build) {
|
|
|
76
77
|
else {
|
|
77
78
|
// TODO: it looks like buildUrl could possibly be undefined, based on the code below.
|
|
78
79
|
// we should account for this case better if it is possible
|
|
79
|
-
const url = (
|
|
80
|
-
|
|
81
|
-
|
|
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
|
+
}
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
88
|
function printDeprecationWarnings(deprecationInfo) {
|
|
@@ -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 = {}));
|
|
@@ -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;
|
|
@@ -21,6 +21,8 @@ export type RawAsset = {
|
|
|
21
21
|
fileExtension?: string;
|
|
22
22
|
contentType: string;
|
|
23
23
|
path: string;
|
|
24
|
+
/** Original asset path derrived from asset map, or exported folder */
|
|
25
|
+
originalPath?: string;
|
|
24
26
|
};
|
|
25
27
|
type CollectedAssets = {
|
|
26
28
|
[platform in Platform]?: {
|
|
@@ -42,6 +44,11 @@ type ManifestFragment = {
|
|
|
42
44
|
type UpdateInfoGroup = {
|
|
43
45
|
[key in Platform]: ManifestFragment;
|
|
44
46
|
};
|
|
47
|
+
type AssetMap = Record<string, {
|
|
48
|
+
httpServerLocation: string;
|
|
49
|
+
name: string;
|
|
50
|
+
type: string;
|
|
51
|
+
}>;
|
|
45
52
|
export declare const MetadataJoi: Joi.ObjectSchema<any>;
|
|
46
53
|
export declare function guessContentTypeFromExtension(ext?: string): string;
|
|
47
54
|
export declare function getBase64URLEncoding(buffer: Buffer): string;
|
|
@@ -69,6 +76,13 @@ export declare function resolveInputDirectoryAsync(inputDir: string, { skipBundl
|
|
|
69
76
|
}): Promise<string>;
|
|
70
77
|
export declare function loadMetadata(distRoot: string): Metadata;
|
|
71
78
|
export declare function filterExportedPlatformsByFlag<T extends Partial<Record<Platform, any>>>(record: T, platformFlag: ExpoCLIExportPlatformFlag): T;
|
|
79
|
+
/** Try to load the asset map for logging the names of assets published */
|
|
80
|
+
export declare function loadAssetMapAsync(distRoot: string): Promise<AssetMap | null>;
|
|
81
|
+
export declare function getAssetHashFromPath(assetPath: string): string | null;
|
|
82
|
+
export declare function getOriginalPathFromAssetMap(assetMap: AssetMap | null, asset: {
|
|
83
|
+
path: string;
|
|
84
|
+
ext: string;
|
|
85
|
+
}): string | null;
|
|
72
86
|
/** Given a directory, load the metadata.json and collect the assets for each platform. */
|
|
73
87
|
export declare function collectAssetsAsync(dir: string): Promise<CollectedAssets>;
|
|
74
88
|
export declare function filterOutAssetsThatAlreadyExistAsync(graphqlClient: ExpoGraphqlClient, uniqueAssetsWithStorageKey: (RawAsset & {
|
|
@@ -77,9 +91,17 @@ export declare function filterOutAssetsThatAlreadyExistAsync(graphqlClient: Expo
|
|
|
77
91
|
storageKey: string;
|
|
78
92
|
})[]>;
|
|
79
93
|
type AssetUploadResult = {
|
|
94
|
+
/** All found assets within the exported folder per platform */
|
|
80
95
|
assetCount: number;
|
|
96
|
+
/** The uploaded JS bundles, per platform */
|
|
97
|
+
launchAssetCount: number;
|
|
98
|
+
/** All unique assets within the exported folder with platforms combined */
|
|
81
99
|
uniqueAssetCount: number;
|
|
100
|
+
/** All unique assets uploaded */
|
|
82
101
|
uniqueUploadedAssetCount: number;
|
|
102
|
+
/** All (non-launch) asset original paths, used for logging */
|
|
103
|
+
uniqueUploadedAssetPaths: string[];
|
|
104
|
+
/** The asset limit received from the server */
|
|
83
105
|
assetLimitPerUpdateGroup: number;
|
|
84
106
|
};
|
|
85
107
|
export declare function uploadAssetsAsync(graphqlClient: ExpoGraphqlClient, assetsForUpdateInfoGroup: CollectedAssets, projectId: string, updateSpinnerText?: (totalAssets: number, missingAssets: number) => void): Promise<AssetUploadResult>;
|
package/build/project/publish.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.filterExportedPlatformsByFlag = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
|
|
3
|
+
exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.getOriginalPathFromAssetMap = exports.getAssetHashFromPath = exports.loadAssetMapAsync = exports.filterExportedPlatformsByFlag = 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"));
|
|
@@ -16,6 +16,7 @@ const log_1 = tslib_1.__importDefault(require("../log"));
|
|
|
16
16
|
const uploads_1 = require("../uploads");
|
|
17
17
|
const expoCli_1 = require("../utils/expoCli");
|
|
18
18
|
const chunk_1 = tslib_1.__importDefault(require("../utils/expodash/chunk"));
|
|
19
|
+
const filter_1 = require("../utils/expodash/filter");
|
|
19
20
|
const uniqBy_1 = tslib_1.__importDefault(require("../utils/expodash/uniqBy"));
|
|
20
21
|
const fileMetadataJoi = joi_1.default.object({
|
|
21
22
|
assets: joi_1.default.array()
|
|
@@ -115,6 +116,7 @@ async function buildBundlesAsync({ projectDir, inputDir, exp, platformFlag, }) {
|
|
|
115
116
|
'--output-dir',
|
|
116
117
|
inputDir,
|
|
117
118
|
'--dump-sourcemap',
|
|
119
|
+
'--dump-assetmap',
|
|
118
120
|
'--platform',
|
|
119
121
|
platformFlag,
|
|
120
122
|
]);
|
|
@@ -128,6 +130,7 @@ async function buildBundlesAsync({ projectDir, inputDir, exp, platformFlag, }) {
|
|
|
128
130
|
'--experimental-bundle',
|
|
129
131
|
'--non-interactive',
|
|
130
132
|
'--dump-sourcemap',
|
|
133
|
+
'--dump-assetmap',
|
|
131
134
|
'--platform',
|
|
132
135
|
platformFlag,
|
|
133
136
|
]);
|
|
@@ -179,9 +182,42 @@ function filterExportedPlatformsByFlag(record, platformFlag) {
|
|
|
179
182
|
return { [platform]: record[platform] };
|
|
180
183
|
}
|
|
181
184
|
exports.filterExportedPlatformsByFlag = filterExportedPlatformsByFlag;
|
|
185
|
+
/** Try to load the asset map for logging the names of assets published */
|
|
186
|
+
async function loadAssetMapAsync(distRoot) {
|
|
187
|
+
const assetMapPath = path_1.default.join(distRoot, 'assetmap.json');
|
|
188
|
+
if (!(await fs_extra_1.default.pathExists(assetMapPath))) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const assetMap = json_file_1.default.read(path_1.default.join(distRoot, 'assetmap.json'));
|
|
192
|
+
// TODO: basic validation?
|
|
193
|
+
return assetMap;
|
|
194
|
+
}
|
|
195
|
+
exports.loadAssetMapAsync = loadAssetMapAsync;
|
|
196
|
+
// exposed for testing
|
|
197
|
+
function getAssetHashFromPath(assetPath) {
|
|
198
|
+
var _a;
|
|
199
|
+
const [, hash] = (_a = assetPath.match(new RegExp(/assets\/([a-z0-9]+)$/, 'i'))) !== null && _a !== void 0 ? _a : [];
|
|
200
|
+
return hash !== null && hash !== void 0 ? hash : null;
|
|
201
|
+
}
|
|
202
|
+
exports.getAssetHashFromPath = getAssetHashFromPath;
|
|
203
|
+
// exposed for testing
|
|
204
|
+
function getOriginalPathFromAssetMap(assetMap, asset) {
|
|
205
|
+
if (!assetMap) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
const assetHash = getAssetHashFromPath(asset.path);
|
|
209
|
+
const assetMapEntry = assetHash && assetMap[assetHash];
|
|
210
|
+
if (!assetMapEntry) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
const pathPrefix = assetMapEntry.httpServerLocation.substring('/assets'.length);
|
|
214
|
+
return `${pathPrefix}/${assetMapEntry.name}.${assetMapEntry.type}`;
|
|
215
|
+
}
|
|
216
|
+
exports.getOriginalPathFromAssetMap = getOriginalPathFromAssetMap;
|
|
182
217
|
/** Given a directory, load the metadata.json and collect the assets for each platform. */
|
|
183
218
|
async function collectAssetsAsync(dir) {
|
|
184
219
|
const metadata = loadMetadata(dir);
|
|
220
|
+
const assetmap = await loadAssetMapAsync(dir);
|
|
185
221
|
const collectedAssets = {};
|
|
186
222
|
for (const platform of Object.keys(metadata.fileMetadata)) {
|
|
187
223
|
collectedAssets[platform] = {
|
|
@@ -190,11 +226,15 @@ async function collectAssetsAsync(dir) {
|
|
|
190
226
|
contentType: 'application/javascript',
|
|
191
227
|
path: path_1.default.resolve(dir, metadata.fileMetadata[platform].bundle),
|
|
192
228
|
},
|
|
193
|
-
assets: metadata.fileMetadata[platform].assets.map(asset =>
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
229
|
+
assets: metadata.fileMetadata[platform].assets.map(asset => {
|
|
230
|
+
var _a;
|
|
231
|
+
return ({
|
|
232
|
+
fileExtension: asset.ext ? ensureLeadingPeriod(asset.ext) : undefined,
|
|
233
|
+
originalPath: (_a = getOriginalPathFromAssetMap(assetmap, asset)) !== null && _a !== void 0 ? _a : undefined,
|
|
234
|
+
contentType: guessContentTypeFromExtension(asset.ext),
|
|
235
|
+
path: path_1.default.join(dir, asset.path),
|
|
236
|
+
});
|
|
237
|
+
}),
|
|
198
238
|
};
|
|
199
239
|
}
|
|
200
240
|
return collectedAssets;
|
|
@@ -218,7 +258,9 @@ exports.filterOutAssetsThatAlreadyExistAsync = filterOutAssetsThatAlreadyExistAs
|
|
|
218
258
|
async function uploadAssetsAsync(graphqlClient, assetsForUpdateInfoGroup, projectId, updateSpinnerText) {
|
|
219
259
|
let assets = [];
|
|
220
260
|
let platform;
|
|
261
|
+
const launchAssets = [];
|
|
221
262
|
for (platform in assetsForUpdateInfoGroup) {
|
|
263
|
+
launchAssets.push(assetsForUpdateInfoGroup[platform].launchAsset);
|
|
222
264
|
assets = [
|
|
223
265
|
...assets,
|
|
224
266
|
assetsForUpdateInfoGroup[platform].launchAsset,
|
|
@@ -236,6 +278,7 @@ async function uploadAssetsAsync(graphqlClient, assetsForUpdateInfoGroup, projec
|
|
|
236
278
|
updateSpinnerText === null || updateSpinnerText === void 0 ? void 0 : updateSpinnerText(totalAssets, totalAssets);
|
|
237
279
|
let missingAssets = await filterOutAssetsThatAlreadyExistAsync(graphqlClient, uniqueAssets);
|
|
238
280
|
const uniqueUploadedAssetCount = missingAssets.length;
|
|
281
|
+
const uniqueUploadedAssetPaths = missingAssets.map(asset => asset.originalPath).filter(filter_1.truthy);
|
|
239
282
|
const missingAssetChunks = (0, chunk_1.default)(missingAssets, 100);
|
|
240
283
|
const specifications = [];
|
|
241
284
|
for (const missingAssets of missingAssetChunks) {
|
|
@@ -263,8 +306,10 @@ async function uploadAssetsAsync(graphqlClient, assetsForUpdateInfoGroup, projec
|
|
|
263
306
|
}
|
|
264
307
|
return {
|
|
265
308
|
assetCount: assets.length,
|
|
309
|
+
launchAssetCount: launchAssets.length,
|
|
266
310
|
uniqueAssetCount: uniqueAssets.length,
|
|
267
311
|
uniqueUploadedAssetCount,
|
|
312
|
+
uniqueUploadedAssetPaths,
|
|
268
313
|
assetLimitPerUpdateGroup,
|
|
269
314
|
};
|
|
270
315
|
}
|