Extract response processing logic from Artifact Exchange method

This commit is contained in:
James M. Greene
2023-03-09 07:49:50 -06:00
parent 7ee7a04145
commit 360f95f104

View File

@@ -7,37 +7,7 @@ const HttpStatusMessages = require('http-status-messages')
// All variables we need from the runtime are loaded here // All variables we need from the runtime are loaded here
const getContext = require('./context') const getContext = require('./context')
// Mostly a lift from https://github.com/octokit/request.js/blob/bd72b7be53ab16a6c1c44be99eb73a328fb1e9e4/src/fetch-wrapper.ts#L151-L165 async function processRuntimeResponse(res, requestOptions) {
// Minor revisions applied.
function toErrorMessage(data) {
if (typeof data === 'string') return data
if (data != null && 'message' in data) {
if (Array.isArray(data.errors)) {
return `${data.message}: ${data.errors.map(JSON.stringify).join(', ')}`
}
return data.message
}
// Defer back to the caller
return null
}
async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName }) {
const { runTimeUrl: RUNTIME_URL } = getContext()
const artifactExchangeUrl = `${RUNTIME_URL}_apis/pipelines/workflows/${workflowRunId}/artifacts?api-version=6.0-preview`
const httpClient = new hc.HttpClient()
let data = null
try {
core.info(`Artifact exchange URL: ${artifactExchangeUrl}`)
const requestHeaders = {
accept: 'application/json',
authorization: `Bearer ${runtimeToken}`
}
const res = await httpClient.get(artifactExchangeUrl, requestHeaders)
// Parse the response body as JSON // Parse the response body as JSON
let obj = null let obj = null
try { try {
@@ -46,13 +16,13 @@ async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName
obj = JSON.parse(contents) obj = JSON.parse(contents)
} }
} catch (error) { } catch (error) {
// Invalid resource (contents not json); leaving result obj null // Invalid resource (contents not json); leaving resulting obj as null
} }
// Specific response shape aligned with Octokit // Specific response shape aligned with Octokit
const response = { const response = {
url: res.message.url || artifactExchangeUrl, url: res.message?.url || requestOptions.url,
status: res.message.statusCode || 0, status: res.message?.statusCode || 0,
headers: { headers: {
...res.message?.headers ...res.message?.headers
}, },
@@ -63,15 +33,40 @@ async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName
// @actions/http-client doesn't do this by default. // @actions/http-client doesn't do this by default.
// Mimic the errors thrown by Octokit for consistency. // Mimic the errors thrown by Octokit for consistency.
if (response.status >= 400) { if (response.status >= 400) {
throw new RequestError( // Try to get an error message from the response body
toErrorMessage(response.data) || const errorMsg =
(typeof response.data === 'string' && response.data) ||
response.data?.error ||
response.data?.message ||
// Try the Node HTTP IncomingMessage's statusMessage property
res.message?.statusMessage || res.message?.statusMessage ||
// Fallback to the HTTP status message based on the status code
HttpStatusMessages[response.status] || HttpStatusMessages[response.status] ||
'Unknown error', // Or if the status code is unexpected...
response.status, `Unknown error (${response.status})`
{
throw new RequestError(errorMsg, response.status, {
response, response,
request: { request: requestOptions
})
}
return response
}
async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName }) {
const { runTimeUrl: RUNTIME_URL } = getContext()
const artifactExchangeUrl = `${RUNTIME_URL}_apis/pipelines/workflows/${workflowRunId}/artifacts?api-version=6.0-preview`
const httpClient = new hc.HttpClient()
let data = null
try {
const requestHeaders = {
accept: 'application/json',
authorization: `Bearer ${runtimeToken}`
}
const requestOptions = {
method: 'GET', method: 'GET',
url: artifactExchangeUrl, url: artifactExchangeUrl,
headers: { headers: {
@@ -79,9 +74,12 @@ async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName
}, },
body: null body: null
} }
}
) core.info(`Artifact exchange URL: ${artifactExchangeUrl}`)
} const res = await httpClient.get(artifactExchangeUrl, requestHeaders)
// May throw a RequestError (HttpError)
const response = await processRuntimeResponse(res, requestOptions)
data = response.data data = response.data
core.debug(JSON.stringify(data)) core.debug(JSON.stringify(data))