eas-cli 0.48.1 → 0.50.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 +144 -50
- package/build/build/build.d.ts +6 -2
- package/build/build/build.js +191 -104
- package/build/build/local.js +1 -1
- package/build/build/runBuildAndSubmit.js +5 -1
- package/build/build/utils/printBuildInfo.js +1 -2
- package/build/build/utils/url.js +6 -8
- package/build/credentials/context.js +5 -0
- package/build/credentials/ios/actions/AscApiKeyUtils.js +0 -1
- package/build/credentials/ios/actions/ConfigureProvisioningProfile.js +1 -1
- package/build/credentials/ios/actions/CreateProvisioningProfile.js +1 -1
- package/build/credentials/ios/appstore/AppStoreApi.d.ts +5 -1
- package/build/credentials/ios/appstore/AppStoreApi.js +38 -15
- package/build/credentials/ios/appstore/ascApiKey.d.ts +21 -5
- package/build/credentials/ios/appstore/ascApiKey.js +28 -12
- package/build/credentials/ios/appstore/authenticate.d.ts +9 -18
- package/build/credentials/ios/appstore/authenticate.js +43 -3
- package/build/credentials/ios/appstore/authenticateTypes.d.ts +42 -0
- package/build/credentials/ios/appstore/authenticateTypes.js +16 -0
- package/build/credentials/ios/appstore/capabilityIdentifiers.d.ts +2 -0
- package/build/credentials/ios/appstore/capabilityIdentifiers.js +9 -0
- package/build/credentials/ios/appstore/contractMessages.d.ts +3 -0
- package/build/credentials/ios/appstore/contractMessages.js +12 -0
- package/build/credentials/ios/appstore/distributionCertificate.d.ts +1 -1
- package/build/credentials/ios/appstore/ensureAppExists.d.ts +2 -2
- package/build/credentials/ios/appstore/ensureAppExists.js +12 -5
- package/build/credentials/ios/appstore/provisioningProfile.d.ts +1 -1
- package/build/credentials/ios/appstore/provisioningProfile.js +6 -0
- package/build/credentials/ios/appstore/provisioningProfileAdhoc.d.ts +1 -1
- package/build/credentials/ios/appstore/provisioningProfileAdhoc.js +17 -2
- package/build/credentials/ios/appstore/pushKey.d.ts +16 -4
- package/build/credentials/ios/appstore/pushKey.js +20 -8
- package/build/credentials/ios/appstore/resolveCredentials.d.ts +10 -1
- package/build/credentials/ios/appstore/resolveCredentials.js +125 -3
- package/build/credentials/ios/utils/authType.d.ts +4 -0
- package/build/credentials/ios/utils/authType.js +8 -0
- package/build/fetch.d.ts +3 -0
- package/build/fetch.js +14 -2
- package/build/graphql/client.js +15 -14
- package/build/graphql/generated.d.ts +83 -0
- package/build/graphql/generated.js +16 -1
- package/build/graphql/mutations/BuildMutation.js +2 -2
- package/build/graphql/types/Build.js +5 -0
- package/build/project/ios/target.js +37 -0
- package/build/submit/ios/AppProduce.d.ts +0 -1
- package/build/submit/ios/AppProduce.js +5 -6
- package/build/submit/ios/AppSpecificPasswordSource.js +2 -2
- package/build/utils/code-signing.d.ts +0 -5
- package/build/utils/code-signing.js +5 -51
- package/oclif.manifest.json +1 -1
- package/package.json +15 -14
package/build/build/build.js
CHANGED
|
@@ -4,9 +4,12 @@ exports.waitForBuildEndAsync = exports.prepareBuildRequestForPlatformAsync = voi
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const cli_progress_1 = tslib_1.__importDefault(require("cli-progress"));
|
|
7
8
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
9
|
+
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
|
|
8
10
|
const common_1 = require("../analytics/common");
|
|
9
11
|
const events_1 = require("../analytics/events");
|
|
12
|
+
const api_1 = require("../api");
|
|
10
13
|
const generated_1 = require("../graphql/generated");
|
|
11
14
|
const BuildQuery_1 = require("../graphql/queries/BuildQuery");
|
|
12
15
|
const log_1 = tslib_1.__importStar(require("../log"));
|
|
@@ -54,7 +57,6 @@ async function prepareBuildRequestForPlatformAsync(builder) {
|
|
|
54
57
|
credentials: credentialsResult === null || credentialsResult === void 0 ? void 0 : credentialsResult.credentials,
|
|
55
58
|
});
|
|
56
59
|
return async () => {
|
|
57
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
58
60
|
if (ctx.localBuildOptions.enable) {
|
|
59
61
|
await (0, local_1.runLocalBuildAsync)(job, ctx.localBuildOptions);
|
|
60
62
|
return undefined;
|
|
@@ -64,31 +66,35 @@ async function prepareBuildRequestForPlatformAsync(builder) {
|
|
|
64
66
|
return await sendBuildRequestAsync(builder, job, metadata);
|
|
65
67
|
}
|
|
66
68
|
catch (error) {
|
|
67
|
-
|
|
68
|
-
log_1.default.error('EAS Build API has changed, please upgrade to the latest eas-cli version.');
|
|
69
|
-
throw new Error('Build request failed.');
|
|
70
|
-
}
|
|
71
|
-
else if (((_f = (_e = (_d = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.extensions) === null || _f === void 0 ? void 0 : _f.errorCode) === 'EAS_BUILD_DOWN_FOR_MAINTENANCE') {
|
|
72
|
-
log_1.default.error('EAS Build is down for maintenance, please try again later. Check https://status.expo.dev/ for updates.');
|
|
73
|
-
throw new Error('Build request failed.');
|
|
74
|
-
}
|
|
75
|
-
else if (((_j = (_h = (_g = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.extensions) === null || _j === void 0 ? void 0 : _j.errorCode) === 'EAS_BUILD_FREE_TIER_DISABLED') {
|
|
76
|
-
log_1.default.error('EAS Build free tier is temporarily disabled, please try again later. Check https://status.expo.dev/ for updates.');
|
|
77
|
-
throw new Error('Build request failed.');
|
|
78
|
-
}
|
|
79
|
-
else if (((_m = (_l = (_k = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.extensions) === null || _m === void 0 ? void 0 : _m.errorCode) === 'EAS_BUILD_TOO_MANY_PENDING_BUILDS') {
|
|
80
|
-
log_1.default.error(`You have already reached the maximum number of pending ${platform_1.requestedPlatformDisplayNames[job.platform]} builds for your account. Try again later.`);
|
|
81
|
-
throw new Error('Build request failed.');
|
|
82
|
-
}
|
|
83
|
-
else if (error === null || error === void 0 ? void 0 : error.graphQLErrors) {
|
|
84
|
-
log_1.default.error('Build request failed. Make sure you are using the latest eas-cli version. If the problem persists, please report the issue.');
|
|
85
|
-
}
|
|
86
|
-
throw error;
|
|
69
|
+
handleBuildRequestError(error, job.platform);
|
|
87
70
|
}
|
|
88
71
|
}
|
|
89
72
|
};
|
|
90
73
|
}
|
|
91
74
|
exports.prepareBuildRequestForPlatformAsync = prepareBuildRequestForPlatformAsync;
|
|
75
|
+
function handleBuildRequestError(error, platform) {
|
|
76
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
77
|
+
if (((_c = (_b = (_a = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.extensions) === null || _c === void 0 ? void 0 : _c.errorCode) === 'TURTLE_DEPRECATED_JOB_FORMAT') {
|
|
78
|
+
log_1.default.error('EAS Build API has changed, please upgrade to the latest eas-cli version.');
|
|
79
|
+
throw new Error('Build request failed.');
|
|
80
|
+
}
|
|
81
|
+
else if (((_f = (_e = (_d = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.extensions) === null || _f === void 0 ? void 0 : _f.errorCode) === 'EAS_BUILD_DOWN_FOR_MAINTENANCE') {
|
|
82
|
+
log_1.default.error('EAS Build is down for maintenance, please try again later. Check https://status.expo.dev/ for updates.');
|
|
83
|
+
throw new Error('Build request failed.');
|
|
84
|
+
}
|
|
85
|
+
else if (((_j = (_h = (_g = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.extensions) === null || _j === void 0 ? void 0 : _j.errorCode) === 'EAS_BUILD_FREE_TIER_DISABLED') {
|
|
86
|
+
log_1.default.error('EAS Build free tier is temporarily disabled, please try again later. Check https://status.expo.dev/ for updates.');
|
|
87
|
+
throw new Error('Build request failed.');
|
|
88
|
+
}
|
|
89
|
+
else if (((_m = (_l = (_k = error === null || error === void 0 ? void 0 : error.graphQLErrors) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.extensions) === null || _m === void 0 ? void 0 : _m.errorCode) === 'EAS_BUILD_TOO_MANY_PENDING_BUILDS') {
|
|
90
|
+
log_1.default.error(`You have already reached the maximum number of pending ${platform_1.requestedPlatformDisplayNames[platform]} builds for your account. Try again later.`);
|
|
91
|
+
throw new Error('Build request failed.');
|
|
92
|
+
}
|
|
93
|
+
else if (error === null || error === void 0 ? void 0 : error.graphQLErrors) {
|
|
94
|
+
log_1.default.error('Build request failed. Make sure you are using the latest eas-cli version. If the problem persists, please report the issue.');
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
92
98
|
async function uploadProjectAsync(ctx) {
|
|
93
99
|
let projectTarballPath;
|
|
94
100
|
try {
|
|
@@ -130,96 +136,177 @@ async function sendBuildRequestAsync(builder, job, metadata) {
|
|
|
130
136
|
trackingCtx: ctx.trackingCtx,
|
|
131
137
|
});
|
|
132
138
|
}
|
|
133
|
-
async function waitForBuildEndAsync(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
139
|
+
async function waitForBuildEndAsync({ buildIds, accountName }, {
|
|
140
|
+
// 2 hours (max build time limit) + 10 minutes (possible queue time )
|
|
141
|
+
timeoutSec = 2 * 60 * 60 + 10 * 60, intervalSec = 10, } = {}) {
|
|
142
|
+
const b = `build${buildIds.length > 1 ? 's' : ''}`;
|
|
143
|
+
log_1.default.log(`Waiting for ${b} to complete. You can press Ctrl+C to exit.`);
|
|
144
|
+
const spinner = (0, ora_1.ora)(`Waiting for ${b} to complete.`).start();
|
|
145
|
+
const endTime = new Date().getTime() + timeoutSec * 1000;
|
|
146
|
+
while (new Date().getTime() <= endTime) {
|
|
147
|
+
const builds = await getBuildsSafelyAsync(buildIds);
|
|
148
|
+
const { refetch } = builds.length === 1
|
|
149
|
+
? await handleSingleBuildProgressAsync({ build: builds[0], accountName }, { spinner })
|
|
150
|
+
: await handleMultipleBuildsProgressAsync({ builds }, { spinner });
|
|
151
|
+
if (!refetch) {
|
|
152
|
+
return builds;
|
|
153
|
+
}
|
|
154
|
+
await (0, promise_1.sleepAsync)(intervalSec * 1000);
|
|
155
|
+
}
|
|
156
|
+
spinner.fail('Timed out');
|
|
157
|
+
throw new Error('Timeout reached! It is taking longer than expected to finish the build, aborting...');
|
|
158
|
+
}
|
|
159
|
+
exports.waitForBuildEndAsync = waitForBuildEndAsync;
|
|
160
|
+
async function getBuildsSafelyAsync(buildIds) {
|
|
161
|
+
const promises = buildIds.map(async (buildId) => {
|
|
162
|
+
try {
|
|
163
|
+
return await BuildQuery_1.BuildQuery.byIdAsync(buildId, { useCache: false });
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
log_1.default.debug('Failed to fetch the build status', err);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return await Promise.all(promises);
|
|
171
|
+
}
|
|
172
|
+
let queueProgressBarStarted = false;
|
|
173
|
+
const queueProgressBar = new cli_progress_1.default.SingleBar({ format: '|{bar}| {estimatedWaitTime}' }, cli_progress_1.default.Presets.rect);
|
|
174
|
+
async function handleSingleBuildProgressAsync({ build, accountName }, { spinner }) {
|
|
175
|
+
if (build === null) {
|
|
176
|
+
spinner.text = 'Could not fetch the build status. Check your network connection.';
|
|
177
|
+
return { refetch: true };
|
|
178
|
+
}
|
|
179
|
+
if (queueProgressBarStarted && (build === null || build === void 0 ? void 0 : build.status) && build.status !== generated_1.BuildStatus.InQueue) {
|
|
180
|
+
if (build.status === generated_1.BuildStatus.InProgress) {
|
|
181
|
+
queueProgressBar.update(queueProgressBar.getTotal(), {
|
|
182
|
+
estimatedWaitTime: '',
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
queueProgressBar.stop();
|
|
186
|
+
log_1.default.newLine();
|
|
187
|
+
queueProgressBarStarted = false;
|
|
188
|
+
spinner.start('Build is about to start');
|
|
189
|
+
}
|
|
190
|
+
switch (build.status) {
|
|
191
|
+
case generated_1.BuildStatus.Finished:
|
|
192
|
+
spinner.succeed('Build finished');
|
|
193
|
+
return { refetch: false };
|
|
194
|
+
case generated_1.BuildStatus.New:
|
|
195
|
+
spinner.text = `Build is waiting to enter the queue. Check your concurrency limit at ${chalk_1.default.underline(formatAccountSubscriptionsUrl(accountName))}.`;
|
|
196
|
+
break;
|
|
197
|
+
case generated_1.BuildStatus.InQueue: {
|
|
198
|
+
spinner.text = 'Build queued...';
|
|
199
|
+
const progressBarPayload = typeof build.estimatedWaitTimeLeftSeconds === 'number'
|
|
200
|
+
? { estimatedWaitTime: formatEstimatedWaitTime(build.estimatedWaitTimeLeftSeconds) }
|
|
201
|
+
: { estimatedWaitTime: '' };
|
|
202
|
+
if (!queueProgressBarStarted &&
|
|
203
|
+
typeof build.initialQueuePosition === 'number' &&
|
|
204
|
+
typeof build.queuePosition === 'number') {
|
|
205
|
+
spinner.stopAndPersist();
|
|
206
|
+
if (build.priority !== generated_1.BuildPriority.High) {
|
|
207
|
+
log_1.default.newLine();
|
|
208
|
+
log_1.default.log('Start builds sooner in the priority queue.');
|
|
209
|
+
log_1.default.log(`Sign up for EAS Production or Enterprise at ${chalk_1.default.underline(formatAccountSubscriptionsUrl(accountName))}`);
|
|
179
210
|
}
|
|
211
|
+
log_1.default.newLine();
|
|
212
|
+
log_1.default.log('Waiting in queue');
|
|
213
|
+
queueProgressBar.start(build.initialQueuePosition + 1, build.initialQueuePosition - build.queuePosition + 1, progressBarPayload);
|
|
214
|
+
queueProgressBarStarted = true;
|
|
180
215
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
spinner.text = 'Could not fetch the build status. Check your network connection.';
|
|
184
|
-
}
|
|
216
|
+
if (typeof build.queuePosition === 'number') {
|
|
217
|
+
queueProgressBar.update(build.queuePosition, progressBarPayload);
|
|
185
218
|
}
|
|
219
|
+
break;
|
|
186
220
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return
|
|
221
|
+
case generated_1.BuildStatus.Canceled:
|
|
222
|
+
spinner.fail('Build canceled');
|
|
223
|
+
return { refetch: false };
|
|
224
|
+
case generated_1.BuildStatus.InProgress:
|
|
225
|
+
spinner.text = 'Build in progress...';
|
|
226
|
+
break;
|
|
227
|
+
case generated_1.BuildStatus.Errored:
|
|
228
|
+
spinner.fail('Build failed');
|
|
229
|
+
if (build.error) {
|
|
230
|
+
return { refetch: false };
|
|
197
231
|
}
|
|
198
232
|
else {
|
|
199
|
-
|
|
200
|
-
const inQueue = builds.filter(build => (build === null || build === void 0 ? void 0 : build.status) === generated_1.BuildStatus.InQueue).length;
|
|
201
|
-
const inProgress = builds.filter(build => (build === null || build === void 0 ? void 0 : build.status) === generated_1.BuildStatus.InProgress).length;
|
|
202
|
-
const errored = builds.filter(build => (build === null || build === void 0 ? void 0 : build.status) === generated_1.BuildStatus.Errored).length;
|
|
203
|
-
const finished = builds.filter(build => (build === null || build === void 0 ? void 0 : build.status) === generated_1.BuildStatus.Finished).length;
|
|
204
|
-
const canceled = builds.filter(build => (build === null || build === void 0 ? void 0 : build.status) === generated_1.BuildStatus.Canceled).length;
|
|
205
|
-
const unknown = builds.length - newBuilds - inQueue - inProgress - errored - finished - canceled;
|
|
206
|
-
spinner.text = [
|
|
207
|
-
newBuilds && `Builds created: ${newBuilds}`,
|
|
208
|
-
inQueue && `Builds in queue: ${inQueue}`,
|
|
209
|
-
inProgress && `Builds in progress: ${inProgress}`,
|
|
210
|
-
canceled && `Builds canceled: ${canceled}`,
|
|
211
|
-
errored && chalk_1.default.red(`Builds failed: ${errored}`),
|
|
212
|
-
finished && chalk_1.default.green(`Builds finished: ${finished}`),
|
|
213
|
-
unknown && chalk_1.default.red(`Builds with unknown status: ${unknown}`),
|
|
214
|
-
]
|
|
215
|
-
.filter(i => i)
|
|
216
|
-
.join('\t');
|
|
233
|
+
throw new Error('Standalone build failed!');
|
|
217
234
|
}
|
|
235
|
+
default:
|
|
236
|
+
spinner.warn('Unknown status');
|
|
237
|
+
throw new Error(`Unknown build status: ${build.status} - aborting!`);
|
|
238
|
+
}
|
|
239
|
+
return { refetch: true };
|
|
240
|
+
}
|
|
241
|
+
const statusToDisplayName = {
|
|
242
|
+
[generated_1.BuildStatus.New]: 'waiting to enter the queue (concurrency limit reached)',
|
|
243
|
+
[generated_1.BuildStatus.InQueue]: 'in queue',
|
|
244
|
+
[generated_1.BuildStatus.InProgress]: 'in progress',
|
|
245
|
+
[generated_1.BuildStatus.Canceled]: 'canceled',
|
|
246
|
+
[generated_1.BuildStatus.Finished]: 'finished',
|
|
247
|
+
[generated_1.BuildStatus.Errored]: 'failed',
|
|
248
|
+
};
|
|
249
|
+
const platforms = [generated_1.AppPlatform.Android, generated_1.AppPlatform.Ios];
|
|
250
|
+
async function handleMultipleBuildsProgressAsync({ builds: maybeBuilds }, { spinner }) {
|
|
251
|
+
const buildCount = maybeBuilds.length;
|
|
252
|
+
const builds = maybeBuilds.filter(isBuildFragment);
|
|
253
|
+
const allFinished = builds.filter(build => build.status === generated_1.BuildStatus.Finished).length === buildCount;
|
|
254
|
+
const allSettled = builds.filter(build => [generated_1.BuildStatus.Finished, generated_1.BuildStatus.Errored, generated_1.BuildStatus.Canceled].includes(build.status)).length === buildCount;
|
|
255
|
+
if (allSettled) {
|
|
256
|
+
if (allFinished) {
|
|
257
|
+
spinner.succeed(formatSettledBuildsText(builds));
|
|
218
258
|
}
|
|
219
|
-
|
|
220
|
-
|
|
259
|
+
else {
|
|
260
|
+
spinner.fail(formatSettledBuildsText(builds));
|
|
261
|
+
}
|
|
262
|
+
return { refetch: false };
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
spinner.text = formatPendingBuildsText(builds);
|
|
266
|
+
return { refetch: true };
|
|
221
267
|
}
|
|
222
|
-
spinner.warn('Timed out');
|
|
223
|
-
throw new Error('Timeout reached! It is taking longer than expected to finish the build, aborting...');
|
|
224
268
|
}
|
|
225
|
-
|
|
269
|
+
function formatSettledBuildsText(builds) {
|
|
270
|
+
return platforms
|
|
271
|
+
.map(platform => {
|
|
272
|
+
const build = (0, nullthrows_1.default)(builds.find(build => build.platform === platform), `Build for platform ${platform} must be defined in this context`);
|
|
273
|
+
return `${platform_1.appPlatformEmojis[platform]} ${platform_1.appPlatformDisplayNames[platform]} build - status: ${chalk_1.default.bold(statusToDisplayName[build.status])}`;
|
|
274
|
+
})
|
|
275
|
+
.join('\n ');
|
|
276
|
+
}
|
|
277
|
+
function formatPendingBuildsText(builds) {
|
|
278
|
+
return platforms
|
|
279
|
+
.map(platform => {
|
|
280
|
+
const build = builds.find(build => build.platform === platform);
|
|
281
|
+
const status = build ? statusToDisplayName[build.status] : 'unknown';
|
|
282
|
+
let extraInfo = '';
|
|
283
|
+
if ((build === null || build === void 0 ? void 0 : build.status) === generated_1.BuildStatus.InQueue &&
|
|
284
|
+
typeof build.initialQueuePosition === 'number' &&
|
|
285
|
+
typeof build.queuePosition === 'number') {
|
|
286
|
+
const percent = Math.floor(((build.initialQueuePosition - build.queuePosition + 1) /
|
|
287
|
+
(build.initialQueuePosition + 1)) *
|
|
288
|
+
100);
|
|
289
|
+
const estimatedWaitTime = typeof build.estimatedWaitTimeLeftSeconds === 'number'
|
|
290
|
+
? ` - ${formatEstimatedWaitTime(build.estimatedWaitTimeLeftSeconds)}`
|
|
291
|
+
: '';
|
|
292
|
+
extraInfo = ` - queue progress: ${chalk_1.default.bold(`${percent}%`)}${estimatedWaitTime}`;
|
|
293
|
+
}
|
|
294
|
+
return `${platform_1.appPlatformEmojis[platform]} ${platform_1.appPlatformDisplayNames[platform]} build - status: ${chalk_1.default.bold(status)}${extraInfo}`;
|
|
295
|
+
})
|
|
296
|
+
.join('\n ');
|
|
297
|
+
}
|
|
298
|
+
function isBuildFragment(maybeBuild) {
|
|
299
|
+
return maybeBuild !== null;
|
|
300
|
+
}
|
|
301
|
+
function formatEstimatedWaitTime(estimatedWaitTimeLeftSeconds) {
|
|
302
|
+
if (estimatedWaitTimeLeftSeconds < 5 * 60) {
|
|
303
|
+
return 'starting soon...';
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const n = Math.floor(estimatedWaitTimeLeftSeconds / (10 * 60)) + 1;
|
|
307
|
+
return `starting in about ${n}0 minutes...`;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function formatAccountSubscriptionsUrl(accountName) {
|
|
311
|
+
return new URL(`/accounts/${accountName}/settings/subscriptions`, (0, api_1.getExpoWebsiteBaseUrl)()).toString();
|
|
312
|
+
}
|
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 = '0.0.
|
|
9
|
+
const PLUGIN_PACKAGE_VERSION = '0.0.74';
|
|
10
10
|
async function runLocalBuildAsync(job, options) {
|
|
11
11
|
var _a;
|
|
12
12
|
const { command, args } = await getCommandAndArgsAsync(job);
|
|
@@ -98,7 +98,11 @@ async function runBuildAndSubmitAsync(projectDir, flags) {
|
|
|
98
98
|
}
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
|
-
const
|
|
101
|
+
const { accountName } = Object.values(buildCtxByPlatform)[0];
|
|
102
|
+
const builds = await (0, build_2.waitForBuildEndAsync)({
|
|
103
|
+
buildIds: startedBuilds.map(({ build }) => build.id),
|
|
104
|
+
accountName,
|
|
105
|
+
});
|
|
102
106
|
(0, printBuildInfo_1.printBuildResults)(builds, flags.json);
|
|
103
107
|
const haveAllBuildsFailedOrCanceled = builds.every(build => (build === null || build === void 0 ? void 0 : build.status) && [generated_1.BuildStatus.Errored, generated_1.BuildStatus.Canceled].includes(build === null || build === void 0 ? void 0 : build.status));
|
|
104
108
|
if (haveAllBuildsFailedOrCanceled || !flags.autoSubmit) {
|
|
@@ -82,8 +82,7 @@ function printDeprecationWarnings(deprecationInfo) {
|
|
|
82
82
|
log_1.default.warn(deprecationInfo.message);
|
|
83
83
|
}
|
|
84
84
|
else if (deprecationInfo.type === generated_1.EasBuildDeprecationInfoType.UserFacing) {
|
|
85
|
-
log_1.default.warn('This command is using API that soon will be deprecated
|
|
86
|
-
log_1.default.warn('There might be some changes necessary to your project config, latest eas-cli will provide more specific error messages.');
|
|
85
|
+
log_1.default.warn('This command is using API that soon will be deprecated.');
|
|
87
86
|
log_1.default.warn(deprecationInfo.message);
|
|
88
87
|
}
|
|
89
88
|
else {
|
package/build/build/utils/url.js
CHANGED
|
@@ -6,21 +6,19 @@ const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
|
6
6
|
const api_1 = require("../../api");
|
|
7
7
|
const generated_1 = require("../../graphql/generated");
|
|
8
8
|
function getProjectDashboardUrl(accountName, projectName) {
|
|
9
|
-
return
|
|
9
|
+
return new URL(`/accounts/${accountName}/projects/${projectName}`, (0, api_1.getExpoWebsiteBaseUrl)()).toString();
|
|
10
10
|
}
|
|
11
11
|
exports.getProjectDashboardUrl = getProjectDashboardUrl;
|
|
12
12
|
function getBuildLogsUrl(build) {
|
|
13
13
|
const { project } = build;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return `${(0, api_1.getExpoWebsiteBaseUrl)()}/builds/${build.id}`;
|
|
19
|
-
}
|
|
14
|
+
const url = project.__typename !== 'App'
|
|
15
|
+
? `/builds/${build.id}`
|
|
16
|
+
: `/accounts/${project.ownerAccount.name}/projects/${project.slug}/builds/${build.id}`;
|
|
17
|
+
return new URL(url, (0, api_1.getExpoWebsiteBaseUrl)()).toString();
|
|
20
18
|
}
|
|
21
19
|
exports.getBuildLogsUrl = getBuildLogsUrl;
|
|
22
20
|
function getArtifactUrl(artifactId) {
|
|
23
|
-
return
|
|
21
|
+
return new URL(`/artifacts/${artifactId}`, (0, api_1.getExpoWebsiteBaseUrl)()).toString();
|
|
24
22
|
}
|
|
25
23
|
exports.getArtifactUrl = getArtifactUrl;
|
|
26
24
|
function getInternalDistributionInstallUrl(build) {
|
|
@@ -12,6 +12,7 @@ const User_1 = require("../user/User");
|
|
|
12
12
|
const AndroidGraphqlClient = tslib_1.__importStar(require("./android/api/GraphqlClient"));
|
|
13
13
|
const IosGraphqlClient = tslib_1.__importStar(require("./ios/api/GraphqlClient"));
|
|
14
14
|
const AppStoreApi_1 = tslib_1.__importDefault(require("./ios/appstore/AppStoreApi"));
|
|
15
|
+
const authenticateTypes_1 = require("./ios/appstore/authenticateTypes");
|
|
15
16
|
class CredentialsContext {
|
|
16
17
|
constructor(options) {
|
|
17
18
|
var _a, _b;
|
|
@@ -73,6 +74,10 @@ class CredentialsContext {
|
|
|
73
74
|
if (this.nonInteractive) {
|
|
74
75
|
return;
|
|
75
76
|
}
|
|
77
|
+
if (this.appStore.defaultAuthenticationMode === authenticateTypes_1.AuthenticationMode.API_KEY) {
|
|
78
|
+
await this.appStore.ensureAuthenticatedAsync();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
76
81
|
log_1.default.log(chalk_1.default.green('If you provide your Apple account credentials we will be able to generate all necessary build credentials and fully validate them.'));
|
|
77
82
|
log_1.default.log(chalk_1.default.green('This is optional, but without Apple account access you will need to provide all the missing values manually and we can only run minimal validation on them.'));
|
|
78
83
|
const confirm = await (0, prompts_1.confirmAsync)({
|
|
@@ -70,7 +70,6 @@ async function provideOrGenerateAscApiKeyAsync(ctx, purpose) {
|
|
|
70
70
|
}
|
|
71
71
|
exports.provideOrGenerateAscApiKeyAsync = provideOrGenerateAscApiKeyAsync;
|
|
72
72
|
async function generateAscApiKeyAsync(ctx, purpose) {
|
|
73
|
-
//console.log('debug');
|
|
74
73
|
await ctx.appStore.ensureAuthenticatedAsync();
|
|
75
74
|
const ascApiKey = await ctx.appStore.createAscApiKeyAsync({
|
|
76
75
|
nickname: getAscApiKeyName(purpose),
|
|
@@ -46,7 +46,7 @@ class ConfigureProvisioningProfile {
|
|
|
46
46
|
certP12: certificateP12,
|
|
47
47
|
certPassword: certificatePassword,
|
|
48
48
|
distCertSerialNumber: serialNumber,
|
|
49
|
-
teamId: authCtx.
|
|
49
|
+
teamId: authCtx.team.id,
|
|
50
50
|
});
|
|
51
51
|
const bundleIdTag = `(${app.bundleIdentifier})`;
|
|
52
52
|
const slugTag = `@${app.account.name}/${app.projectName}`;
|
|
@@ -45,7 +45,7 @@ class CreateProvisioningProfile {
|
|
|
45
45
|
certP12: this.distributionCertificate.certificateP12,
|
|
46
46
|
certPassword: this.distributionCertificate.certificatePassword,
|
|
47
47
|
distCertSerialNumber: this.distributionCertificate.serialNumber,
|
|
48
|
-
teamId: (_c = (_b = this.distributionCertificate.appleTeam) === null || _b === void 0 ? void 0 : _b.appleTeamIdentifier) !== null && _c !== void 0 ? _c : appleAuthCtx.
|
|
48
|
+
teamId: (_c = (_b = this.distributionCertificate.appleTeam) === null || _b === void 0 ? void 0 : _b.appleTeamIdentifier) !== null && _c !== void 0 ? _c : appleAuthCtx.team.id,
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { AscApiKey, AscApiKeyInfo, DistributionCertificate, DistributionCertificateStoreInfo, ProvisioningProfile, ProvisioningProfileStoreInfo, PushKey, PushKeyStoreInfo } from './Credentials.types';
|
|
2
|
-
import {
|
|
2
|
+
import { Options as AuthenticateOptions } from './authenticate';
|
|
3
|
+
import { AuthCtx, AuthenticationMode, UserAuthCtx } from './authenticateTypes';
|
|
3
4
|
import { AppLookupParams, IosCapabilitiesOptions } from './ensureAppExists';
|
|
4
5
|
import { ProfileClass } from './provisioningProfile';
|
|
5
6
|
export default class AppStoreApi {
|
|
6
7
|
authCtx?: AuthCtx;
|
|
8
|
+
defaultAuthenticationMode: AuthenticationMode;
|
|
9
|
+
constructor();
|
|
10
|
+
ensureUserAuthenticatedAsync(options?: AuthenticateOptions): Promise<UserAuthCtx>;
|
|
7
11
|
ensureAuthenticatedAsync(options?: AuthenticateOptions): Promise<AuthCtx>;
|
|
8
12
|
ensureBundleIdExistsAsync(app: AppLookupParams, options?: IosCapabilitiesOptions): Promise<void>;
|
|
9
13
|
listDistributionCertificatesAsync(): Promise<DistributionCertificateStoreInfo[]>;
|
|
@@ -1,16 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const log_1 = tslib_1.__importDefault(require("../../../log"));
|
|
3
5
|
const ascApiKey_1 = require("./ascApiKey");
|
|
4
6
|
const authenticate_1 = require("./authenticate");
|
|
7
|
+
const authenticateTypes_1 = require("./authenticateTypes");
|
|
5
8
|
const distributionCertificate_1 = require("./distributionCertificate");
|
|
6
9
|
const ensureAppExists_1 = require("./ensureAppExists");
|
|
7
10
|
const provisioningProfile_1 = require("./provisioningProfile");
|
|
8
11
|
const provisioningProfileAdhoc_1 = require("./provisioningProfileAdhoc");
|
|
9
12
|
const pushKey_1 = require("./pushKey");
|
|
13
|
+
const resolveCredentials_1 = require("./resolveCredentials");
|
|
10
14
|
class AppStoreApi {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.defaultAuthenticationMode = (0, resolveCredentials_1.hasAscEnvVars)()
|
|
17
|
+
? authenticateTypes_1.AuthenticationMode.API_KEY
|
|
18
|
+
: authenticateTypes_1.AuthenticationMode.USER;
|
|
19
|
+
}
|
|
20
|
+
async ensureUserAuthenticatedAsync(options) {
|
|
21
|
+
if (this.authCtx && !(0, authenticate_1.isUserAuthCtx)(this.authCtx)) {
|
|
22
|
+
// already authenticated, but with the wrong type
|
|
23
|
+
log_1.default.log(`Only user authentication is supported. Reauthenticating as user...`);
|
|
24
|
+
this.authCtx = undefined;
|
|
25
|
+
}
|
|
26
|
+
const updatedAuthCtx = await this.ensureAuthenticatedAsync({
|
|
27
|
+
...options,
|
|
28
|
+
mode: authenticateTypes_1.AuthenticationMode.USER,
|
|
29
|
+
});
|
|
30
|
+
return (0, authenticate_1.assertUserAuthCtx)(updatedAuthCtx);
|
|
31
|
+
}
|
|
11
32
|
async ensureAuthenticatedAsync(options) {
|
|
33
|
+
var _a;
|
|
12
34
|
if (!this.authCtx) {
|
|
13
|
-
|
|
35
|
+
const mode = (_a = options === null || options === void 0 ? void 0 : options.mode) !== null && _a !== void 0 ? _a : this.defaultAuthenticationMode;
|
|
36
|
+
this.authCtx = await (0, authenticate_1.authenticateAsync)({ mode, ...options });
|
|
14
37
|
}
|
|
15
38
|
return this.authCtx;
|
|
16
39
|
}
|
|
@@ -31,16 +54,16 @@ class AppStoreApi {
|
|
|
31
54
|
return await (0, distributionCertificate_1.revokeDistributionCertificateAsync)(ctx, ids);
|
|
32
55
|
}
|
|
33
56
|
async listPushKeysAsync() {
|
|
34
|
-
const
|
|
35
|
-
return await (0, pushKey_1.listPushKeysAsync)(
|
|
57
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
58
|
+
return await (0, pushKey_1.listPushKeysAsync)(userCtx);
|
|
36
59
|
}
|
|
37
60
|
async createPushKeyAsync(name) {
|
|
38
|
-
const
|
|
39
|
-
return await (0, pushKey_1.createPushKeyAsync)(
|
|
61
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
62
|
+
return await (0, pushKey_1.createPushKeyAsync)(userCtx, name);
|
|
40
63
|
}
|
|
41
64
|
async revokePushKeyAsync(ids) {
|
|
42
|
-
const
|
|
43
|
-
return await (0, pushKey_1.revokePushKeyAsync)(
|
|
65
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
66
|
+
return await (0, pushKey_1.revokePushKeyAsync)(userCtx, ids);
|
|
44
67
|
}
|
|
45
68
|
async useExistingProvisioningProfileAsync(bundleIdentifier, provisioningProfile, distCert) {
|
|
46
69
|
const ctx = await this.ensureAuthenticatedAsync();
|
|
@@ -63,20 +86,20 @@ class AppStoreApi {
|
|
|
63
86
|
return await (0, provisioningProfileAdhoc_1.createOrReuseAdhocProvisioningProfileAsync)(ctx, udids, bundleIdentifier, distCertSerialNumber);
|
|
64
87
|
}
|
|
65
88
|
async listAscApiKeysAsync() {
|
|
66
|
-
const
|
|
67
|
-
return await (0, ascApiKey_1.listAscApiKeysAsync)(
|
|
89
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
90
|
+
return await (0, ascApiKey_1.listAscApiKeysAsync)(userCtx);
|
|
68
91
|
}
|
|
69
92
|
async getAscApiKeyAsync(keyId) {
|
|
70
|
-
const
|
|
71
|
-
return await (0, ascApiKey_1.getAscApiKeyAsync)(
|
|
93
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
94
|
+
return await (0, ascApiKey_1.getAscApiKeyAsync)(userCtx, keyId);
|
|
72
95
|
}
|
|
73
96
|
async createAscApiKeyAsync({ nickname }) {
|
|
74
|
-
const
|
|
75
|
-
return await (0, ascApiKey_1.createAscApiKeyAsync)(
|
|
97
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
98
|
+
return await (0, ascApiKey_1.createAscApiKeyAsync)(userCtx, { nickname });
|
|
76
99
|
}
|
|
77
100
|
async revokeAscApiKeyAsync(keyId) {
|
|
78
|
-
const
|
|
79
|
-
return await (0, ascApiKey_1.revokeAscApiKeyAsync)(
|
|
101
|
+
const userCtx = await this.ensureUserAuthenticatedAsync();
|
|
102
|
+
return await (0, ascApiKey_1.revokeAscApiKeyAsync)(userCtx, keyId);
|
|
80
103
|
}
|
|
81
104
|
}
|
|
82
105
|
exports.default = AppStoreApi;
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
/// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
|
|
2
2
|
import { ApiKey, ApiKeyProps } from '@expo/apple-utils';
|
|
3
3
|
import { AscApiKey, AscApiKeyInfo } from './Credentials.types';
|
|
4
|
-
import { AuthCtx } from './
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { AuthCtx, UserAuthCtx } from './authenticateTypes';
|
|
5
|
+
/**
|
|
6
|
+
* List App Store Connect API Keys.
|
|
7
|
+
* **Does not support App Store Connect API (CI).**
|
|
8
|
+
*/
|
|
9
|
+
export declare function listAscApiKeysAsync(userAuthCtx: UserAuthCtx): Promise<AscApiKeyInfo[]>;
|
|
10
|
+
/**
|
|
11
|
+
* Get an App Store Connect API Key.
|
|
12
|
+
* **Does not support App Store Connect API (CI).**
|
|
13
|
+
*/
|
|
14
|
+
export declare function getAscApiKeyAsync(userAuthCtx: UserAuthCtx, keyId: string): Promise<AscApiKeyInfo | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Create an App Store Connect API Key.
|
|
17
|
+
* **Does not support App Store Connect API (CI).**
|
|
18
|
+
*/
|
|
19
|
+
export declare function createAscApiKeyAsync(userAuthCtx: UserAuthCtx, { nickname, allAppsVisible, roles, keyType, }: Partial<Pick<ApiKeyProps, 'nickname' | 'roles' | 'allAppsVisible' | 'keyType'>>): Promise<AscApiKey>;
|
|
20
|
+
/**
|
|
21
|
+
* Revoke an App Store Connect API Key.
|
|
22
|
+
* **Does not support App Store Connect API (CI).**
|
|
23
|
+
*/
|
|
24
|
+
export declare function revokeAscApiKeyAsync(userAuthCtx: UserAuthCtx, keyId: string): Promise<AscApiKeyInfo>;
|
|
9
25
|
export declare function getAscApiKeyInfo(apiKey: ApiKey, authCtx: AuthCtx): AscApiKeyInfo;
|