From 00e38c80b28fd9b5e99b890d85e080edc2fcc49f Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 3 Feb 2021 17:33:46 -0600 Subject: [PATCH] Fallback if GitHub status is stuck as "pending" (#20729) GitHub's status API is super flaky. Sometimes it reports a job as "pending" even after it completes in CircleCI. If it's still pending when we time out, return the build ID anyway. TODO: The location of the retry loop is a bit weird. We should probably combine this function with the one that downloads the artifacts, and wrap the retry loop around the whole thing. --- scripts/release/get-build-id-for-commit.js | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/scripts/release/get-build-id-for-commit.js b/scripts/release/get-build-id-for-commit.js index 15cbe7de52..a5c6d96b02 100644 --- a/scripts/release/get-build-id-for-commit.js +++ b/scripts/release/get-build-id-for-commit.js @@ -2,8 +2,8 @@ const fetch = require('node-fetch'); -const POLLING_INTERVAL = 5 * 1000; // 5 seconds -const RETRY_TIMEOUT = 10 * 60 * 1000; // 10 minutes +const POLLING_INTERVAL = 10 * 1000; // 10 seconds +const RETRY_TIMEOUT = 4 * 60 * 1000; // 4 minutes function wait(ms) { return new Promise(resolve => { @@ -11,6 +11,10 @@ function wait(ms) { }); } +function scrapeBuildIDFromStatus(status) { + return /\/facebook\/react\/([0-9]+)/.exec(status.target_url)[1]; +} + async function getBuildIdForCommit(sha) { const retryLimit = Date.now() + RETRY_TIMEOUT; retry: while (true) { @@ -30,11 +34,24 @@ async function getBuildIdForCommit(sha) { const status = statuses[i]; if (status.context === `ci/circleci: process_artifacts_combined`) { if (status.state === 'success') { - return /\/facebook\/react\/([0-9]+)/.exec(status.target_url)[1]; + return scrapeBuildIDFromStatus(status); } if (status.state === 'failure') { throw new Error(`Build job for commit failed: ${sha}`); } + if (status.state === 'pending') { + if (Date.now() < retryLimit) { + await wait(POLLING_INTERVAL); + continue retry; + } + // GitHub's status API is super flaky. Sometimes it reports a job + // as "pending" even after it completes in CircleCI. If it's still + // pending when we time out, return the build ID anyway. + // TODO: The location of the retry loop is a bit weird. We should + // probably combine this function with the one that downloads the + // artifacts, and wrap the retry loop around the whole thing. + return scrapeBuildIDFromStatus(status); + } } } if (state === 'pending') {