eas-cli 12.4.1 → 12.5.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 +66 -62
- package/build/build/evaluateConfigWithEnvVarsAsync.d.ts +1 -4
- package/build/build/evaluateConfigWithEnvVarsAsync.js +3 -6
- package/build/build/local.js +19 -11
- package/build/build/runBuildAndSubmit.d.ts +0 -2
- package/build/build/runBuildAndSubmit.js +0 -1
- package/build/commandUtils/flags.d.ts +0 -3
- package/build/commandUtils/flags.js +1 -15
- package/build/commands/build/index.d.ts +0 -2
- package/build/commands/build/index.js +0 -2
- package/build/commands/build/resign.d.ts +0 -1
- package/build/commands/build/resign.js +0 -2
- package/build/commands/build/version/get.d.ts +0 -1
- package/build/commands/build/version/get.js +0 -2
- package/build/commands/build/version/set.d.ts +0 -1
- package/build/commands/build/version/set.js +0 -3
- package/build/commands/build/version/sync.d.ts +0 -1
- package/build/commands/build/version/sync.js +0 -3
- package/build/commands/config.d.ts +0 -1
- package/build/commands/config.js +0 -2
- package/build/commands/env/exec.d.ts +23 -0
- package/build/commands/env/exec.js +124 -0
- package/build/commands/submit/internal.d.ts +24 -0
- package/build/commands/submit/internal.js +168 -0
- package/build/commands/update/republish.d.ts +2 -0
- package/build/commands/update/republish.js +34 -4
- package/build/commands/worker/deploy.js +15 -14
- package/build/credentials/manager/Actions.d.ts +4 -2
- package/build/credentials/manager/Actions.js +2 -0
- package/build/credentials/manager/AndroidActions.js +5 -0
- package/build/credentials/manager/IosActions.js +5 -0
- package/build/credentials/manager/ManageAndroid.js +3 -0
- package/build/credentials/manager/ManageIos.js +3 -0
- package/build/graphql/generated.d.ts +165 -32
- package/build/graphql/generated.js +1 -0
- package/build/graphql/queries/AppStoreConnectApiKeyQuery.d.ts +8 -0
- package/build/graphql/queries/AppStoreConnectApiKeyQuery.js +32 -0
- package/build/graphql/queries/GoogleServiceAccountKeyQuery.d.ts +6 -0
- package/build/graphql/queries/GoogleServiceAccountKeyQuery.js +25 -0
- package/build/graphql/types/Submission.js +1 -1
- package/build/project/android/applicationId.js +3 -3
- package/build/project/expoConfig.js +0 -15
- package/build/project/ios/bundleIdentifier.js +3 -3
- package/build/project/publish.js +3 -2
- package/build/submit/ArchiveSource.js +15 -1
- package/build/submit/BaseSubmitter.d.ts +1 -0
- package/build/submit/BaseSubmitter.js +5 -2
- package/build/submit/android/AndroidSubmitCommand.d.ts +2 -2
- package/build/submit/android/AndroidSubmitCommand.js +1 -1
- package/build/submit/ios/IosSubmitCommand.d.ts +2 -2
- package/build/submit/ios/IosSubmitCommand.js +1 -1
- package/build/submit/submit.js +2 -1
- package/build/submit/utils/builds.js +22 -10
- package/build/submit/utils/logs.js +16 -17
- package/build/update/getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync.d.ts +5 -0
- package/build/update/{getBranchNameFromChannelNameAsync.js → getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync.js} +8 -7
- package/build/update/republish.js +2 -2
- package/build/utils/prompts.js +3 -3
- package/build/worker/assets.d.ts +1 -1
- package/build/worker/assets.js +4 -2
- package/build/worker/deployment.d.ts +10 -0
- package/build/worker/deployment.js +38 -27
- package/build/worker/upload.js +4 -6
- package/build/worker/utils/logs.d.ts +14 -13
- package/build/worker/utils/logs.js +18 -18
- package/oclif.manifest.json +103 -79
- package/package.json +7 -6
- package/build/update/getBranchNameFromChannelNameAsync.d.ts +0 -2
|
@@ -8,6 +8,7 @@ const url_1 = require("url");
|
|
|
8
8
|
const uuid = tslib_1.__importStar(require("uuid"));
|
|
9
9
|
const builds_1 = require("./utils/builds");
|
|
10
10
|
const files_1 = require("./utils/files");
|
|
11
|
+
const generated_1 = require("../graphql/generated");
|
|
11
12
|
const BuildQuery_1 = require("../graphql/queries/BuildQuery");
|
|
12
13
|
const AppPlatform_1 = require("../graphql/types/AppPlatform");
|
|
13
14
|
const log_1 = tslib_1.__importStar(require("../log"));
|
|
@@ -26,6 +27,15 @@ var ArchiveSourceType;
|
|
|
26
27
|
ArchiveSourceType[ArchiveSourceType["prompt"] = 6] = "prompt";
|
|
27
28
|
ArchiveSourceType[ArchiveSourceType["gcs"] = 7] = "gcs";
|
|
28
29
|
})(ArchiveSourceType || (exports.ArchiveSourceType = ArchiveSourceType = {}));
|
|
30
|
+
const buildStatusMapping = {
|
|
31
|
+
[generated_1.BuildStatus.New]: 'new',
|
|
32
|
+
[generated_1.BuildStatus.InQueue]: 'in queue',
|
|
33
|
+
[generated_1.BuildStatus.InProgress]: 'in progress',
|
|
34
|
+
[generated_1.BuildStatus.Finished]: 'finished',
|
|
35
|
+
[generated_1.BuildStatus.Errored]: 'errored',
|
|
36
|
+
[generated_1.BuildStatus.PendingCancel]: 'canceled',
|
|
37
|
+
[generated_1.BuildStatus.Canceled]: 'canceled',
|
|
38
|
+
};
|
|
29
39
|
async function getArchiveAsync(ctx, source) {
|
|
30
40
|
switch (source.sourceType) {
|
|
31
41
|
case ArchiveSourceType.prompt: {
|
|
@@ -200,7 +210,7 @@ async function handleBuildListSourceAsync(ctx) {
|
|
|
200
210
|
}
|
|
201
211
|
}
|
|
202
212
|
function formatBuildChoice(build) {
|
|
203
|
-
const { id, updatedAt, runtimeVersion, buildProfile, gitCommitHash, gitCommitMessage, channel, message, } = build;
|
|
213
|
+
const { id, updatedAt, runtimeVersion, buildProfile, gitCommitHash, gitCommitMessage, channel, message, status, } = build;
|
|
204
214
|
const buildDate = new Date(updatedAt);
|
|
205
215
|
const splitCommitMessage = gitCommitMessage?.split('\n');
|
|
206
216
|
const formattedCommitData = gitCommitHash && splitCommitMessage && splitCommitMessage.length > 0
|
|
@@ -218,6 +228,7 @@ function formatBuildChoice(build) {
|
|
|
218
228
|
? chalk_1.default.bold(message.length > 200 ? `${message.slice(0, 200)}...` : message)
|
|
219
229
|
: null,
|
|
220
230
|
},
|
|
231
|
+
{ name: 'Status', value: buildStatusMapping[status] },
|
|
221
232
|
];
|
|
222
233
|
const filteredDescriptionArray = descriptionItems
|
|
223
234
|
.filter(item => item.value)
|
|
@@ -230,6 +241,9 @@ function formatBuildChoice(build) {
|
|
|
230
241
|
};
|
|
231
242
|
}
|
|
232
243
|
async function handlePromptSourceAsync(ctx) {
|
|
244
|
+
if (ctx.nonInteractive) {
|
|
245
|
+
throw new Error('Please run this command with appropriate input.');
|
|
246
|
+
}
|
|
233
247
|
const { sourceType: sourceTypeRaw } = await (0, prompts_1.promptAsync)({
|
|
234
248
|
name: 'sourceType',
|
|
235
249
|
type: 'select',
|
|
@@ -25,6 +25,7 @@ export default abstract class BaseSubmitter<P extends Platform, ResolvedSourceOp
|
|
|
25
25
|
[K in keyof ResolvedSourceOptions]: () => Promise<ResolvedSourceOptions[K]>;
|
|
26
26
|
}, sourceOptionAnalytics: Record<keyof ResolvedSourceOptions, AnalyticEvents>);
|
|
27
27
|
private getSourceOptionsAsync;
|
|
28
|
+
getSubmissionInputAsync(): Promise<SubmissionInput<P>>;
|
|
28
29
|
submitAsync(): Promise<SubmissionFragment>;
|
|
29
30
|
abstract createSubmissionInputAsync(resolvedOptions: ResolvedSourceOptions): Promise<SubmissionInput<P>>;
|
|
30
31
|
formatArchive(archive: ResolvedArchiveSource): Pick<SubmissionInput<P>, 'archiveSource' | 'buildId'>;
|
|
@@ -32,9 +32,12 @@ class BaseSubmitter {
|
|
|
32
32
|
}
|
|
33
33
|
return resolvedSourceOptions;
|
|
34
34
|
}
|
|
35
|
-
async
|
|
35
|
+
async getSubmissionInputAsync() {
|
|
36
36
|
const resolvedSourceOptions = await this.getSourceOptionsAsync();
|
|
37
|
-
|
|
37
|
+
return await this.createSubmissionInputAsync(resolvedSourceOptions);
|
|
38
|
+
}
|
|
39
|
+
async submitAsync() {
|
|
40
|
+
const input = await this.getSubmissionInputAsync();
|
|
38
41
|
return await this.createSubmissionWithAnalyticsAsync(input);
|
|
39
42
|
}
|
|
40
43
|
formatArchive(archive) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Platform } from '@expo/eas-build-job';
|
|
2
|
-
import
|
|
2
|
+
import AndroidSubmitter from './AndroidSubmitter';
|
|
3
3
|
import { SubmissionContext } from '../context';
|
|
4
4
|
export default class AndroidSubmitCommand {
|
|
5
5
|
private ctx;
|
|
6
6
|
constructor(ctx: SubmissionContext<Platform.ANDROID>);
|
|
7
|
-
runAsync(): Promise<
|
|
7
|
+
runAsync(): Promise<AndroidSubmitter>;
|
|
8
8
|
private getAndroidSubmissionOptionsAsync;
|
|
9
9
|
private maybeGetAndroidPackageFromCurrentProjectAsync;
|
|
10
10
|
private resolveTrack;
|
|
@@ -36,7 +36,7 @@ class AndroidSubmitCommand {
|
|
|
36
36
|
}
|
|
37
37
|
const submissionOptions = await this.getAndroidSubmissionOptionsAsync(archiveSourceValue);
|
|
38
38
|
const submitter = new AndroidSubmitter_1.default(this.ctx, submissionOptions, archive);
|
|
39
|
-
return
|
|
39
|
+
return submitter;
|
|
40
40
|
}
|
|
41
41
|
async getAndroidSubmissionOptionsAsync(archiveSource) {
|
|
42
42
|
const track = this.resolveTrack();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Platform } from '@expo/eas-build-job';
|
|
2
|
-
import
|
|
2
|
+
import IosSubmitter from './IosSubmitter';
|
|
3
3
|
import { SubmissionContext } from '../context';
|
|
4
4
|
export default class IosSubmitCommand {
|
|
5
5
|
private ctx;
|
|
6
6
|
constructor(ctx: SubmissionContext<Platform.IOS>);
|
|
7
|
-
runAsync(): Promise<
|
|
7
|
+
runAsync(): Promise<IosSubmitter>;
|
|
8
8
|
private resolveSubmissionOptionsAsync;
|
|
9
9
|
private resolveCredentialSubmissionOptionsAsync;
|
|
10
10
|
private resolveAppSpecificPasswordSource;
|
|
@@ -38,7 +38,7 @@ class IosSubmitCommand {
|
|
|
38
38
|
}
|
|
39
39
|
const options = await this.resolveSubmissionOptionsAsync(archiveSourceValue);
|
|
40
40
|
const submitter = new IosSubmitter_1.default(this.ctx, options, archive);
|
|
41
|
-
return
|
|
41
|
+
return submitter;
|
|
42
42
|
}
|
|
43
43
|
async resolveSubmissionOptionsAsync(archiveSource) {
|
|
44
44
|
const credentialsSource = await this.resolveCredentialSubmissionOptionsAsync();
|
package/build/submit/submit.js
CHANGED
|
@@ -18,7 +18,8 @@ async function submitAsync(ctx) {
|
|
|
18
18
|
const command = ctx.platform === eas_build_job_1.Platform.ANDROID
|
|
19
19
|
? new AndroidSubmitCommand_1.default(ctx)
|
|
20
20
|
: new IosSubmitCommand_1.default(ctx);
|
|
21
|
-
|
|
21
|
+
const submitter = await command.runAsync();
|
|
22
|
+
return await submitter.submitAsync();
|
|
22
23
|
}, {
|
|
23
24
|
attemptEvent: AnalyticsManager_1.SubmissionEvent.SUBMIT_COMMAND_ATTEMPT,
|
|
24
25
|
successEvent: AnalyticsManager_1.SubmissionEvent.SUBMIT_COMMAND_SUCCESS,
|
|
@@ -4,15 +4,27 @@ exports.getRecentBuildsForSubmissionAsync = void 0;
|
|
|
4
4
|
const generated_1 = require("../../graphql/generated");
|
|
5
5
|
const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
|
|
6
6
|
async function getRecentBuildsForSubmissionAsync(graphqlClient, platform, appId, { limit = 1 } = {}) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
const allowedStatuses = [
|
|
8
|
+
generated_1.BuildStatus.New,
|
|
9
|
+
generated_1.BuildStatus.InQueue,
|
|
10
|
+
generated_1.BuildStatus.InProgress,
|
|
11
|
+
generated_1.BuildStatus.Finished,
|
|
12
|
+
];
|
|
13
|
+
const buildsPromises = [];
|
|
14
|
+
for (const buildStatus of allowedStatuses) {
|
|
15
|
+
buildsPromises.push(BuildQuery_1.BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
|
16
|
+
appId,
|
|
17
|
+
limit,
|
|
18
|
+
offset: 0,
|
|
19
|
+
filter: {
|
|
20
|
+
platform,
|
|
21
|
+
distribution: generated_1.DistributionType.Store,
|
|
22
|
+
status: buildStatus,
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
const builds = (await Promise.all(buildsPromises)).reduce((acc, value) => acc.concat(value), []);
|
|
27
|
+
builds.sort((buildA, buildB) => (buildA.createdAt > buildB.createdAt ? -1 : 1));
|
|
28
|
+
return builds.slice(0, limit);
|
|
17
29
|
}
|
|
18
30
|
exports.getRecentBuildsForSubmissionAsync = getRecentBuildsForSubmissionAsync;
|
|
@@ -22,23 +22,22 @@ async function displayLogsAsync(submission, { verbose = false, moreSubmissions =
|
|
|
22
22
|
}
|
|
23
23
|
exports.displayLogsAsync = displayLogsAsync;
|
|
24
24
|
async function downloadAndPrintSubmissionLogsAsync(submission) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
log_1.default.log(msgWithPrefix);
|
|
25
|
+
for (const logFile of submission.logFiles) {
|
|
26
|
+
const response = await (0, fetch_1.default)(logFile);
|
|
27
|
+
const logs = parseLogs(await response.text());
|
|
28
|
+
log_1.default.addNewLineIfNone();
|
|
29
|
+
const prefix = chalk_1.default.blueBright('[logs] ');
|
|
30
|
+
for (const { level, msg } of logs) {
|
|
31
|
+
const msgWithPrefix = `${prefix}${msg}`;
|
|
32
|
+
if (level === 'error') {
|
|
33
|
+
log_1.default.error(msgWithPrefix);
|
|
34
|
+
}
|
|
35
|
+
else if (level === 'warn') {
|
|
36
|
+
log_1.default.warn(msgWithPrefix);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
log_1.default.log(msgWithPrefix);
|
|
40
|
+
}
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
|
2
|
+
export declare function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(graphqlClient: ExpoGraphqlClient, projectId: string, channelName: string): Promise<{
|
|
3
|
+
branchName: string;
|
|
4
|
+
branchId: string;
|
|
5
|
+
}>;
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync = void 0;
|
|
4
4
|
const queries_1 = require("../branch/queries");
|
|
5
5
|
const errors_1 = require("../channel/errors");
|
|
6
6
|
const queries_2 = require("../channel/queries");
|
|
7
7
|
const ChannelQuery_1 = require("../graphql/queries/ChannelQuery");
|
|
8
|
-
async function
|
|
9
|
-
let
|
|
8
|
+
async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(graphqlClient, projectId, channelName) {
|
|
9
|
+
let branchInfo;
|
|
10
10
|
try {
|
|
11
11
|
const channel = await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
12
12
|
appId: projectId,
|
|
13
13
|
channelName,
|
|
14
14
|
});
|
|
15
15
|
if (channel.updateBranches.length === 1) {
|
|
16
|
-
|
|
16
|
+
const branch = channel.updateBranches[0];
|
|
17
|
+
branchInfo = { branchId: branch.id, branchName: branch.name };
|
|
17
18
|
}
|
|
18
19
|
else if (channel.updateBranches.length === 0) {
|
|
19
20
|
throw new Error("Channel has no branches associated with it. Run 'eas channel:edit' to map a branch");
|
|
@@ -38,8 +39,8 @@ async function getBranchNameFromChannelNameAsync(graphqlClient, projectId, chann
|
|
|
38
39
|
if (!newChannel) {
|
|
39
40
|
throw new Error(`Could not create channel with name ${channelName} on project with id ${projectId}`);
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
branchInfo = { branchId, branchName: channelName };
|
|
42
43
|
}
|
|
43
|
-
return
|
|
44
|
+
return branchInfo;
|
|
44
45
|
}
|
|
45
|
-
exports.
|
|
46
|
+
exports.getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync = getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync;
|
|
@@ -26,7 +26,7 @@ async function republishAsync({ graphqlClient, app, updatesToPublish, targetBran
|
|
|
26
26
|
update.branchId === arbitraryUpdate.branchId &&
|
|
27
27
|
update.branchName === arbitraryUpdate.branchName &&
|
|
28
28
|
update.runtimeVersion === arbitraryUpdate.runtimeVersion;
|
|
29
|
-
(0, assert_1.default)(updatesToPublish.every(isSameGroup), 'All updates must belong to the same update group');
|
|
29
|
+
(0, assert_1.default)(updatesToPublish.every(isSameGroup), 'All updates being republished must belong to the same update group');
|
|
30
30
|
(0, assert_1.default)(updatesToPublish.every(u => u.isRollBackToEmbedded) ||
|
|
31
31
|
updatesToPublish.every(u => !u.isRollBackToEmbedded), 'All updates must either be roll back to embedded updates or not');
|
|
32
32
|
const { runtimeVersion } = arbitraryUpdate;
|
|
@@ -44,7 +44,7 @@ async function republishAsync({ graphqlClient, app, updatesToPublish, targetBran
|
|
|
44
44
|
throw new Error('Republished updates must use the same code signing key and algorithm as original update');
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
log_1.default.withTick(`The republished update group will be signed`);
|
|
47
|
+
log_1.default.withTick(`The republished update group will be signed with the same code signing key and algorithm as the original update`);
|
|
48
48
|
}
|
|
49
49
|
const publishIndicator = (0, ora_1.ora)('Republishing...').start();
|
|
50
50
|
let updatesRepublished;
|
package/build/utils/prompts.js
CHANGED
|
@@ -10,9 +10,9 @@ async function promptVariableEnvironmentAsync(nonInteractive) {
|
|
|
10
10
|
throw new Error('The `--environment` flag must be set when running in `--non-interactive` mode.');
|
|
11
11
|
}
|
|
12
12
|
return await (0, prompts_1.selectAsync)('Select environment:', [
|
|
13
|
-
{ title: '
|
|
14
|
-
{ title: '
|
|
15
|
-
{ title: '
|
|
13
|
+
{ title: 'development', value: generated_1.EnvironmentVariableEnvironment.Development },
|
|
14
|
+
{ title: 'preview', value: generated_1.EnvironmentVariableEnvironment.Preview },
|
|
15
|
+
{ title: 'production', value: generated_1.EnvironmentVariableEnvironment.Production },
|
|
16
16
|
]);
|
|
17
17
|
}
|
|
18
18
|
exports.promptVariableEnvironmentAsync = promptVariableEnvironmentAsync;
|
package/build/worker/assets.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ interface AssetMapOptions {
|
|
|
10
10
|
/** Mapping of normalized file paths to a SHA512 hash */
|
|
11
11
|
export type AssetMap = Record<string, string>;
|
|
12
12
|
/** Creates an asset map of a given target path */
|
|
13
|
-
declare function createAssetMapAsync(assetPath
|
|
13
|
+
declare function createAssetMapAsync(assetPath?: string, options?: AssetMapOptions): Promise<AssetMap>;
|
|
14
14
|
export interface Manifest {
|
|
15
15
|
env: Record<string, string | undefined>;
|
|
16
16
|
}
|
package/build/worker/assets.js
CHANGED
|
@@ -65,8 +65,10 @@ function listFilesRecursively(basePath) {
|
|
|
65
65
|
/** Creates an asset map of a given target path */
|
|
66
66
|
async function createAssetMapAsync(assetPath, options) {
|
|
67
67
|
const map = Object.create(null);
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
if (assetPath) {
|
|
69
|
+
for await (const file of listFilesRecursively(assetPath)) {
|
|
70
|
+
map[file.normalizedPath] = await computeSha512HashAsync(file.path, options?.hashOptions);
|
|
71
|
+
}
|
|
70
72
|
}
|
|
71
73
|
return map;
|
|
72
74
|
}
|
|
@@ -10,6 +10,16 @@ export declare function getSignedDeploymentUrlAsync(graphqlClient: ExpoGraphqlCl
|
|
|
10
10
|
/** If the terminal is running in non interactive mode or not */
|
|
11
11
|
nonInteractive?: boolean;
|
|
12
12
|
}): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Assign a dev domain name to a project.
|
|
15
|
+
* - When running in interactive mode, it will prompt the user with a suggested domain name.
|
|
16
|
+
* - When running in non interactive mode, it will auto-assign the suggested domain name.
|
|
17
|
+
*/
|
|
18
|
+
export declare function assignDevDomainNameAsync({ graphqlClient, appId, nonInteractive, }: {
|
|
19
|
+
graphqlClient: ExpoGraphqlClient;
|
|
20
|
+
appId: string;
|
|
21
|
+
nonInteractive?: boolean;
|
|
22
|
+
}): ReturnType<typeof DeploymentsMutation.assignDevDomainNameAsync>;
|
|
13
23
|
export declare function assignWorkerDeploymentAliasAsync({ graphqlClient, appId, deploymentId, aliasName, }: {
|
|
14
24
|
graphqlClient: ExpoGraphqlClient;
|
|
15
25
|
appId: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.selectWorkerDeploymentOnAppAsync = exports.assignWorkerDeploymentProductionAsync = exports.assignWorkerDeploymentAliasAsync = exports.getSignedDeploymentUrlAsync = void 0;
|
|
3
|
+
exports.selectWorkerDeploymentOnAppAsync = exports.assignWorkerDeploymentProductionAsync = exports.assignWorkerDeploymentAliasAsync = exports.assignDevDomainNameAsync = exports.getSignedDeploymentUrlAsync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
6
|
const mutations_1 = require("./mutations");
|
|
@@ -19,23 +19,20 @@ async function getSignedDeploymentUrlAsync(graphqlClient, options) {
|
|
|
19
19
|
}
|
|
20
20
|
catch (error) {
|
|
21
21
|
const isMissingDevDomain = error?.graphQLErrors?.some(e => ['APP_NO_DEV_DOMAIN_NAME'].includes(e?.extensions?.errorCode));
|
|
22
|
+
// Throw unexpected errors eagerly
|
|
22
23
|
if (!isMissingDevDomain) {
|
|
23
24
|
throw error;
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
-
throw new Error('The project URL needs to be set up, but the terminal is running in non-interactive mode.');
|
|
27
|
-
}
|
|
28
|
-
const suggestedDevDomainName = await queries_1.DeploymentsQuery.getSuggestedDevDomainByAppIdAsync(graphqlClient, { appId: options.appId });
|
|
26
|
+
// Ensure the callback is invoked, containing cleanup logic for possible spinners
|
|
29
27
|
options.onSetupDevDomain?.();
|
|
30
|
-
|
|
28
|
+
// Assign the dev domain name by prompting the user
|
|
29
|
+
await assignDevDomainNameAsync({
|
|
31
30
|
graphqlClient,
|
|
32
31
|
appId: options.appId,
|
|
33
|
-
|
|
34
|
-
});
|
|
35
|
-
return await mutations_1.DeploymentsMutation.createSignedDeploymentUrlAsync(graphqlClient, {
|
|
36
|
-
appId: options.appId,
|
|
37
|
-
deploymentIdentifier: options.deploymentIdentifier,
|
|
32
|
+
nonInteractive: options.nonInteractive,
|
|
38
33
|
});
|
|
34
|
+
// Retry creating the signed URL
|
|
35
|
+
return await getSignedDeploymentUrlAsync(graphqlClient, options);
|
|
39
36
|
}
|
|
40
37
|
}
|
|
41
38
|
exports.getSignedDeploymentUrlAsync = getSignedDeploymentUrlAsync;
|
|
@@ -55,23 +52,23 @@ function formatDevDomainName(name = '') {
|
|
|
55
52
|
.replace(DEV_DOMAIN_INVALID_MULTIPLE_HYPHENS, '-')
|
|
56
53
|
.trim();
|
|
57
54
|
}
|
|
58
|
-
async function
|
|
55
|
+
async function promptDevDomainNameAsync(initialDevDomain) {
|
|
59
56
|
const rootDomain = `.${logs_1.EXPO_BASE_DOMAIN}.app`;
|
|
60
57
|
const memoizedFormatDevDomainName = (0, memoize_1.memoize)(formatDevDomainName);
|
|
61
58
|
const { name } = await (0, prompts_1.promptAsync)({
|
|
62
59
|
type: 'text',
|
|
63
60
|
name: 'name',
|
|
64
|
-
message: 'Choose a URL for your project:',
|
|
65
|
-
initial,
|
|
61
|
+
message: 'Choose a preview URL for your project:',
|
|
62
|
+
initial: initialDevDomain,
|
|
66
63
|
validate: (value) => {
|
|
67
64
|
if (!value) {
|
|
68
|
-
return 'You have to choose a URL for your project';
|
|
65
|
+
return 'You have to choose a preview URL for your project';
|
|
69
66
|
}
|
|
70
67
|
if (value.length < 3) {
|
|
71
|
-
return '
|
|
68
|
+
return 'Preview URLs must be at least 3 characters long';
|
|
72
69
|
}
|
|
73
70
|
if (value.endsWith('-')) {
|
|
74
|
-
return '
|
|
71
|
+
return 'Preview URLs cannot end with a hyphen (-)';
|
|
75
72
|
}
|
|
76
73
|
return true;
|
|
77
74
|
},
|
|
@@ -95,29 +92,43 @@ async function chooseDevDomainNameAsync({ graphqlClient, appId, initial, }) {
|
|
|
95
92
|
}
|
|
96
93
|
},
|
|
97
94
|
});
|
|
95
|
+
// This should never happen due to the validation, if it does its an error
|
|
98
96
|
if (!name) {
|
|
99
|
-
throw new Error('No
|
|
97
|
+
throw new Error('No preview URL provided, aborting deployment.');
|
|
98
|
+
}
|
|
99
|
+
return name;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Assign a dev domain name to a project.
|
|
103
|
+
* - When running in interactive mode, it will prompt the user with a suggested domain name.
|
|
104
|
+
* - When running in non interactive mode, it will auto-assign the suggested domain name.
|
|
105
|
+
*/
|
|
106
|
+
async function assignDevDomainNameAsync({ graphqlClient, appId, nonInteractive, }) {
|
|
107
|
+
let devDomainName = await queries_1.DeploymentsQuery.getSuggestedDevDomainByAppIdAsync(graphqlClient, {
|
|
108
|
+
appId,
|
|
109
|
+
});
|
|
110
|
+
if (!nonInteractive) {
|
|
111
|
+
devDomainName = await promptDevDomainNameAsync(devDomainName);
|
|
100
112
|
}
|
|
101
113
|
try {
|
|
102
|
-
|
|
114
|
+
return await mutations_1.DeploymentsMutation.assignDevDomainNameAsync(graphqlClient, {
|
|
103
115
|
appId,
|
|
104
|
-
name,
|
|
116
|
+
name: devDomainName,
|
|
105
117
|
});
|
|
106
|
-
if (!success) {
|
|
107
|
-
throw new Error('Failed to assign project URL');
|
|
108
|
-
}
|
|
109
118
|
}
|
|
110
119
|
catch (error) {
|
|
111
120
|
const isChosenNameTaken = error?.graphQLErrors?.some(e => ['DEV_DOMAIN_NAME_TAKEN'].includes(e?.extensions?.errorCode));
|
|
112
|
-
|
|
113
|
-
log_1.default.error(`The project URL "${name}" is already taken, choose a different name.`);
|
|
114
|
-
await chooseDevDomainNameAsync({ graphqlClient, appId, initial });
|
|
115
|
-
}
|
|
121
|
+
// Throw unexpected errors eagerly
|
|
116
122
|
if (!isChosenNameTaken) {
|
|
117
123
|
throw error;
|
|
118
124
|
}
|
|
125
|
+
if (!nonInteractive) {
|
|
126
|
+
log_1.default.error(`The preview URL "${devDomainName}" is already taken, choose a different URL.`);
|
|
127
|
+
}
|
|
128
|
+
return await assignDevDomainNameAsync({ graphqlClient, appId, nonInteractive });
|
|
119
129
|
}
|
|
120
130
|
}
|
|
131
|
+
exports.assignDevDomainNameAsync = assignDevDomainNameAsync;
|
|
121
132
|
async function assignWorkerDeploymentAliasAsync({ graphqlClient, appId, deploymentId, aliasName, }) {
|
|
122
133
|
return await mutations_1.DeploymentsMutation.assignAliasAsync(graphqlClient, {
|
|
123
134
|
appId,
|
package/build/worker/upload.js
CHANGED
|
@@ -126,16 +126,14 @@ async function* batchUploadAsync(uploads) {
|
|
|
126
126
|
}
|
|
127
127
|
yield await Promise.race(queue);
|
|
128
128
|
}
|
|
129
|
+
if (queue.size > 0) {
|
|
130
|
+
controller.abort();
|
|
131
|
+
}
|
|
129
132
|
}
|
|
130
133
|
catch (error) {
|
|
131
|
-
if (
|
|
134
|
+
if (error.name !== 'AbortError') {
|
|
132
135
|
throw error;
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
|
-
finally {
|
|
136
|
-
if (queue.size > 0) {
|
|
137
|
-
controller.abort();
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
138
|
}
|
|
141
139
|
exports.batchUploadAsync = batchUploadAsync;
|
|
@@ -8,7 +8,7 @@ type WorkerDeploymentData = {
|
|
|
8
8
|
/** The actual deployment information */
|
|
9
9
|
deployment: Pick<WorkerDeploymentFragment, 'deploymentIdentifier' | 'url'>;
|
|
10
10
|
/** All modified aliases of the deployment, if any */
|
|
11
|
-
aliases?: WorkerDeploymentAliasFragment[];
|
|
11
|
+
aliases?: (WorkerDeploymentAliasFragment | null)[];
|
|
12
12
|
/** The production promoting alias of the deployment, if any */
|
|
13
13
|
production?: WorkerDeploymentAliasFragment | null;
|
|
14
14
|
};
|
|
@@ -16,19 +16,20 @@ export declare function formatWorkerDeploymentTable(data: WorkerDeploymentData):
|
|
|
16
16
|
type WorkerDeploymentOutput = {
|
|
17
17
|
/** The absolute URL to the dashboard on `expo.dev` */
|
|
18
18
|
dashboardUrl: string;
|
|
19
|
-
/** The deployment
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
/** The deployment identifier */
|
|
20
|
+
identifier: string;
|
|
21
|
+
/** The deployment URL */
|
|
22
|
+
url: string;
|
|
23
|
+
/** Custom aliases, if assigned */
|
|
24
|
+
aliases?: {
|
|
25
|
+
id: string;
|
|
26
|
+
url: string;
|
|
27
|
+
name: string;
|
|
28
|
+
}[];
|
|
29
|
+
/** The production alias, if assigned */
|
|
30
|
+
production?: {
|
|
31
|
+
id: string;
|
|
22
32
|
url: string;
|
|
23
|
-
aliases?: {
|
|
24
|
-
id: string;
|
|
25
|
-
name: string;
|
|
26
|
-
url: string;
|
|
27
|
-
}[];
|
|
28
|
-
production?: {
|
|
29
|
-
id: string;
|
|
30
|
-
url: string;
|
|
31
|
-
};
|
|
32
33
|
};
|
|
33
34
|
};
|
|
34
35
|
export declare function formatWorkerDeploymentJson(data: WorkerDeploymentData): WorkerDeploymentOutput;
|
|
@@ -19,7 +19,10 @@ function formatWorkerDeploymentTable(data) {
|
|
|
19
19
|
{ label: 'Deployment URL', value: data.deployment.url },
|
|
20
20
|
];
|
|
21
21
|
if (data.aliases?.length) {
|
|
22
|
-
|
|
22
|
+
const alias = data.aliases.filter(Boolean)[0];
|
|
23
|
+
if (alias) {
|
|
24
|
+
fields.push({ label: 'Alias URL', value: alias.url });
|
|
25
|
+
}
|
|
23
26
|
}
|
|
24
27
|
if (data.production) {
|
|
25
28
|
fields.push({ label: 'Production URL', value: data.production.url });
|
|
@@ -30,25 +33,22 @@ function formatWorkerDeploymentTable(data) {
|
|
|
30
33
|
}
|
|
31
34
|
exports.formatWorkerDeploymentTable = formatWorkerDeploymentTable;
|
|
32
35
|
function formatWorkerDeploymentJson(data) {
|
|
36
|
+
const aliases = !data.aliases
|
|
37
|
+
? []
|
|
38
|
+
: data.aliases.filter(Boolean);
|
|
33
39
|
return {
|
|
34
40
|
dashboardUrl: getDashboardUrl(data.projectId),
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
? undefined
|
|
47
|
-
: {
|
|
48
|
-
id: data.production.id,
|
|
49
|
-
url: data.production.url,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
41
|
+
identifier: data.deployment.deploymentIdentifier,
|
|
42
|
+
url: data.deployment.url,
|
|
43
|
+
aliases: !aliases.length
|
|
44
|
+
? undefined
|
|
45
|
+
: aliases.map(alias => ({ id: alias.id, url: alias.url, name: alias.aliasName })),
|
|
46
|
+
production: !data.production
|
|
47
|
+
? undefined
|
|
48
|
+
: {
|
|
49
|
+
id: data.production.id,
|
|
50
|
+
url: data.production.url,
|
|
51
|
+
},
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
exports.formatWorkerDeploymentJson = formatWorkerDeploymentJson;
|