|
5 | 5 |
|
6 | 6 | import * as fs from 'fs'; |
7 | 7 | import * as path from 'path'; |
8 | | -import fetch, { RequestInit } from 'node-fetch'; |
9 | 8 | import { Readable } from 'stream'; |
| 9 | +import type { ReadableStream } from 'stream/web'; |
10 | 10 | import { pipeline } from 'node:stream/promises'; |
11 | 11 | import * as yauzl from 'yauzl'; |
12 | 12 | import * as crypto from 'crypto'; |
@@ -413,19 +413,23 @@ class State { |
413 | 413 | } |
414 | 414 | } |
415 | 415 |
|
416 | | -const azdoFetchOptions = { headers: { Authorization: `Bearer ${e('SYSTEM_ACCESSTOKEN')}` }, timeout: 60_000 }; |
| 416 | +const azdoFetchOptions = { headers: { Authorization: `Bearer ${e('SYSTEM_ACCESSTOKEN')}` } }; |
417 | 417 |
|
418 | 418 | async function requestAZDOAPI<T>(path: string): Promise<T> { |
419 | | - const res = await fetch(`${e('BUILDS_API_URL')}${path}?api-version=6.0`, azdoFetchOptions); |
| 419 | + const abortController = new AbortController(); |
| 420 | + const timeout = setTimeout(() => abortController.abort(), 2 * 60 * 1000); |
420 | 421 |
|
421 | | - if (!res.ok) { |
422 | | - throw new Error(`Unexpected status code: ${res.status}`); |
423 | | - } |
| 422 | + try { |
| 423 | + const res = await fetch(`${e('BUILDS_API_URL')}${path}?api-version=6.0`, { ...azdoFetchOptions, signal: abortController.signal }); |
424 | 424 |
|
425 | | - return await Promise.race([ |
426 | | - res.json(), |
427 | | - new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 60_000)) |
428 | | - ]); |
| 425 | + if (!res.ok) { |
| 426 | + throw new Error(`Unexpected status code: ${res.status}`); |
| 427 | + } |
| 428 | + |
| 429 | + return await res.json(); |
| 430 | + } finally { |
| 431 | + clearTimeout(timeout); |
| 432 | + } |
429 | 433 | } |
430 | 434 |
|
431 | 435 | interface Artifact { |
@@ -456,16 +460,20 @@ async function getPipelineTimeline(): Promise<Timeline> { |
456 | 460 | } |
457 | 461 |
|
458 | 462 | async function downloadArtifact(artifact: Artifact, downloadPath: string): Promise<void> { |
459 | | - const res = await fetch(artifact.resource.downloadUrl, azdoFetchOptions); |
| 463 | + const abortController = new AbortController(); |
| 464 | + const timeout = setTimeout(() => abortController.abort(), 6 * 60 * 1000); |
460 | 465 |
|
461 | | - if (!res.ok) { |
462 | | - throw new Error(`Unexpected status code: ${res.status}`); |
463 | | - } |
| 466 | + try { |
| 467 | + const res = await fetch(artifact.resource.downloadUrl, { ...azdoFetchOptions, signal: abortController.signal }); |
464 | 468 |
|
465 | | - await Promise.race([ |
466 | | - pipeline(res.body, fs.createWriteStream(downloadPath)), |
467 | | - new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5 * 60 * 1000)) |
468 | | - ]); |
| 469 | + if (!res.ok) { |
| 470 | + throw new Error(`Unexpected status code: ${res.status}`); |
| 471 | + } |
| 472 | + |
| 473 | + await pipeline(Readable.fromWeb(res.body as ReadableStream), fs.createWriteStream(downloadPath)); |
| 474 | + } finally { |
| 475 | + clearTimeout(timeout); |
| 476 | + } |
469 | 477 | } |
470 | 478 |
|
471 | 479 | async function unzip(packagePath: string, outputPath: string): Promise<string> { |
|
0 commit comments