mirror of
https://github.com/actions/deploy-pages.git
synced 2025-12-09 00:26:14 +00:00
Wrap Twirp responses like Octokit responses for consistency
This commit is contained in:
9
package-lock.json
generated
9
package-lock.json
generated
@@ -11,7 +11,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^2.0.0",
|
"@actions/artifact": "^2.0.0",
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^6.0.0"
|
"@actions/github": "^6.0.0",
|
||||||
|
"@octokit/request-error": "^5.0.1",
|
||||||
|
"http-status-messages": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
@@ -4670,6 +4672,11 @@
|
|||||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/http-status-messages": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-status-messages/-/http-status-messages-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-zq9mKkNX6w6qYtNE0aAiH+urvEenUUIyoq8eAWQh2prhA5o03NETCOm/D2GIVt/qCFItt+23Sm1E7HyelPvi6w=="
|
||||||
|
},
|
||||||
"node_modules/human-signals": {
|
"node_modules/human-signals": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^2.0.0",
|
"@actions/artifact": "^2.0.0",
|
||||||
"@actions/core": "^1.10.1",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^6.0.0"
|
"@actions/github": "^6.0.0",
|
||||||
|
"@octokit/request-error": "^5.0.1",
|
||||||
|
"http-status-messages": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
|
|||||||
@@ -1,16 +1,80 @@
|
|||||||
const core = require('@actions/core')
|
const core = require('@actions/core')
|
||||||
const github = require('@actions/github')
|
const github = require('@actions/github')
|
||||||
const { DefaultArtifactClient } = require('@actions/artifact')
|
const { DefaultArtifactClient } = require('@actions/artifact')
|
||||||
|
const { RequestError } = require('@octokit/request-error')
|
||||||
|
const HttpStatusMessages = require('http-status-messages')
|
||||||
|
|
||||||
|
function wrapTwirpResponseLikeOctokit(twirpResponse, requestOptions) {
|
||||||
|
// Specific response shape aligned with Octokit
|
||||||
|
const response = {
|
||||||
|
url: requestOptions.url,
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
...requestOptions.headers
|
||||||
|
},
|
||||||
|
data: twirpResponse
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mimic the errors thrown by Octokit for consistency.
|
||||||
|
function wrapTwirpErrorLikeOctokit(twirpError, requestOptions) {
|
||||||
|
const rawErrorMsg = twirpError?.message || twirpError?.toString() || ''
|
||||||
|
const statusCodeMatch = rawErrorMsg.match(/Failed request: \((?<statusCode>\d+)\)/)
|
||||||
|
const statusCode = statusCodeMatch?.groups?.statusCode ?? 500
|
||||||
|
|
||||||
|
// Try to provide the best error message
|
||||||
|
const errorMsg =
|
||||||
|
rawErrorMsg ||
|
||||||
|
// Fallback to the HTTP status message based on the status code
|
||||||
|
HttpStatusMessages[statusCode] ||
|
||||||
|
// Or if the status code is unexpected...
|
||||||
|
`Unknown error (${statusCode})`
|
||||||
|
|
||||||
|
// RequestError is an Octokit-specific class
|
||||||
|
return new RequestError(errorMsg, statusCode, {
|
||||||
|
response: {
|
||||||
|
url: requestOptions.url,
|
||||||
|
status: statusCode,
|
||||||
|
headers: {
|
||||||
|
...requestOptions.headers
|
||||||
|
},
|
||||||
|
data: rawErrorMsg ? { message: rawErrorMsg } : ''
|
||||||
|
},
|
||||||
|
request: requestOptions
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArtifactsServiceOrigin() {
|
||||||
|
const resultsUrl = process.env.ACTIONS_RESULTS_URL
|
||||||
|
return resultsUrl ? new URL(resultsUrl).origin : ''
|
||||||
|
}
|
||||||
|
|
||||||
async function getArtifactMetadata({ artifactName }) {
|
async function getArtifactMetadata({ artifactName }) {
|
||||||
const artifactClient = new DefaultArtifactClient()
|
const artifactClient = new DefaultArtifactClient()
|
||||||
|
|
||||||
|
// Primarily for debugging purposes, accuracy is not critical
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
url: `${getArtifactsServiceOrigin()}/twirp/github.actions.results.api.v1.ArtifactService/ListArtifacts`,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
core.info(`Fetching artifact metadata for ${artifactName} in this workflow run`)
|
core.info(`Fetching artifact metadata for ${artifactName} in this workflow run`)
|
||||||
|
|
||||||
const response = await artifactClient.listArtifacts()
|
let response
|
||||||
|
try {
|
||||||
|
const twirpResponse = await artifactClient.listArtifacts()
|
||||||
|
response = wrapTwirpResponseLikeOctokit(twirpResponse, requestOptions)
|
||||||
|
} catch (twirpError) {
|
||||||
|
const octokitError = wrapTwirpErrorLikeOctokit(twirpError, requestOptions)
|
||||||
|
throw octokitError
|
||||||
|
}
|
||||||
|
|
||||||
const filteredArtifacts = response.artifacts.filter(artifact => artifact.name === artifactName)
|
const filteredArtifacts = response.data.artifacts.filter(artifact => artifact.name === artifactName)
|
||||||
|
|
||||||
const artifactCount = filteredArtifacts.length
|
const artifactCount = filteredArtifacts.length
|
||||||
core.debug(`List artifact count: ${artifactCount}`)
|
core.debug(`List artifact count: ${artifactCount}`)
|
||||||
|
|||||||
@@ -62,20 +62,15 @@ class Deployment {
|
|||||||
core.debug(`Action ID: ${this.actionsId}`)
|
core.debug(`Action ID: ${this.actionsId}`)
|
||||||
core.debug(`Actions Workflow Run ID: ${this.workflowRun}`)
|
core.debug(`Actions Workflow Run ID: ${this.workflowRun}`)
|
||||||
|
|
||||||
let artifactData
|
|
||||||
try {
|
try {
|
||||||
artifactData = await getArtifactMetadata({ artifactName: this.artifactName })
|
const artifactData = await getArtifactMetadata({ artifactName: this.artifactName })
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Failed to create deployment: ${error.message}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (artifactData?.size > ONE_GIGABYTE) {
|
if (artifactData?.size > ONE_GIGABYTE) {
|
||||||
core.warning(
|
core.warning(
|
||||||
`Uploaded artifact size of ${artifactData?.size} bytes exceeds the allowed size of ${SIZE_LIMIT_DESCRIPTION}. Deployment might fail.`
|
`Uploaded artifact size of ${artifactData?.size} bytes exceeds the allowed size of ${SIZE_LIMIT_DESCRIPTION}. Deployment might fail.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const deployment = await createPagesDeployment({
|
const deployment = await createPagesDeployment({
|
||||||
githubToken: this.githubToken,
|
githubToken: this.githubToken,
|
||||||
artifactId: artifactData.id,
|
artifactId: artifactData.id,
|
||||||
@@ -103,14 +98,14 @@ class Deployment {
|
|||||||
|
|
||||||
// build customized error message based on server response
|
// build customized error message based on server response
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
let errorMessage = `Failed to create deployment (status: ${error.status}) with build version ${this.buildVersion}. `
|
let errorMessage = `Failed to create deployment (status: ${error.status}) with build version ${this.buildVersion}.`
|
||||||
if (error.status === 400) {
|
if (error.status === 400) {
|
||||||
errorMessage += `Responded with: ${error.message}`
|
errorMessage += ` Responded with: ${error.message}`
|
||||||
} else if (error.status === 403) {
|
} else if (error.status === 403) {
|
||||||
errorMessage += 'Ensure GITHUB_TOKEN has permission "pages: write".'
|
errorMessage += ' Ensure GITHUB_TOKEN has permission "pages: write".'
|
||||||
} else if (error.status === 404) {
|
} else if (error.status === 404) {
|
||||||
const pagesSettingsUrl = `${this.githubServerUrl}/${this.repositoryNwo}/settings/pages`
|
const pagesSettingsUrl = `${this.githubServerUrl}/${this.repositoryNwo}/settings/pages`
|
||||||
errorMessage += `Ensure GitHub Pages has been enabled: ${pagesSettingsUrl}`
|
errorMessage += ` Ensure GitHub Pages has been enabled: ${pagesSettingsUrl}`
|
||||||
// If using GHES, add a special note about compatibility
|
// If using GHES, add a special note about compatibility
|
||||||
if (new URL(this.githubServerUrl).hostname.toLowerCase() !== 'github.com') {
|
if (new URL(this.githubServerUrl).hostname.toLowerCase() !== 'github.com') {
|
||||||
errorMessage +=
|
errorMessage +=
|
||||||
@@ -118,7 +113,7 @@ class Deployment {
|
|||||||
}
|
}
|
||||||
} else if (error.status >= 500) {
|
} else if (error.status >= 500) {
|
||||||
errorMessage +=
|
errorMessage +=
|
||||||
'Server error, is githubstatus.com reporting a Pages outage? Please re-run the deployment at a later time.'
|
' Server error, is githubstatus.com reporting a Pages outage? Please re-run the deployment at a later time.'
|
||||||
}
|
}
|
||||||
throw new Error(errorMessage)
|
throw new Error(errorMessage)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user