feat: setup custom retry with builtin node fetch (#304)

This commit is contained in:
Blake Kostner
2024-09-25 13:20:41 +02:00
committed by GitHub
parent d1c02572fa
commit 2fdf20c985
7 changed files with 135 additions and 111 deletions
+52 -49
View File
@@ -1,12 +1,13 @@
const core = require('@actions/core')
const { exec } = require('@actions/exec')
const tc = require('@actions/tool-cache')
const http = require('@actions/http-client')
const path = require('path')
const semver = require('semver')
const fs = require('fs')
const os = require('os')
const MAX_HTTP_RETRIES = 3
main().catch((err) => {
core.setFailed(err.message)
})
@@ -261,8 +262,7 @@ async function getOTPVersions(osVersion) {
hexMirrors: hexMirrorsInput(),
actionTitle: `fetch ${originListing}`,
action: async (hexMirror) => {
const l = await get(`${hexMirror}${originListing}`, [null])
return l
return get(`${hexMirror}${originListing}`, [])
},
})
} else if (process.platform === 'win32') {
@@ -289,7 +289,7 @@ async function getOTPVersions(osVersion) {
})
} else if (process.platform === 'win32') {
otpVersionsListings.forEach((otpVersionsListing) => {
jsonParseAsList(otpVersionsListing)
otpVersionsListing
.map((x) => x.assets)
.flat()
.filter((x) => x.name.match(/^otp_win64_.*.exe$/))
@@ -313,8 +313,7 @@ async function getElixirVersions() {
hexMirrors: hexMirrorsInput(),
actionTitle: `fetch ${originListing}`,
action: async (hexMirror) => {
const l = await get(`${hexMirror}${originListing}`, [null])
return l
return get(`${hexMirror}${originListing}`, [])
},
})
const otpVersionsForElixirMap = {}
@@ -347,7 +346,7 @@ async function getGleamVersions() {
)
const gleamVersionsListing = {}
resultJSONs.forEach((resultJSON) => {
jsonParseAsList(resultJSON)
resultJSON
.map((x) => x.tag_name)
.forEach((ver) => {
const gleamMatch = ver.match(/^v?([^ ]+)/)
@@ -366,7 +365,7 @@ async function getRebar3Versions() {
)
const rebar3VersionsListing = {}
resultJSONs.forEach((resultJSON) => {
jsonParseAsList(resultJSON)
resultJSON
.map((x) => x.tag_name)
.forEach((ver) => {
rebar3VersionsListing[ver] = ver
@@ -560,38 +559,56 @@ function getRunnerOSVersion() {
return containerFromEnvImageOS
}
async function get(url0, pageIdxs) {
async function getPage(pageIdx) {
const url = new URL(url0)
const headers = {}
const GithubToken = getInput('github-token', false)
if (GithubToken && url.host === 'api.github.com') {
headers.authorization = `Bearer ${GithubToken}`
}
if (pageIdx !== null) {
url.searchParams.append('page', pageIdx)
}
const httpClient = new http.HttpClient('setup-beam', [], {
allowRetries: true,
maxRetries: 3,
async function getUrlResponse(url, headers, attempt = 1) {
try {
const response = await fetch(url, {
headers,
signal: AbortSignal.timeout(10000),
})
const response = await httpClient.get(url, headers)
if (response.statusCode >= 400 && response.statusCode <= 599) {
throw new Error(
`Got ${response.statusCode} from ${url}. Exiting with error`,
)
const contentType = response.headers.get('content-type') || ''
if (!response.ok) {
throw new Error(response.statusText)
}
return response.readBody()
if (contentType.indexOf('application/json') !== -1) {
return response.json()
} else {
return response.text()
}
} catch (err) {
core.debug(`Error fetching from ${url}: ${err}`)
if (attempt <= MAX_HTTP_RETRIES) {
const delay = attempt * 2 * 1000
core.debug(`Error during fetch. Retrying in ${delay}ms`)
await new Promise((resolve) => setTimeout(resolve, delay))
return getUrlResponse(url, headers, attempt + 1)
} else {
throw err
}
}
}
async function get(url0, pageIdxs) {
const url = new URL(url0)
const headers = {}
const GithubToken = getInput('github-token', false)
if (GithubToken && url.host === 'api.github.com') {
headers.authorization = `Bearer ${GithubToken}`
}
if (pageIdxs[0] === null) {
return getPage(null)
if (pageIdxs.length === 0) {
return getUrlResponse(url, headers)
} else {
return Promise.all(
pageIdxs.map((page) => {
const urlWithPage = new URL(url)
urlWithPage.searchParams.append('page', page)
return getUrlResponse(urlWithPage, headers)
}),
)
}
return Promise.all(pageIdxs.map(getPage))
}
function maybePrependWithV(v) {
@@ -686,21 +703,6 @@ function parseVersionFile(versionFilePath0) {
return appVersions
}
function jsonParseAsList(maybeJson) {
try {
const obj = JSON.parse(maybeJson)
if (!Array.isArray(obj)) {
throw new Error('expected a list!')
}
return obj
} catch (exc) {
throw new Error(
`Got an exception when trying to parse non-JSON list ${maybeJson}: ${exc}`,
)
}
}
function debugLog(groupName, message) {
const group = `Debugging for ${groupName}`
core.debug(
@@ -1058,6 +1060,7 @@ function debugLoggingEnabled() {
}
module.exports = {
get,
getOTPVersion,
getElixirVersion,
getGleamVersion,