mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-15 03:38:08 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a107f30620 | ||
|
|
67df0e2787 |
No files matched your search
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@expo/build-tools': minor
|
||||
---
|
||||
|
||||
Add a configurable timeout to `eas/wait_for_asc_build_processing` and fail when Apple does not finish processing before the deadline.
|
||||
+17
-3
@@ -24,7 +24,7 @@ const api = () => nock('https://api.appstoreconnect.apple.com');
|
||||
const logger = createMockLogger();
|
||||
const globalContext = () => createGlobalContextMock({ projectTargetDirectory: '/project', logger });
|
||||
|
||||
async function waitAsync(diagnostics: Record<string, string> = {}): Promise<void> {
|
||||
async function waitAsync(diagnostics: Record<string, string | number> = {}): Promise<void> {
|
||||
const fn = getEasFunctions(createCustomBuildContextMock()).find(
|
||||
fn => fn.getFullId() === 'eas/wait_for_asc_build_processing'
|
||||
)!;
|
||||
@@ -139,6 +139,18 @@ it('polls an existing upload through awaiting and processing states until comple
|
||||
await expect(waitAsync()).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it('reports a processing timeout instead of success when Apple is still processing', async () => {
|
||||
let now = 0;
|
||||
jest.spyOn(Date, 'now').mockImplementation(() => now);
|
||||
jest.mocked(setTimeout).mockImplementation(async () => {
|
||||
now += 2000;
|
||||
});
|
||||
mockProcessing('PROCESSING');
|
||||
await expect(waitAsync({ wait_processing_timeout_seconds: 1 })).rejects.toMatchObject({
|
||||
errorCode: 'EAS_UPLOAD_TO_ASC_PROCESSING_TIMEOUT',
|
||||
});
|
||||
});
|
||||
|
||||
it('uses the supplied bundle identifier in mismatch errors without an IPA', async () => {
|
||||
mockProcessing(
|
||||
'FAILED',
|
||||
@@ -226,7 +238,7 @@ it.each([undefined, false, true])(
|
||||
);
|
||||
|
||||
it.each(['upload', 'wait'])(
|
||||
'preserves the successful timeout return for the %s step',
|
||||
'reports the default processing timeout for the %s step',
|
||||
async step => {
|
||||
mockProcessing('PROCESSING');
|
||||
const start = Date.now();
|
||||
@@ -234,6 +246,8 @@ it.each(['upload', 'wait'])(
|
||||
jest.mocked(setTimeout).mockImplementationOnce(async () => {
|
||||
jest.spyOn(Date, 'now').mockReturnValue(start + 30 * 60 * 1000);
|
||||
});
|
||||
await expect(step === 'upload' ? uploadAsync(true) : waitAsync()).resolves.toBeUndefined();
|
||||
await expect(step === 'upload' ? uploadAsync(true) : waitAsync()).rejects.toMatchObject({
|
||||
errorCode: 'EAS_UPLOAD_TO_ASC_PROCESSING_TIMEOUT',
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -15,6 +15,12 @@ export function createWaitForAscBuildProcessingBuildFunction(): BuildFunction {
|
||||
name: 'Wait for App Store Connect processing',
|
||||
__metricsId: 'eas/wait_for_asc_build_processing',
|
||||
inputProviders: [
|
||||
BuildStepInput.createProvider({
|
||||
id: 'wait_processing_timeout_seconds',
|
||||
required: false,
|
||||
defaultValue: 30 * 60,
|
||||
allowedValueTypeName: BuildStepInputValueTypeName.NUMBER,
|
||||
}),
|
||||
BuildStepInput.createProvider({
|
||||
id: 'asc_api_key_path',
|
||||
required: true,
|
||||
@@ -46,6 +52,7 @@ export function createWaitForAscBuildProcessingBuildFunction(): BuildFunction {
|
||||
.object({
|
||||
asc_api_key_path: z.string(),
|
||||
build_upload_id: z.string(),
|
||||
wait_processing_timeout_seconds: z.number().finite().positive(),
|
||||
bundle_identifier: z.string().optional(),
|
||||
apple_app_identifier: z.string().optional(),
|
||||
bundle_short_version: z.string().optional(),
|
||||
@@ -53,6 +60,7 @@ export function createWaitForAscBuildProcessingBuildFunction(): BuildFunction {
|
||||
.parse({
|
||||
asc_api_key_path: inputs.asc_api_key_path.value,
|
||||
build_upload_id: inputs.build_upload_id.value,
|
||||
wait_processing_timeout_seconds: inputs.wait_processing_timeout_seconds.value,
|
||||
bundle_identifier: inputs.bundle_identifier.value,
|
||||
apple_app_identifier: inputs.apple_app_identifier.value,
|
||||
bundle_short_version: inputs.bundle_short_version.value,
|
||||
@@ -63,6 +71,7 @@ export function createWaitForAscBuildProcessingBuildFunction(): BuildFunction {
|
||||
await waitForAscBuildProcessingAsync({
|
||||
client,
|
||||
buildUploadId: parsedInputs.build_upload_id,
|
||||
processingTimeoutSeconds: parsedInputs.wait_processing_timeout_seconds,
|
||||
logger: ctx.logger,
|
||||
ipaBundleIdentifier: parsedInputs.bundle_identifier,
|
||||
appleAppIdentifier: parsedInputs.apple_app_identifier,
|
||||
@@ -81,6 +90,7 @@ export async function waitForAscBuildProcessingAsync({
|
||||
appleAppIdentifier,
|
||||
ascAppBundleIdentifier,
|
||||
bundleShortVersion,
|
||||
processingTimeoutSeconds = 30 * 60,
|
||||
}: {
|
||||
client: AscApiClient;
|
||||
buildUploadId: string;
|
||||
@@ -89,13 +99,14 @@ export async function waitForAscBuildProcessingAsync({
|
||||
appleAppIdentifier: string | undefined;
|
||||
ascAppBundleIdentifier: string | undefined;
|
||||
bundleShortVersion: string | undefined;
|
||||
processingTimeoutSeconds?: number;
|
||||
}): Promise<void> {
|
||||
logger.info('Checking build upload status...');
|
||||
const waitingForBuildStartedAt = Date.now();
|
||||
const waitingLogIntervalMs = 10 * 1000;
|
||||
let lastWaitLogTime = 0;
|
||||
let lastWaitLogState: string | null = null;
|
||||
while (Date.now() - waitingForBuildStartedAt < 30 * 60 * 1000 /* 30 minutes */) {
|
||||
while (Date.now() - waitingForBuildStartedAt < processingTimeoutSeconds * 1000) {
|
||||
const {
|
||||
data: {
|
||||
attributes: { state },
|
||||
@@ -205,9 +216,14 @@ export async function waitForAscBuildProcessingAsync({
|
||||
throw new Error(`Build upload (ID: ${buildUploadId}) failed.`);
|
||||
} else if (state.state === 'COMPLETE') {
|
||||
logger.info(`Build upload (ID: ${buildUploadId}) complete!`);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new UserError(
|
||||
'EAS_UPLOAD_TO_ASC_PROCESSING_TIMEOUT',
|
||||
`Apple did not finish processing build upload ${buildUploadId} within ${processingTimeoutSeconds} seconds. ` +
|
||||
'The binary was uploaded. Check its status in App Store Connect before uploading it again, or increase wait_processing_timeout_seconds.'
|
||||
);
|
||||
}
|
||||
|
||||
function isClosedVersionTrainError(messages: { code: string }[]): boolean {
|
||||
|
||||
Reference in new issue
Block a user