eas-cli 12.3.0 → 12.4.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/ios/version.js +11 -6
- package/build/commandUtils/context/contextUtils/getProjectIdAsync.d.ts +1 -0
- package/build/commandUtils/context/contextUtils/getProjectIdAsync.js +3 -1
- package/build/commands/worker/alias.d.ts +22 -0
- package/build/commands/worker/alias.js +170 -0
- package/build/commands/worker/deploy.d.ts +12 -1
- package/build/commands/worker/deploy.js +173 -65
- package/build/graphql/generated.d.ts +372 -146
- package/build/graphql/generated.js +46 -44
- package/build/project/expoConfig.d.ts +1 -0
- package/build/project/expoConfig.js +1 -0
- package/build/worker/assets.d.ts +12 -0
- package/build/worker/assets.js +20 -1
- package/build/worker/deployment.d.ts +25 -2
- package/build/worker/deployment.js +102 -15
- package/build/worker/fragments/WorkerDeployment.d.ts +1 -0
- package/build/worker/fragments/WorkerDeployment.js +14 -0
- package/build/worker/fragments/WorkerDeploymentAlias.d.ts +1 -0
- package/build/worker/fragments/WorkerDeploymentAlias.js +12 -0
- package/build/worker/mutations.d.ts +6 -0
- package/build/worker/mutations.js +33 -0
- package/build/worker/queries.d.ts +7 -0
- package/build/worker/queries.js +61 -0
- package/build/worker/utils/logs.d.ts +35 -0
- package/build/worker/utils/logs.js +54 -0
- package/oclif.manifest.json +129 -3
- package/package.json +4 -3
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const core_1 = require("@oclif/core");
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
8
|
+
const flags_1 = require("../../commandUtils/flags");
|
|
9
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
10
|
+
const ora_1 = require("../../ora");
|
|
11
|
+
const prompts_1 = require("../../prompts");
|
|
12
|
+
const json_1 = require("../../utils/json");
|
|
13
|
+
const deployment_1 = require("../../worker/deployment");
|
|
14
|
+
const logs_1 = require("../../worker/utils/logs");
|
|
15
|
+
class WorkerAlias extends EasCommand_1.default {
|
|
16
|
+
async runAsync() {
|
|
17
|
+
// NOTE(cedric): `Log.warn` uses `console.log`, which is incorrect when running with `--json`
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.warn(chalk_1.default.yellow('EAS Worker Deployments are in beta and subject to breaking changes.'));
|
|
20
|
+
const { flags: rawFlags } = await this.parse(_a);
|
|
21
|
+
const flags = this.sanitizeFlags(rawFlags);
|
|
22
|
+
if (flags.json) {
|
|
23
|
+
(0, json_1.enableJsonOutput)();
|
|
24
|
+
}
|
|
25
|
+
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, } = await this.getContextAsync(_a, {
|
|
26
|
+
nonInteractive: true,
|
|
27
|
+
});
|
|
28
|
+
const { projectId } = await getDynamicPrivateProjectConfigAsync();
|
|
29
|
+
const aliasName = await resolveDeploymentAliasAsync(flags);
|
|
30
|
+
const deploymentId = await resolveDeploymentIdAsync({
|
|
31
|
+
...flags,
|
|
32
|
+
graphqlClient,
|
|
33
|
+
projectId,
|
|
34
|
+
aliasName,
|
|
35
|
+
});
|
|
36
|
+
let progress = null;
|
|
37
|
+
let deploymentAlias = null;
|
|
38
|
+
if (aliasName) {
|
|
39
|
+
try {
|
|
40
|
+
progress = (0, ora_1.ora)((0, chalk_1.default) `Assigning alias {bold ${aliasName}} to deployment`).start();
|
|
41
|
+
deploymentAlias = await (0, deployment_1.assignWorkerDeploymentAliasAsync)({
|
|
42
|
+
graphqlClient,
|
|
43
|
+
appId: projectId,
|
|
44
|
+
deploymentId,
|
|
45
|
+
aliasName,
|
|
46
|
+
});
|
|
47
|
+
progress.text = (0, chalk_1.default) `Assigned alias {bold ${aliasName}} to deployment`;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
progress?.fail((0, chalk_1.default) `Failed to assign {bold ${aliasName}} alias to deployment`);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let deploymentProdAlias = null;
|
|
55
|
+
if (flags.isProduction) {
|
|
56
|
+
try {
|
|
57
|
+
progress = (progress ?? (0, ora_1.ora)()).start((0, chalk_1.default) `Promoting deployment to {bold production}`);
|
|
58
|
+
deploymentProdAlias = await (0, deployment_1.assignWorkerDeploymentProductionAsync)({
|
|
59
|
+
graphqlClient,
|
|
60
|
+
appId: projectId,
|
|
61
|
+
deploymentId,
|
|
62
|
+
});
|
|
63
|
+
progress.text = (0, chalk_1.default) `Promoted deployment to {bold production}`;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
progress?.fail((0, chalk_1.default) `Failed to promote deployment to {bold production}`);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
progress?.succeed(!deploymentAlias
|
|
71
|
+
? (0, chalk_1.default) `Promoted deployment to {bold production}`
|
|
72
|
+
: (0, chalk_1.default) `Promoted deployment to {bold production} with alias {bold ${deploymentAlias.aliasName}}`);
|
|
73
|
+
// Either use the alias, or production deployment information
|
|
74
|
+
const deployment = deploymentAlias?.workerDeployment ?? deploymentProdAlias?.workerDeployment;
|
|
75
|
+
if (flags.json) {
|
|
76
|
+
(0, json_1.printJsonOnlyOutput)((0, logs_1.formatWorkerDeploymentJson)({
|
|
77
|
+
projectId,
|
|
78
|
+
deployment: deployment,
|
|
79
|
+
aliases: [deploymentAlias].filter(Boolean),
|
|
80
|
+
production: deploymentProdAlias,
|
|
81
|
+
}));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
log_1.default.addNewLineIfNone();
|
|
85
|
+
log_1.default.log(`🎉 Your deployment is modified`);
|
|
86
|
+
log_1.default.addNewLineIfNone();
|
|
87
|
+
log_1.default.log((0, logs_1.formatWorkerDeploymentTable)({
|
|
88
|
+
projectId,
|
|
89
|
+
deployment: deployment,
|
|
90
|
+
aliases: [deploymentAlias].filter(Boolean),
|
|
91
|
+
production: deploymentProdAlias,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
sanitizeFlags(flags) {
|
|
95
|
+
return {
|
|
96
|
+
nonInteractive: flags['non-interactive'],
|
|
97
|
+
json: flags['json'],
|
|
98
|
+
aliasName: flags.alias?.trim().toLowerCase(),
|
|
99
|
+
deploymentIdentifier: flags.id?.trim().toLowerCase(),
|
|
100
|
+
isProduction: flags.prod,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
_a = WorkerAlias;
|
|
105
|
+
WorkerAlias.description = 'Assign deployment aliases';
|
|
106
|
+
WorkerAlias.aliases = ['deploy:alias', 'deploy:promote'];
|
|
107
|
+
// TODO(@kitten): Keep command hidden until worker deployments are live
|
|
108
|
+
WorkerAlias.hidden = true;
|
|
109
|
+
WorkerAlias.state = 'beta';
|
|
110
|
+
WorkerAlias.flags = {
|
|
111
|
+
prod: core_1.Flags.boolean({
|
|
112
|
+
aliases: ['production'],
|
|
113
|
+
description: 'Promote an existing deployment to production',
|
|
114
|
+
default: false,
|
|
115
|
+
}),
|
|
116
|
+
alias: core_1.Flags.string({
|
|
117
|
+
description: 'Custom alias to assign to the existing deployment',
|
|
118
|
+
helpValue: 'name',
|
|
119
|
+
required: false,
|
|
120
|
+
}),
|
|
121
|
+
id: core_1.Flags.string({
|
|
122
|
+
description: 'Unique identifier of an existing deployment',
|
|
123
|
+
helpValue: 'xyz123',
|
|
124
|
+
required: false,
|
|
125
|
+
}),
|
|
126
|
+
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
127
|
+
};
|
|
128
|
+
WorkerAlias.contextDefinition = {
|
|
129
|
+
..._a.ContextOptions.DynamicProjectConfig,
|
|
130
|
+
..._a.ContextOptions.ProjectDir,
|
|
131
|
+
..._a.ContextOptions.LoggedIn,
|
|
132
|
+
};
|
|
133
|
+
exports.default = WorkerAlias;
|
|
134
|
+
async function resolveDeploymentAliasAsync(flags) {
|
|
135
|
+
if (flags.aliasName?.trim()) {
|
|
136
|
+
return flags.aliasName.trim().toLowerCase();
|
|
137
|
+
}
|
|
138
|
+
// Skip alias prompt when promoting deployments to prod
|
|
139
|
+
if (flags.isProduction) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
if (flags.nonInteractive) {
|
|
143
|
+
throw new Error('The `--alias` flag must be set when running in `--non-interactive` mode.');
|
|
144
|
+
}
|
|
145
|
+
const { alias: aliasName } = await (0, prompts_1.promptAsync)({
|
|
146
|
+
type: 'text',
|
|
147
|
+
name: 'alias',
|
|
148
|
+
message: 'Enter the alias to assign to a deployment',
|
|
149
|
+
validate: (value) => !!value.trim(),
|
|
150
|
+
hint: 'The alias name is case insensitive and must be URL safe',
|
|
151
|
+
});
|
|
152
|
+
return aliasName.trim().toLowerCase();
|
|
153
|
+
}
|
|
154
|
+
async function resolveDeploymentIdAsync({ graphqlClient, deploymentIdentifier, aliasName, projectId, nonInteractive, }) {
|
|
155
|
+
if (deploymentIdentifier) {
|
|
156
|
+
return deploymentIdentifier;
|
|
157
|
+
}
|
|
158
|
+
if (nonInteractive) {
|
|
159
|
+
throw new Error('The `--id` flag must be set when running in `--non-interactive` mode.');
|
|
160
|
+
}
|
|
161
|
+
const deployment = await (0, deployment_1.selectWorkerDeploymentOnAppAsync)({
|
|
162
|
+
graphqlClient,
|
|
163
|
+
appId: projectId,
|
|
164
|
+
selectTitle: (0, chalk_1.default) `deployment to assign the {underline ${aliasName}} alias`,
|
|
165
|
+
});
|
|
166
|
+
if (!deployment) {
|
|
167
|
+
throw new Error('No deployments found for this project, create a new deployment with "eas deploy"');
|
|
168
|
+
}
|
|
169
|
+
return deployment.deploymentIdentifier;
|
|
170
|
+
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import EasCommand from '../../commandUtils/EasCommand';
|
|
2
|
+
import { EnvironmentVariableEnvironment } from '../../graphql/generated';
|
|
2
3
|
export default class WorkerDeploy extends EasCommand {
|
|
3
4
|
static description: string;
|
|
4
5
|
static aliases: string[];
|
|
6
|
+
static usage: string[];
|
|
5
7
|
static hidden: boolean;
|
|
6
8
|
static state: string;
|
|
7
|
-
static flags: {
|
|
9
|
+
static flags: {
|
|
10
|
+
environment: import("@oclif/core/lib/interfaces").OptionFlag<EnvironmentVariableEnvironment | undefined>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
prod: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
alias: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
15
|
+
id: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
16
|
+
'export-dir': import("@oclif/core/lib/interfaces").OptionFlag<string>;
|
|
17
|
+
};
|
|
8
18
|
static contextDefinition: {
|
|
9
19
|
loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
|
|
10
20
|
projectDir: import("../../commandUtils/context/ProjectDirContextField").default;
|
|
@@ -12,4 +22,5 @@ export default class WorkerDeploy extends EasCommand {
|
|
|
12
22
|
getDynamicPrivateProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicPrivateProjectConfigContextField;
|
|
13
23
|
};
|
|
14
24
|
runAsync(): Promise<void>;
|
|
25
|
+
private sanitizeFlags;
|
|
15
26
|
}
|
|
@@ -2,68 +2,52 @@
|
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const timeago_js_1 = require("@expo/timeago.js");
|
|
6
|
+
const core_1 = require("@oclif/core");
|
|
5
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
8
|
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
7
9
|
const path = tslib_1.__importStar(require("node:path"));
|
|
8
10
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
11
|
+
const flags_1 = require("../../commandUtils/flags");
|
|
9
12
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
10
13
|
const ora_1 = require("../../ora");
|
|
14
|
+
const json_1 = require("../../utils/json");
|
|
11
15
|
const progress_1 = require("../../utils/progress");
|
|
12
16
|
const WorkerAssets = tslib_1.__importStar(require("../../worker/assets"));
|
|
13
17
|
const deployment_1 = require("../../worker/deployment");
|
|
14
18
|
const upload_1 = require("../../worker/upload");
|
|
19
|
+
const logs_1 = require("../../worker/utils/logs");
|
|
15
20
|
const isDirectory = (directoryPath) => node_fs_1.default.promises
|
|
16
21
|
.stat(directoryPath)
|
|
17
22
|
.then(stat => stat.isDirectory())
|
|
18
23
|
.catch(() => false);
|
|
19
24
|
class WorkerDeploy extends EasCommand_1.default {
|
|
20
25
|
async runAsync() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
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".`);
|
|
26
|
+
// NOTE(cedric): `Log.warn` uses `console.log`, which is incorrect when running with `--json`
|
|
27
|
+
// eslint-disable-next-line no-console
|
|
28
|
+
console.warn(chalk_1.default.yellow('EAS Worker Deployments are in beta and subject to breaking changes.'));
|
|
29
|
+
const { flags: rawFlags } = await this.parse(_a);
|
|
30
|
+
const flags = this.sanitizeFlags(rawFlags);
|
|
31
|
+
if (flags.json) {
|
|
32
|
+
(0, json_1.enableJsonOutput)();
|
|
50
33
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
34
|
+
const { getDynamicPrivateProjectConfigAsync, loggedIn: { graphqlClient }, projectDir, } = await this.getContextAsync(_a, flags);
|
|
35
|
+
const [{ projectId }, projectDist] = await Promise.all([
|
|
36
|
+
getDynamicPrivateProjectConfigAsync(),
|
|
37
|
+
resolveExportedProjectAsync(flags, projectDir),
|
|
38
|
+
]);
|
|
39
|
+
logExportedProjectInfo(projectDist);
|
|
40
|
+
async function* emitWorkerTarballAsync(params) {
|
|
41
|
+
yield ['assets.json', JSON.stringify(params.assetMap)];
|
|
42
|
+
yield ['manifest.json', JSON.stringify(params.manifest)];
|
|
43
|
+
if (projectDist.type === 'server' && projectDist.serverPath) {
|
|
44
|
+
const workerFiles = WorkerAssets.listWorkerFilesAsync(projectDist.serverPath);
|
|
58
45
|
for await (const workerFile of workerFiles) {
|
|
59
46
|
yield [`server/${workerFile.normalizedPath}`, workerFile.data];
|
|
60
47
|
}
|
|
61
48
|
}
|
|
62
49
|
}
|
|
63
|
-
async function uploadTarballAsync(tarPath) {
|
|
64
|
-
const uploadUrl = await (0, deployment_1.getSignedDeploymentUrlAsync)(graphqlClient, exp, {
|
|
65
|
-
appId: projectId,
|
|
66
|
-
});
|
|
50
|
+
async function uploadTarballAsync(tarPath, uploadUrl) {
|
|
67
51
|
const { response } = await (0, upload_1.uploadAsync)({
|
|
68
52
|
url: uploadUrl,
|
|
69
53
|
filePath: tarPath,
|
|
@@ -74,7 +58,7 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
74
58
|
});
|
|
75
59
|
if (response.status === 413) {
|
|
76
60
|
throw new Error('Upload failed! (Payload too large)\n' +
|
|
77
|
-
`The files in "
|
|
61
|
+
`The files in "${path.relative(projectDir, projectDist.path)}" (at: ${projectDir}) exceed the maximum file size (10MB gzip).`);
|
|
78
62
|
}
|
|
79
63
|
else if (!response.ok) {
|
|
80
64
|
throw new Error(`Upload failed! (${response.statusText})`);
|
|
@@ -93,7 +77,8 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
93
77
|
}
|
|
94
78
|
// TODO(@kitten): Batch and upload multiple files in parallel
|
|
95
79
|
const uploadParams = [];
|
|
96
|
-
|
|
80
|
+
const assetPath = projectDist.type === 'server' ? projectDist.clientPath : projectDist.path;
|
|
81
|
+
for await (const asset of WorkerAssets.listAssetMapFilesAsync(assetPath, assetMap)) {
|
|
97
82
|
const uploadURL = uploads[asset.normalizedPath];
|
|
98
83
|
if (uploadURL) {
|
|
99
84
|
uploadParams.push({ url: uploadURL, filePath: asset.path });
|
|
@@ -110,9 +95,9 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
110
95
|
message(ratio) {
|
|
111
96
|
const percent = `${Math.floor(ratio * 100)}`;
|
|
112
97
|
const details = chalk_1.default.dim(`(${progress.pending} Pending, ${progress.transferred} Completed, ${progress.total} Total)`);
|
|
113
|
-
return `Uploading
|
|
98
|
+
return `Uploading assets: ${percent.padStart(3)}% ${details}`;
|
|
114
99
|
},
|
|
115
|
-
completedMessage: 'Uploaded assets
|
|
100
|
+
completedMessage: 'Uploaded assets',
|
|
116
101
|
});
|
|
117
102
|
try {
|
|
118
103
|
for await (const signal of (0, upload_1.batchUploadAsync)(uploadParams)) {
|
|
@@ -132,46 +117,151 @@ class WorkerDeploy extends EasCommand_1.default {
|
|
|
132
117
|
}
|
|
133
118
|
updateProgress({ isComplete: true });
|
|
134
119
|
}
|
|
135
|
-
let progress = (0, ora_1.ora)('Preparing worker upload');
|
|
136
120
|
let assetMap;
|
|
137
121
|
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
122
|
let deployResult;
|
|
123
|
+
let progress = (0, ora_1.ora)('Preparing project').start();
|
|
149
124
|
try {
|
|
150
|
-
|
|
125
|
+
const manifest = await WorkerAssets.createManifestAsync({
|
|
126
|
+
environment: flags.environment,
|
|
127
|
+
projectDir,
|
|
128
|
+
projectId,
|
|
129
|
+
}, graphqlClient);
|
|
130
|
+
assetMap = await WorkerAssets.createAssetMapAsync(projectDist.type === 'server' ? projectDist.clientPath : projectDist.path);
|
|
131
|
+
tarPath = await WorkerAssets.packFilesIterableAsync(emitWorkerTarballAsync({
|
|
132
|
+
assetMap,
|
|
133
|
+
manifest,
|
|
134
|
+
}));
|
|
135
|
+
const uploadUrl = await (0, deployment_1.getSignedDeploymentUrlAsync)(graphqlClient, {
|
|
136
|
+
appId: projectId,
|
|
137
|
+
deploymentIdentifier: flags.deploymentIdentifier,
|
|
138
|
+
// NOTE(cedric): this function might ask the user for a dev-domain name,
|
|
139
|
+
// when that happens, no ora spinner should be running.
|
|
140
|
+
onSetupDevDomain: () => progress.stop(),
|
|
141
|
+
nonInteractive: flags.nonInteractive,
|
|
142
|
+
});
|
|
143
|
+
progress.start('Creating deployment');
|
|
144
|
+
deployResult = await uploadTarballAsync(tarPath, uploadUrl);
|
|
145
|
+
progress.succeed('Created deployment');
|
|
151
146
|
}
|
|
152
147
|
catch (error) {
|
|
153
|
-
progress.fail('Failed to create
|
|
148
|
+
progress.fail('Failed to create deployment');
|
|
154
149
|
throw error;
|
|
155
150
|
}
|
|
156
|
-
progress.succeed('Created worker deployment');
|
|
157
151
|
await uploadAssetsAsync(assetMap, deployResult.uploads);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
152
|
+
let deploymentAlias = null;
|
|
153
|
+
if (flags.aliasName) {
|
|
154
|
+
progress = (0, ora_1.ora)((0, chalk_1.default) `Assigning alias {bold ${flags.aliasName}} to deployment`).start();
|
|
155
|
+
try {
|
|
156
|
+
deploymentAlias = await (0, deployment_1.assignWorkerDeploymentAliasAsync)({
|
|
157
|
+
graphqlClient,
|
|
158
|
+
appId: projectId,
|
|
159
|
+
deploymentId: deployResult.id,
|
|
160
|
+
aliasName: flags.aliasName,
|
|
161
|
+
});
|
|
162
|
+
// Only stop the spinner when not promoting to production
|
|
163
|
+
if (!flags.isProduction) {
|
|
164
|
+
progress.succeed((0, chalk_1.default) `Assigned alias {bold ${flags.aliasName}} to deployment`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
progress.fail((0, chalk_1.default) `Failed to assign {bold ${flags.aliasName}} alias to deployment`);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
let deploymentProdAlias = null;
|
|
173
|
+
if (flags.isProduction) {
|
|
174
|
+
try {
|
|
175
|
+
if (!flags.aliasName) {
|
|
176
|
+
progress = (0, ora_1.ora)((0, chalk_1.default) `Promoting deployment to {bold production}`).start();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
progress.text = (0, chalk_1.default) `Promoting deployment to {bold production}`;
|
|
180
|
+
}
|
|
181
|
+
deploymentProdAlias = await (0, deployment_1.assignWorkerDeploymentProductionAsync)({
|
|
182
|
+
graphqlClient,
|
|
183
|
+
appId: projectId,
|
|
184
|
+
deploymentId: deployResult.id,
|
|
185
|
+
});
|
|
186
|
+
progress.succeed(!flags.aliasName
|
|
187
|
+
? (0, chalk_1.default) `Promoted deployment to {bold production}`
|
|
188
|
+
: (0, chalk_1.default) `Promoted deployment to {bold production} with alias {bold ${flags.aliasName}}`);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
progress.fail('Failed to promote deployment to production');
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (flags.json) {
|
|
196
|
+
(0, json_1.printJsonOnlyOutput)((0, logs_1.formatWorkerDeploymentJson)({
|
|
197
|
+
projectId,
|
|
198
|
+
deployment: {
|
|
199
|
+
deploymentIdentifier: deployResult.id,
|
|
200
|
+
url: (0, logs_1.getDeploymentUrlFromFullName)(deployResult.fullName),
|
|
201
|
+
},
|
|
202
|
+
aliases: [deploymentAlias].filter(Boolean),
|
|
203
|
+
production: deploymentProdAlias,
|
|
204
|
+
}));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
161
207
|
log_1.default.addNewLineIfNone();
|
|
162
|
-
log_1.default.log(`🎉 Your
|
|
208
|
+
log_1.default.log(`🎉 Your deployment is ready`);
|
|
163
209
|
log_1.default.addNewLineIfNone();
|
|
164
|
-
log_1.default.log(
|
|
210
|
+
log_1.default.log((0, logs_1.formatWorkerDeploymentTable)({
|
|
211
|
+
projectId,
|
|
212
|
+
deployment: {
|
|
213
|
+
deploymentIdentifier: deployResult.id,
|
|
214
|
+
url: (0, logs_1.getDeploymentUrlFromFullName)(deployResult.fullName),
|
|
215
|
+
},
|
|
216
|
+
aliases: [deploymentAlias].filter(Boolean),
|
|
217
|
+
production: deploymentProdAlias,
|
|
218
|
+
}));
|
|
219
|
+
if (!deploymentProdAlias) {
|
|
220
|
+
log_1.default.addNewLineIfNone();
|
|
221
|
+
log_1.default.log('🚀 When you are ready to deploy to production:');
|
|
222
|
+
log_1.default.log((0, chalk_1.default) ` $ eas deploy {bold --prod}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
sanitizeFlags(flags) {
|
|
226
|
+
return {
|
|
227
|
+
nonInteractive: flags['non-interactive'],
|
|
228
|
+
json: flags['json'],
|
|
229
|
+
isProduction: !!flags.prod,
|
|
230
|
+
aliasName: flags.alias?.trim().toLowerCase(),
|
|
231
|
+
deploymentIdentifier: flags.id?.trim(),
|
|
232
|
+
exportDir: flags['export-dir'],
|
|
233
|
+
};
|
|
165
234
|
}
|
|
166
235
|
}
|
|
167
236
|
_a = WorkerDeploy;
|
|
168
|
-
WorkerDeploy.description = '
|
|
237
|
+
WorkerDeploy.description = 'Deploy your Expo web build';
|
|
169
238
|
WorkerDeploy.aliases = ['deploy'];
|
|
239
|
+
WorkerDeploy.usage = [(0, chalk_1.default) `deploy {dim [options]}`, `deploy --prod`];
|
|
170
240
|
// TODO(@kitten): Keep command hidden until worker deployments are live
|
|
171
241
|
WorkerDeploy.hidden = true;
|
|
172
242
|
WorkerDeploy.state = 'beta';
|
|
173
243
|
WorkerDeploy.flags = {
|
|
174
|
-
|
|
244
|
+
prod: core_1.Flags.boolean({
|
|
245
|
+
aliases: ['production'],
|
|
246
|
+
description: 'Create a new production deployment',
|
|
247
|
+
default: false,
|
|
248
|
+
}),
|
|
249
|
+
alias: core_1.Flags.string({
|
|
250
|
+
description: 'Custom alias to assign to the new deployment',
|
|
251
|
+
helpValue: 'name',
|
|
252
|
+
}),
|
|
253
|
+
id: core_1.Flags.string({
|
|
254
|
+
description: 'Custom unique identifier for the new deployment',
|
|
255
|
+
helpValue: 'xyz123',
|
|
256
|
+
}),
|
|
257
|
+
'export-dir': core_1.Flags.string({
|
|
258
|
+
description: 'Directory where the Expo project was exported',
|
|
259
|
+
helpValue: 'dir',
|
|
260
|
+
default: 'dist',
|
|
261
|
+
}),
|
|
262
|
+
// TODO(@kitten): Allow deployment identifier to be specified
|
|
263
|
+
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
264
|
+
...flags_1.EASEnvironmentFlag,
|
|
175
265
|
};
|
|
176
266
|
WorkerDeploy.contextDefinition = {
|
|
177
267
|
..._a.ContextOptions.DynamicProjectConfig,
|
|
@@ -179,3 +269,21 @@ WorkerDeploy.contextDefinition = {
|
|
|
179
269
|
..._a.ContextOptions.LoggedIn,
|
|
180
270
|
};
|
|
181
271
|
exports.default = WorkerDeploy;
|
|
272
|
+
async function resolveExportedProjectAsync(flags, projectDir) {
|
|
273
|
+
const exportPath = path.join(projectDir, flags.exportDir);
|
|
274
|
+
const serverPath = path.join(exportPath, 'server');
|
|
275
|
+
const clientPath = path.join(exportPath, 'client');
|
|
276
|
+
const [hasServerPath, hasClientPath, modifiedAt] = await Promise.all([
|
|
277
|
+
isDirectory(serverPath),
|
|
278
|
+
isDirectory(clientPath),
|
|
279
|
+
node_fs_1.default.promises.stat(exportPath).then(stat => stat.mtime),
|
|
280
|
+
]);
|
|
281
|
+
if (hasServerPath && hasClientPath) {
|
|
282
|
+
return { type: 'server', path: exportPath, modifiedAt, serverPath, clientPath };
|
|
283
|
+
}
|
|
284
|
+
return { type: 'static', path: exportPath, modifiedAt };
|
|
285
|
+
}
|
|
286
|
+
function logExportedProjectInfo(project) {
|
|
287
|
+
const modifiedAgo = (0, timeago_js_1.format)(project.modifiedAt);
|
|
288
|
+
log_1.default.log((0, chalk_1.default) `{dim > Project export: ${project.type} - created ${modifiedAgo}}`);
|
|
289
|
+
}
|