eas-cli 11.0.3 → 12.1.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 +60 -60
- package/build/build/build.js +8 -45
- package/build/build/configure.js +4 -1
- package/build/build/evaluateConfigWithEnvVarsAsync.d.ts +2 -1
- package/build/build/evaluateConfigWithEnvVarsAsync.js +31 -9
- package/build/build/graphql.d.ts +2 -1
- package/build/build/graphql.js +13 -2
- package/build/build/local.js +1 -1
- package/build/build/runBuildAndSubmit.js +12 -2
- package/build/build/types.d.ts +20 -0
- package/build/commands/build/resign.js +1 -0
- package/build/commands/build/version/get.js +1 -0
- package/build/commands/build/version/set.js +1 -0
- package/build/commands/build/version/sync.js +1 -0
- package/build/commands/config.js +1 -0
- package/build/commands/project/onboarding.js +3 -0
- package/build/commands/update/index.js +22 -5
- package/build/commands/update/roll-back-to-embedded.js +6 -6
- package/build/commands/worker/deploy.d.ts +15 -0
- package/build/commands/worker/deploy.js +181 -0
- package/build/credentials/ios/appstore/bundleIdCapabilities.js +41 -0
- package/build/graphql/generated.d.ts +301 -53
- package/build/graphql/generated.js +72 -12
- package/build/project/maybeUploadFingerprintAsync.d.ts +15 -0
- package/build/project/maybeUploadFingerprintAsync.js +57 -0
- package/build/project/publish.d.ts +16 -11
- package/build/project/publish.js +33 -30
- package/build/project/remoteVersionSource.d.ts +8 -1
- package/build/project/remoteVersionSource.js +94 -5
- package/build/project/resolveRuntimeVersionAsync.d.ts +13 -0
- package/build/project/resolveRuntimeVersionAsync.js +21 -17
- package/build/worker/assets.d.ts +25 -0
- package/build/worker/assets.js +110 -0
- package/build/worker/deployment.d.ts +6 -0
- package/build/worker/deployment.js +57 -0
- package/build/worker/mutations.d.ts +11 -0
- package/build/worker/mutations.js +45 -0
- package/build/worker/upload.d.ts +20 -0
- package/build/worker/upload.js +141 -0
- package/oclif.manifest.json +22 -1
- package/package.json +8 -5
|
@@ -4,25 +4,36 @@ exports.evaluateConfigWithEnvVarsAsync = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const generated_1 = require("../graphql/generated");
|
|
6
6
|
const EnvironmentVariablesQuery_1 = require("../graphql/queries/EnvironmentVariablesQuery");
|
|
7
|
-
const log_1 = tslib_1.
|
|
7
|
+
const log_1 = tslib_1.__importStar(require("../log"));
|
|
8
8
|
function isEnvironment(env) {
|
|
9
|
-
return Object.values(generated_1.EnvironmentVariableEnvironment).includes(env
|
|
9
|
+
return Object.values(generated_1.EnvironmentVariableEnvironment).includes(env);
|
|
10
10
|
}
|
|
11
|
-
async function evaluateConfigWithEnvVarsAsync({ flags, buildProfile, graphqlClient, getProjectConfig, opts, }) {
|
|
11
|
+
async function evaluateConfigWithEnvVarsAsync({ flags, buildProfile, buildProfileName, graphqlClient, getProjectConfig, opts, }) {
|
|
12
12
|
if (!graphqlClient) {
|
|
13
13
|
log_1.default.warn('An Expo user account is required to fetch environment variables.');
|
|
14
14
|
const config = await getProjectConfig(opts);
|
|
15
15
|
return { env: buildProfile.env ?? {}, ...config };
|
|
16
16
|
}
|
|
17
17
|
const { projectId } = await getProjectConfig({ env: buildProfile.env, ...opts });
|
|
18
|
-
const env = await resolveEnvVarsAsync({
|
|
18
|
+
const env = await resolveEnvVarsAsync({
|
|
19
|
+
flags,
|
|
20
|
+
buildProfile,
|
|
21
|
+
buildProfileName,
|
|
22
|
+
graphqlClient,
|
|
23
|
+
projectId,
|
|
24
|
+
});
|
|
19
25
|
const config = await getProjectConfig({ ...opts, env });
|
|
20
26
|
return { env, ...config };
|
|
21
27
|
}
|
|
22
28
|
exports.evaluateConfigWithEnvVarsAsync = evaluateConfigWithEnvVarsAsync;
|
|
23
|
-
async function resolveEnvVarsAsync({ flags, buildProfile, graphqlClient, projectId, }) {
|
|
24
|
-
const environment = flags.environment ??
|
|
29
|
+
async function resolveEnvVarsAsync({ flags, buildProfile, buildProfileName, graphqlClient, projectId, }) {
|
|
30
|
+
const environment = flags.environment ??
|
|
31
|
+
buildProfile.environment?.toUpperCase() ??
|
|
32
|
+
process.env.EAS_CURRENT_ENVIRONMENT;
|
|
25
33
|
if (!environment || !isEnvironment(environment)) {
|
|
34
|
+
log_1.default.log(`Loaded "env" configuration for the "${buildProfileName}" profile: ${buildProfile.env && Object.keys(buildProfile.env).length > 0
|
|
35
|
+
? Object.keys(buildProfile.env).join(', ')
|
|
36
|
+
: 'no environment variables specified'}. ${(0, log_1.learnMore)('https://docs.expo.dev/build-reference/variables/')}`);
|
|
26
37
|
return { ...buildProfile.env };
|
|
27
38
|
}
|
|
28
39
|
try {
|
|
@@ -30,13 +41,24 @@ async function resolveEnvVarsAsync({ flags, buildProfile, graphqlClient, project
|
|
|
30
41
|
appId: projectId,
|
|
31
42
|
environment,
|
|
32
43
|
});
|
|
33
|
-
const
|
|
44
|
+
const serverEnvVars = Object.fromEntries(environmentVariables
|
|
34
45
|
.filter(({ name, value }) => name && value)
|
|
35
46
|
.map(({ name, value }) => [name, value]));
|
|
36
|
-
|
|
47
|
+
const envVarsWithSource = {
|
|
48
|
+
...Object.fromEntries(Object.keys(serverEnvVars).map(key => [key, 'EAS server'])),
|
|
49
|
+
...(buildProfile.env
|
|
50
|
+
? Object.fromEntries(Object.keys(buildProfile.env).map(key => [key, 'build profile']))
|
|
51
|
+
: null),
|
|
52
|
+
};
|
|
53
|
+
log_1.default.log(`Loaded "env" configuration for the "${buildProfileName}" profile and "${environment.toLowerCase()}" environment: ${Object.keys(envVarsWithSource).length > 0
|
|
54
|
+
? Object.keys(envVarsWithSource)
|
|
55
|
+
.map(key => `${key} (source: ${envVarsWithSource[key]})`)
|
|
56
|
+
.join('\n')
|
|
57
|
+
: 'no environment variables specified'}\n${(0, log_1.learnMore)('https://docs.expo.dev/build-reference/variables/')}`);
|
|
58
|
+
return { ...serverEnvVars, ...buildProfile.env };
|
|
37
59
|
}
|
|
38
60
|
catch (e) {
|
|
39
|
-
log_1.default.error(
|
|
61
|
+
log_1.default.error(`Failed to pull env variables for environment ${environment} from EAS servers`);
|
|
40
62
|
log_1.default.error(e);
|
|
41
63
|
log_1.default.error('This can possibly be a bug in EAS/EAS CLI. Report it here: https://github.com/expo/eas-cli/issues');
|
|
42
64
|
return { ...buildProfile.env };
|
package/build/build/graphql.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ArchiveSource, BuildMode, BuildTrigger, Metadata, Workflow } from '@expo/eas-build-job';
|
|
2
2
|
import { LoggerLevel } from '@expo/logger';
|
|
3
|
-
import { BuildIosEnterpriseProvisioning, BuildMetadataInput, BuildWorkflow, BuildMode as GraphQLBuildMode, BuildTrigger as GraphQLBuildTrigger, ProjectArchiveSourceInput, WorkerLoggerLevel } from '../graphql/generated';
|
|
3
|
+
import { BuildIosEnterpriseProvisioning, BuildMetadataInput, BuildWorkflow, FingerprintSourceInput, BuildMode as GraphQLBuildMode, BuildTrigger as GraphQLBuildTrigger, ProjectArchiveSourceInput, WorkerLoggerLevel } from '../graphql/generated';
|
|
4
4
|
export declare function transformProjectArchive(archiveSource: ArchiveSource): ProjectArchiveSourceInput;
|
|
5
5
|
export declare function transformMetadata(metadata: Metadata): BuildMetadataInput;
|
|
6
|
+
export declare function transformFingerprintSource(fingerprintSource: NonNullable<Metadata['fingerprintSource']>): FingerprintSourceInput | null;
|
|
6
7
|
export declare function transformWorkflow(workflow: Workflow): BuildWorkflow;
|
|
7
8
|
export declare function transformIosEnterpriseProvisioning(enterpriseProvisioning: Metadata['iosEnterpriseProvisioning']): BuildIosEnterpriseProvisioning;
|
|
8
9
|
export declare function transformBuildMode(buildMode: BuildMode): GraphQLBuildMode;
|
package/build/build/graphql.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loggerLevelToGraphQLWorkerLoggerLevel = exports.transformBuildTrigger = exports.transformBuildMode = exports.transformIosEnterpriseProvisioning = exports.transformWorkflow = exports.transformMetadata = exports.transformProjectArchive = void 0;
|
|
3
|
+
exports.loggerLevelToGraphQLWorkerLoggerLevel = exports.transformBuildTrigger = exports.transformBuildMode = exports.transformIosEnterpriseProvisioning = exports.transformWorkflow = exports.transformFingerprintSource = exports.transformMetadata = exports.transformProjectArchive = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
6
|
const logger_1 = require("@expo/logger");
|
|
@@ -28,7 +28,7 @@ exports.transformProjectArchive = transformProjectArchive;
|
|
|
28
28
|
function transformMetadata(metadata) {
|
|
29
29
|
return {
|
|
30
30
|
...metadata,
|
|
31
|
-
fingerprintSource: metadata.fingerprintSource,
|
|
31
|
+
fingerprintSource: metadata.fingerprintSource && transformFingerprintSource(metadata.fingerprintSource),
|
|
32
32
|
credentialsSource: metadata.credentialsSource && transformCredentialsSource(metadata.credentialsSource),
|
|
33
33
|
distribution: metadata.distribution && transformDistribution(metadata.distribution),
|
|
34
34
|
workflow: metadata.workflow && transformWorkflow(metadata.workflow),
|
|
@@ -37,6 +37,17 @@ function transformMetadata(metadata) {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
exports.transformMetadata = transformMetadata;
|
|
40
|
+
function transformFingerprintSource(fingerprintSource) {
|
|
41
|
+
if (fingerprintSource.type !== eas_build_job_1.FingerprintSourceType.GCS) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
type: generated_1.FingerprintSourceType.Gcs,
|
|
46
|
+
bucketKey: fingerprintSource.bucketKey,
|
|
47
|
+
isDebugFingerprint: fingerprintSource.isDebugFingerprint,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
exports.transformFingerprintSource = transformFingerprintSource;
|
|
40
51
|
function transformCredentialsSource(credentialsSource) {
|
|
41
52
|
if (credentialsSource === 'local') {
|
|
42
53
|
return generated_1.BuildCredentialsSource.Local;
|
package/build/build/local.js
CHANGED
|
@@ -6,7 +6,7 @@ const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
|
|
|
6
6
|
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
7
7
|
const ora_1 = require("../ora");
|
|
8
8
|
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
|
|
9
|
-
const PLUGIN_PACKAGE_VERSION = '1.0.
|
|
9
|
+
const PLUGIN_PACKAGE_VERSION = '1.0.135';
|
|
10
10
|
var LocalBuildMode;
|
|
11
11
|
(function (LocalBuildMode) {
|
|
12
12
|
/**
|
|
@@ -83,7 +83,7 @@ async function runBuildAndSubmitAsync(graphqlClient, analytics, vcsClient, proje
|
|
|
83
83
|
});
|
|
84
84
|
const customBuildConfigMetadataByPlatform = {};
|
|
85
85
|
for (const buildProfile of buildProfiles) {
|
|
86
|
-
(0, remoteVersionSource_1.
|
|
86
|
+
await (0, remoteVersionSource_1.validateBuildProfileVersionSettingsAsync)(buildProfile, easJsonCliConfig, projectDir, flags);
|
|
87
87
|
const maybeMetadata = await (0, customBuildConfig_1.validateCustomBuildConfigAsync)({
|
|
88
88
|
projectDir,
|
|
89
89
|
profile: buildProfile.profile,
|
|
@@ -100,11 +100,11 @@ async function runBuildAndSubmitAsync(graphqlClient, analytics, vcsClient, proje
|
|
|
100
100
|
const { env } = await (0, evaluateConfigWithEnvVarsAsync_1.evaluateConfigWithEnvVarsAsync)({
|
|
101
101
|
flags,
|
|
102
102
|
buildProfile: buildProfile.profile,
|
|
103
|
+
buildProfileName: buildProfile.profileName,
|
|
103
104
|
graphqlClient,
|
|
104
105
|
getProjectConfig: getDynamicPrivateProjectConfigAsync,
|
|
105
106
|
opts: { env: buildProfile.profile.env },
|
|
106
107
|
});
|
|
107
|
-
log_1.default.log(`Loaded "env" configuration for the "${buildProfile.profileName}" profile: ${env ? Object.keys(env).join(', ') : 'no environment variables specified'}. ${(0, log_1.learnMore)('https://docs.expo.dev/build-reference/variables/')}`);
|
|
108
108
|
const { build: maybeBuild, buildCtx } = await prepareAndStartBuildAsync({
|
|
109
109
|
projectDir,
|
|
110
110
|
flags,
|
|
@@ -265,6 +265,16 @@ async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildP
|
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
await (0, projectUtils_1.validateAppVersionRuntimePolicySupportAsync)(buildCtx.projectDir, buildCtx.exp);
|
|
268
|
+
if (easJsonCliConfig?.appVersionSource === undefined &&
|
|
269
|
+
buildProfile.profile.autoIncrement !== 'version') {
|
|
270
|
+
if (buildProfile.profile.autoIncrement !== true) {
|
|
271
|
+
log_1.default.warn(`The field "cli.appVersionSource" is not set, but it will be required in the future. ${(0, log_1.learnMore)('https://docs.expo.dev/build-reference/app-versions/')}`);
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
const easJsonAccessor = eas_json_1.EasJsonAccessor.fromProjectPath(projectDir);
|
|
275
|
+
easJsonCliConfig = await (0, remoteVersionSource_1.ensureAppVersionSourceIsSetAsync)(easJsonAccessor, easJsonCliConfig, flags.nonInteractive);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
268
278
|
if (easJsonCliConfig?.appVersionSource === eas_json_1.AppVersionSource.REMOTE) {
|
|
269
279
|
(0, remoteVersionSource_1.validateAppConfigForRemoteVersionSource)(buildCtx.exp, buildProfile.platform);
|
|
270
280
|
}
|
package/build/build/types.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { ResourceClass } from '@expo/eas-json';
|
|
2
|
+
import { LoggerLevel } from '@expo/logger';
|
|
3
|
+
import { LocalBuildOptions } from './local';
|
|
4
|
+
import { RequestedPlatform } from '../platform';
|
|
1
5
|
export declare enum BuildStatus {
|
|
2
6
|
NEW = "new",
|
|
3
7
|
IN_QUEUE = "in-queue",
|
|
@@ -13,3 +17,19 @@ export declare enum BuildDistributionType {
|
|
|
13
17
|
/** @deprecated Use simulator flag instead */
|
|
14
18
|
SIMULATOR = "simulator"
|
|
15
19
|
}
|
|
20
|
+
export interface BuildFlags {
|
|
21
|
+
requestedPlatform: RequestedPlatform;
|
|
22
|
+
profile?: string;
|
|
23
|
+
nonInteractive: boolean;
|
|
24
|
+
wait: boolean;
|
|
25
|
+
clearCache: boolean;
|
|
26
|
+
json: boolean;
|
|
27
|
+
autoSubmit: boolean;
|
|
28
|
+
submitProfile?: string;
|
|
29
|
+
localBuildOptions: LocalBuildOptions;
|
|
30
|
+
resourceClass?: ResourceClass;
|
|
31
|
+
message?: string;
|
|
32
|
+
buildLoggerLevel?: LoggerLevel;
|
|
33
|
+
freezeCredentials: boolean;
|
|
34
|
+
repack: boolean;
|
|
35
|
+
}
|
|
@@ -56,6 +56,7 @@ class BuildResign extends EasCommand_1.default {
|
|
|
56
56
|
const { exp, projectId, env } = await (0, evaluateConfigWithEnvVarsAsync_1.evaluateConfigWithEnvVarsAsync)({
|
|
57
57
|
flags,
|
|
58
58
|
buildProfile,
|
|
59
|
+
buildProfileName: flags.targetProfile ?? 'production',
|
|
59
60
|
graphqlClient,
|
|
60
61
|
getProjectConfig: getDynamicPrivateProjectConfigAsync,
|
|
61
62
|
opts: { env: buildProfile.env },
|
|
@@ -46,6 +46,7 @@ class BuildVersionGetView extends EasCommand_1.default {
|
|
|
46
46
|
const { exp, projectId, env } = await (0, evaluateConfigWithEnvVarsAsync_1.evaluateConfigWithEnvVarsAsync)({
|
|
47
47
|
flags,
|
|
48
48
|
buildProfile: profile,
|
|
49
|
+
buildProfileName: flags.profile ?? 'production',
|
|
49
50
|
graphqlClient,
|
|
50
51
|
getProjectConfig: getDynamicPrivateProjectConfigAsync,
|
|
51
52
|
opts: { env: profile.env },
|
|
@@ -34,6 +34,7 @@ class BuildVersionSetView extends EasCommand_1.default {
|
|
|
34
34
|
const { exp, projectId, env } = await (0, evaluateConfigWithEnvVarsAsync_1.evaluateConfigWithEnvVarsAsync)({
|
|
35
35
|
flags,
|
|
36
36
|
buildProfile: profile,
|
|
37
|
+
buildProfileName: flags.profile ?? 'production',
|
|
37
38
|
graphqlClient,
|
|
38
39
|
getProjectConfig: getDynamicPrivateProjectConfigAsync,
|
|
39
40
|
opts: { env: profile.env },
|
|
@@ -45,6 +45,7 @@ class BuildVersionSyncView extends EasCommand_1.default {
|
|
|
45
45
|
const { exp, projectId, env } = await (0, evaluateConfigWithEnvVarsAsync_1.evaluateConfigWithEnvVarsAsync)({
|
|
46
46
|
flags,
|
|
47
47
|
buildProfile: profileInfo.profile,
|
|
48
|
+
buildProfileName: profileInfo.profileName,
|
|
48
49
|
graphqlClient,
|
|
49
50
|
getProjectConfig: getDynamicPrivateProjectConfigAsync,
|
|
50
51
|
opts: { env: profileInfo.profile.env },
|
package/build/commands/config.js
CHANGED
|
@@ -64,6 +64,7 @@ class Config extends EasCommand_1.default {
|
|
|
64
64
|
const { exp: appConfig } = await (0, evaluateConfigWithEnvVarsAsync_1.evaluateConfigWithEnvVarsAsync)({
|
|
65
65
|
flags,
|
|
66
66
|
buildProfile: profile,
|
|
67
|
+
buildProfileName: profileName,
|
|
67
68
|
graphqlClient,
|
|
68
69
|
getProjectConfig: getDynamicPublicProjectConfigAsync,
|
|
69
70
|
opts: { env: profile.env },
|
|
@@ -3,6 +3,7 @@ var _a;
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
|
+
const eas_json_1 = require("@expo/eas-json");
|
|
6
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
8
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
8
9
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
@@ -284,6 +285,7 @@ async function configureProjectFromBareDefaultExpoTemplateAsync({ app, vcsClient
|
|
|
284
285
|
const easJson = {
|
|
285
286
|
cli: {
|
|
286
287
|
version: `>= ${easCli_1.easCliVersion}`,
|
|
288
|
+
appVersionSource: eas_json_1.AppVersionSource.REMOTE,
|
|
287
289
|
},
|
|
288
290
|
build: {
|
|
289
291
|
development: {
|
|
@@ -304,6 +306,7 @@ async function configureProjectFromBareDefaultExpoTemplateAsync({ app, vcsClient
|
|
|
304
306
|
},
|
|
305
307
|
production: {
|
|
306
308
|
channel: 'production',
|
|
309
|
+
autoIncrement: true,
|
|
307
310
|
...easBuildGitHubConfig,
|
|
308
311
|
},
|
|
309
312
|
},
|
|
@@ -7,6 +7,7 @@ const core_1 = require("@oclif/core");
|
|
|
7
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
8
|
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
|
|
9
9
|
const queries_1 = require("../../branch/queries");
|
|
10
|
+
const graphql_1 = require("../../build/graphql");
|
|
10
11
|
const repository_1 = require("../../build/utils/repository");
|
|
11
12
|
const url_1 = require("../../build/utils/url");
|
|
12
13
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
@@ -17,6 +18,7 @@ const generated_1 = require("../../graphql/generated");
|
|
|
17
18
|
const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
|
|
18
19
|
const log_1 = tslib_1.__importStar(require("../../log"));
|
|
19
20
|
const ora_1 = require("../../ora");
|
|
21
|
+
const maybeUploadFingerprintAsync_1 = require("../../project/maybeUploadFingerprintAsync");
|
|
20
22
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
21
23
|
const publish_1 = require("../../project/publish");
|
|
22
24
|
const workflow_1 = require("../../project/workflow");
|
|
@@ -182,7 +184,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
182
184
|
throw e;
|
|
183
185
|
}
|
|
184
186
|
const workflows = await (0, workflow_1.resolveWorkflowPerPlatformAsync)(projectDir, vcsClient);
|
|
185
|
-
const
|
|
187
|
+
const runtimeVersionInfoObjects = await (0, publish_1.getRuntimeVersionInfoObjectsAsync)({
|
|
186
188
|
exp,
|
|
187
189
|
platforms: realizedPlatforms,
|
|
188
190
|
projectDir,
|
|
@@ -192,23 +194,35 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
192
194
|
},
|
|
193
195
|
env: undefined,
|
|
194
196
|
});
|
|
195
|
-
const
|
|
197
|
+
const runtimeToPlatformsAndFingerprintInfoMapping = (0, publish_1.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects)(runtimeVersionInfoObjects);
|
|
196
198
|
const { branchId } = await (0, queries_1.ensureBranchExistsAsync)(graphqlClient, {
|
|
197
199
|
appId: projectId,
|
|
198
200
|
branchName,
|
|
199
201
|
});
|
|
202
|
+
const runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping = await Promise.all(runtimeToPlatformsAndFingerprintInfoMapping.map(async (info) => {
|
|
203
|
+
return {
|
|
204
|
+
...info,
|
|
205
|
+
fingerprintSource: info.fingerprint
|
|
206
|
+
? (await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
|
|
207
|
+
runtimeVersion: info.runtimeVersion,
|
|
208
|
+
fingerprint: info.fingerprint,
|
|
209
|
+
graphqlClient,
|
|
210
|
+
})).fingerprintSource ?? null
|
|
211
|
+
: null,
|
|
212
|
+
};
|
|
213
|
+
}));
|
|
200
214
|
const runtimeVersionToRolloutInfoGroup = rolloutPercentage !== undefined
|
|
201
215
|
? await (0, publish_1.getRuntimeToUpdateRolloutInfoGroupMappingAsync)(graphqlClient, {
|
|
202
216
|
appId: projectId,
|
|
203
217
|
branchName,
|
|
204
218
|
rolloutPercentage,
|
|
205
|
-
|
|
219
|
+
runtimeToPlatformsAndFingerprintInfoMapping,
|
|
206
220
|
})
|
|
207
221
|
: undefined;
|
|
208
222
|
const gitCommitHash = await vcsClient.getCommitHashAsync();
|
|
209
223
|
const isGitWorkingTreeDirty = await vcsClient.hasUncommittedChangesAsync();
|
|
210
224
|
// Sort the updates into different groups based on their platform specific runtime versions
|
|
211
|
-
const updateGroups =
|
|
225
|
+
const updateGroups = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(({ runtimeVersion, platforms, fingerprintSource }) => {
|
|
212
226
|
const localUpdateInfoGroup = Object.fromEntries(platforms.map(platform => [
|
|
213
227
|
platform,
|
|
214
228
|
unsortedUpdateInfoGroups[platform],
|
|
@@ -226,6 +240,9 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
226
240
|
branchId,
|
|
227
241
|
updateInfoGroup: localUpdateInfoGroup,
|
|
228
242
|
rolloutInfoGroup: localRolloutInfoGroup,
|
|
243
|
+
runtimeFingerprintSource: fingerprintSource
|
|
244
|
+
? (0, graphql_1.transformFingerprintSource)(fingerprintSource)
|
|
245
|
+
: null,
|
|
229
246
|
runtimeVersion,
|
|
230
247
|
message: updateMessage,
|
|
231
248
|
gitCommitHash,
|
|
@@ -283,7 +300,7 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
283
300
|
log_1.default.log('👉 Since multiple runtime versions are defined, multiple update groups have been published.');
|
|
284
301
|
}
|
|
285
302
|
log_1.default.addNewLineIfNone();
|
|
286
|
-
for (const runtime of (0, uniqBy_1.default)(
|
|
303
|
+
for (const runtime of (0, uniqBy_1.default)(runtimeToPlatformsAndFingerprintInfoMapping, version => version.runtimeVersion)) {
|
|
287
304
|
const newUpdatesForRuntimeVersion = newUpdates.filter(update => update.runtimeVersion === runtime.runtimeVersion);
|
|
288
305
|
if (newUpdatesForRuntimeVersion.length === 0) {
|
|
289
306
|
throw new Error(`Publish response is missing updates with runtime ${runtime.runtimeVersion}.`);
|
|
@@ -75,7 +75,7 @@ class UpdateRollBackToEmbedded extends EasCommand_1.default {
|
|
|
75
75
|
const gitCommitHash = await vcsClient.getCommitHashAsync();
|
|
76
76
|
const isGitWorkingTreeDirty = await vcsClient.hasUncommittedChangesAsync();
|
|
77
77
|
const workflows = await (0, workflow_1.resolveWorkflowPerPlatformAsync)(projectDir, vcsClient);
|
|
78
|
-
const
|
|
78
|
+
const runtimeVersionInfoObjects = await (0, publish_1.getRuntimeVersionInfoObjectsAsync)({
|
|
79
79
|
exp,
|
|
80
80
|
platforms: realizedPlatforms,
|
|
81
81
|
projectDir,
|
|
@@ -85,6 +85,7 @@ class UpdateRollBackToEmbedded extends EasCommand_1.default {
|
|
|
85
85
|
},
|
|
86
86
|
env: undefined,
|
|
87
87
|
});
|
|
88
|
+
const runtimeToPlatformsAndFingerprintInfoMapping = (0, publish_1.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects)(runtimeVersionInfoObjects);
|
|
88
89
|
let newUpdates;
|
|
89
90
|
const publishSpinner = (0, ora_1.ora)('Publishing...').start();
|
|
90
91
|
try {
|
|
@@ -95,7 +96,7 @@ class UpdateRollBackToEmbedded extends EasCommand_1.default {
|
|
|
95
96
|
updateMessage,
|
|
96
97
|
branchId,
|
|
97
98
|
codeSigningInfo,
|
|
98
|
-
|
|
99
|
+
runtimeToPlatformsAndFingerprintInfoMapping,
|
|
99
100
|
realizedPlatforms,
|
|
100
101
|
});
|
|
101
102
|
publishSpinner.succeed('Published!');
|
|
@@ -113,7 +114,7 @@ class UpdateRollBackToEmbedded extends EasCommand_1.default {
|
|
|
113
114
|
log_1.default.log('👉 Since multiple runtime versions are defined, multiple update groups have been published.');
|
|
114
115
|
}
|
|
115
116
|
log_1.default.addNewLineIfNone();
|
|
116
|
-
for (const runtime of (0, uniqBy_1.default)(
|
|
117
|
+
for (const runtime of (0, uniqBy_1.default)(runtimeToPlatformsAndFingerprintInfoMapping, version => version.runtimeVersion)) {
|
|
117
118
|
const newUpdatesForRuntimeVersion = newUpdates.filter(update => update.runtimeVersion === runtime.runtimeVersion);
|
|
118
119
|
if (newUpdatesForRuntimeVersion.length === 0) {
|
|
119
120
|
throw new Error(`Publish response is missing updates with runtime ${runtime.runtimeVersion}.`);
|
|
@@ -150,11 +151,10 @@ class UpdateRollBackToEmbedded extends EasCommand_1.default {
|
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
|
-
async publishRollbacksAsync({ graphqlClient, isGitWorkingTreeDirty, gitCommitHash, updateMessage, branchId, codeSigningInfo,
|
|
154
|
-
const runtimeToPlatformMapping = (0, publish_1.getRuntimeToPlatformMappingFromRuntimeVersions)(runtimeVersions);
|
|
154
|
+
async publishRollbacksAsync({ graphqlClient, isGitWorkingTreeDirty, gitCommitHash, updateMessage, branchId, codeSigningInfo, runtimeToPlatformsAndFingerprintInfoMapping, realizedPlatforms, }) {
|
|
155
155
|
const rollbackInfoGroups = Object.fromEntries(realizedPlatforms.map(platform => [platform, true]));
|
|
156
156
|
// Sort the updates into different groups based on their platform specific runtime versions
|
|
157
|
-
const updateGroups =
|
|
157
|
+
const updateGroups = runtimeToPlatformsAndFingerprintInfoMapping.map(({ runtimeVersion, platforms }) => {
|
|
158
158
|
const localRollbackInfoGroup = Object.fromEntries(platforms.map(platform => [platform, rollbackInfoGroups[platform]]));
|
|
159
159
|
return {
|
|
160
160
|
branchId,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import EasCommand from '../../commandUtils/EasCommand';
|
|
2
|
+
export default class WorkerDeploy extends EasCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static aliases: string[];
|
|
5
|
+
static hidden: boolean;
|
|
6
|
+
static state: string;
|
|
7
|
+
static flags: {};
|
|
8
|
+
static contextDefinition: {
|
|
9
|
+
loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
|
|
10
|
+
projectDir: import("../../commandUtils/context/ProjectDirContextField").default;
|
|
11
|
+
getDynamicPublicProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicPublicProjectConfigContextField;
|
|
12
|
+
getDynamicPrivateProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicPrivateProjectConfigContextField;
|
|
13
|
+
};
|
|
14
|
+
runAsync(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
+
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
7
|
+
const path = tslib_1.__importStar(require("node:path"));
|
|
8
|
+
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
9
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
10
|
+
const ora_1 = require("../../ora");
|
|
11
|
+
const progress_1 = require("../../utils/progress");
|
|
12
|
+
const WorkerAssets = tslib_1.__importStar(require("../../worker/assets"));
|
|
13
|
+
const deployment_1 = require("../../worker/deployment");
|
|
14
|
+
const upload_1 = require("../../worker/upload");
|
|
15
|
+
const isDirectory = (directoryPath) => node_fs_1.default.promises
|
|
16
|
+
.stat(directoryPath)
|
|
17
|
+
.then(stat => stat.isDirectory())
|
|
18
|
+
.catch(() => false);
|
|
19
|
+
class WorkerDeploy extends EasCommand_1.default {
|
|
20
|
+
async runAsync() {
|
|
21
|
+
log_1.default.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
|
|
22
|
+
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, } = await this.getContextAsync(_a, {
|
|
23
|
+
nonInteractive: true,
|
|
24
|
+
});
|
|
25
|
+
const { projectId, projectDir, exp } = await getDynamicPrivateProjectConfigAsync();
|
|
26
|
+
const distPath = path.resolve(projectDir, 'dist');
|
|
27
|
+
let distServerPath;
|
|
28
|
+
let distClientPath;
|
|
29
|
+
if (exp.web?.output === 'static') {
|
|
30
|
+
distClientPath = distPath;
|
|
31
|
+
distServerPath = null;
|
|
32
|
+
if (!(await isDirectory(distClientPath))) {
|
|
33
|
+
throw new Error(`No "dist/" folder found. Prepare your project for deployment with "npx expo export"`);
|
|
34
|
+
}
|
|
35
|
+
log_1.default.log('Detected "static" worker deployment');
|
|
36
|
+
}
|
|
37
|
+
else if (exp.web?.output === 'server') {
|
|
38
|
+
distClientPath = path.resolve(distPath, 'client');
|
|
39
|
+
distServerPath = path.resolve(distPath, 'server');
|
|
40
|
+
if (!(await isDirectory(distClientPath))) {
|
|
41
|
+
throw new Error(`No "dist/client/" folder found. Prepare your project for deployment with "npx expo export"`);
|
|
42
|
+
}
|
|
43
|
+
else if (!(await isDirectory(distServerPath))) {
|
|
44
|
+
throw new Error(`No "dist/server/" folder found. Prepare your project for deployment with "npx expo export"`);
|
|
45
|
+
}
|
|
46
|
+
log_1.default.log('Detected "server" worker deployment');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw new Error(`Single-page apps are not supported. Ensure that app.json key "expo.web.output" is set to "server" or "static".`);
|
|
50
|
+
}
|
|
51
|
+
async function* emitWorkerTarballAsync(assetMap) {
|
|
52
|
+
yield ['assets.json', JSON.stringify(assetMap)];
|
|
53
|
+
// TODO: Create manifest from user configuration
|
|
54
|
+
const manifest = { env: {} };
|
|
55
|
+
yield ['manifest.json', JSON.stringify(manifest)];
|
|
56
|
+
if (distServerPath) {
|
|
57
|
+
const workerFiles = WorkerAssets.listWorkerFilesAsync(distServerPath);
|
|
58
|
+
for await (const workerFile of workerFiles) {
|
|
59
|
+
yield [`server/${workerFile.normalizedPath}`, workerFile.data];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function uploadTarballAsync(tarPath) {
|
|
64
|
+
const uploadUrl = await (0, deployment_1.getSignedDeploymentUrlAsync)(graphqlClient, exp, {
|
|
65
|
+
appId: projectId,
|
|
66
|
+
});
|
|
67
|
+
const { response } = await (0, upload_1.uploadAsync)({
|
|
68
|
+
url: uploadUrl,
|
|
69
|
+
filePath: tarPath,
|
|
70
|
+
compress: false,
|
|
71
|
+
headers: {
|
|
72
|
+
accept: 'application/json',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
if (response.status === 413) {
|
|
76
|
+
throw new Error('Upload failed! (Payload too large)\n' +
|
|
77
|
+
`The files in "dist/server/" (at: ${distServerPath}) exceed the maximum file size (10MB gzip).`);
|
|
78
|
+
}
|
|
79
|
+
else if (!response.ok) {
|
|
80
|
+
throw new Error(`Upload failed! (${response.statusText})`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const json = await response.json();
|
|
84
|
+
if (!json.success || !json.result || typeof json.result !== 'object') {
|
|
85
|
+
throw new Error(json.message ? `Upload failed: ${json.message}` : 'Upload failed!');
|
|
86
|
+
}
|
|
87
|
+
return json.result;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function uploadAssetsAsync(assetMap, uploads) {
|
|
91
|
+
if (typeof uploads !== 'object' || !uploads) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// TODO(@kitten): Batch and upload multiple files in parallel
|
|
95
|
+
const uploadParams = [];
|
|
96
|
+
for await (const asset of WorkerAssets.listAssetMapFilesAsync(distClientPath, assetMap)) {
|
|
97
|
+
const uploadURL = uploads[asset.normalizedPath];
|
|
98
|
+
if (uploadURL) {
|
|
99
|
+
uploadParams.push({ url: uploadURL, filePath: asset.path });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const progress = {
|
|
103
|
+
total: uploadParams.length,
|
|
104
|
+
pending: 0,
|
|
105
|
+
percent: 0,
|
|
106
|
+
transferred: 0,
|
|
107
|
+
};
|
|
108
|
+
const updateProgress = (0, progress_1.createProgressTracker)({
|
|
109
|
+
total: progress.total,
|
|
110
|
+
message(ratio) {
|
|
111
|
+
const percent = `${Math.floor(ratio * 100)}`;
|
|
112
|
+
const details = chalk_1.default.dim(`(${progress.pending} Pending, ${progress.transferred} Completed, ${progress.total} Total)`);
|
|
113
|
+
return `Uploading client assets: ${percent.padStart(3)}% ${details}`;
|
|
114
|
+
},
|
|
115
|
+
completedMessage: 'Uploaded assets for serverless deployment',
|
|
116
|
+
});
|
|
117
|
+
try {
|
|
118
|
+
for await (const signal of (0, upload_1.batchUploadAsync)(uploadParams)) {
|
|
119
|
+
if ('response' in signal) {
|
|
120
|
+
progress.pending--;
|
|
121
|
+
progress.percent = ++progress.transferred / progress.total;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
progress.pending++;
|
|
125
|
+
}
|
|
126
|
+
updateProgress({ progress });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
updateProgress({ isComplete: true, error });
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
updateProgress({ isComplete: true });
|
|
134
|
+
}
|
|
135
|
+
let progress = (0, ora_1.ora)('Preparing worker upload');
|
|
136
|
+
let assetMap;
|
|
137
|
+
let tarPath;
|
|
138
|
+
try {
|
|
139
|
+
assetMap = await WorkerAssets.createAssetMapAsync(distClientPath);
|
|
140
|
+
tarPath = await WorkerAssets.packFilesIterableAsync(emitWorkerTarballAsync(assetMap));
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
progress.fail('Failed to prepare worker upload');
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
progress.succeed('Prepared worker upload');
|
|
147
|
+
progress = (0, ora_1.ora)('Creating worker deployment');
|
|
148
|
+
let deployResult;
|
|
149
|
+
try {
|
|
150
|
+
deployResult = await uploadTarballAsync(tarPath);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
progress.fail('Failed to create worker deployment');
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
progress.succeed('Created worker deployment');
|
|
157
|
+
await uploadAssetsAsync(assetMap, deployResult.uploads);
|
|
158
|
+
const baseDomain = process.env.EXPO_STAGING ? 'staging.expo' : 'expo';
|
|
159
|
+
const deploymentURL = `https://${deployResult.fullName}.${baseDomain}.app`;
|
|
160
|
+
const deploymentsUrl = `https://${baseDomain}.dev/accounts/${exp.owner}/projects/${deployResult.name}/serverless/deployments`;
|
|
161
|
+
log_1.default.addNewLineIfNone();
|
|
162
|
+
log_1.default.log(`🎉 Your worker deployment is ready: ${deploymentURL}`);
|
|
163
|
+
log_1.default.addNewLineIfNone();
|
|
164
|
+
log_1.default.log(`🔗 Manage on EAS: ${deploymentsUrl}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
_a = WorkerDeploy;
|
|
168
|
+
WorkerDeploy.description = 'deploy an Expo web build';
|
|
169
|
+
WorkerDeploy.aliases = ['deploy'];
|
|
170
|
+
// TODO(@kitten): Keep command hidden until worker deployments are live
|
|
171
|
+
WorkerDeploy.hidden = true;
|
|
172
|
+
WorkerDeploy.state = 'beta';
|
|
173
|
+
WorkerDeploy.flags = {
|
|
174
|
+
// TODO(@kitten): Allow deployment identifier to be specified
|
|
175
|
+
};
|
|
176
|
+
WorkerDeploy.contextDefinition = {
|
|
177
|
+
..._a.ContextOptions.DynamicProjectConfig,
|
|
178
|
+
..._a.ContextOptions.ProjectDir,
|
|
179
|
+
..._a.ContextOptions.LoggedIn,
|
|
180
|
+
};
|
|
181
|
+
exports.default = WorkerDeploy;
|
|
@@ -635,6 +635,47 @@ exports.CapabilityMapping = [
|
|
|
635
635
|
validateOptions: validateBooleanOptions,
|
|
636
636
|
getOptions: getBooleanOptions,
|
|
637
637
|
},
|
|
638
|
+
{
|
|
639
|
+
entitlement: 'com.apple.developer.journal.allow',
|
|
640
|
+
name: 'Journaling Suggestions',
|
|
641
|
+
capability: apple_utils_1.CapabilityType.JOURNALING_SUGGESTIONS,
|
|
642
|
+
validateOptions: createValidateStringArrayOptions(['suggestions']),
|
|
643
|
+
getOptions: getDefinedOptions,
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
entitlement: 'com.apple.developer.managed-app-distribution.install-ui',
|
|
647
|
+
name: 'Managed App Installation UI',
|
|
648
|
+
capability: apple_utils_1.CapabilityType.MANAGED_APP_INSTALLATION_UI,
|
|
649
|
+
validateOptions: createValidateStringArrayOptions(['managed-app']),
|
|
650
|
+
getOptions: getDefinedOptions,
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
entitlement: 'com.apple.developer.networking.slicing.appcategory',
|
|
654
|
+
name: '5G Network Slicing',
|
|
655
|
+
capability: apple_utils_1.CapabilityType.NETWORK_SLICING,
|
|
656
|
+
validateOptions: createValidateStringArrayOptions([
|
|
657
|
+
'gaming-6014',
|
|
658
|
+
'communication-9000',
|
|
659
|
+
'streaming-9001',
|
|
660
|
+
]),
|
|
661
|
+
getOptions: getDefinedOptions,
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
entitlement: 'com.apple.developer.networking.slicing.trafficcategory',
|
|
665
|
+
name: '5G Network Slicing',
|
|
666
|
+
capability: apple_utils_1.CapabilityType.NETWORK_SLICING,
|
|
667
|
+
validateOptions: createValidateStringArrayOptions([
|
|
668
|
+
'defaultslice-1',
|
|
669
|
+
'video-2',
|
|
670
|
+
'background-3',
|
|
671
|
+
'voice-4',
|
|
672
|
+
'callsignaling-5',
|
|
673
|
+
'responsivedata-6',
|
|
674
|
+
'avstreaming-7',
|
|
675
|
+
'responsiveav-8',
|
|
676
|
+
]),
|
|
677
|
+
getOptions: getDefinedOptions,
|
|
678
|
+
},
|
|
638
679
|
// VMNET
|
|
639
680
|
// These don't appear to have entitlements, so it's unclear how we can automatically enable / disable them at this time.
|
|
640
681
|
// TODO: Maybe add a warning about manually enabling features?
|