2023-02-22 07:55:03 -06:00
const core = require ( '@actions/core' )
const github = require ( '@actions/github' )
2023-12-19 14:46:02 -06:00
const { DefaultArtifactClient } = require ( '@actions/artifact' )
2023-12-22 11:40:57 -06:00
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 : ''
}
2023-03-08 19:43:11 -06:00
2023-12-19 14:46:02 -06:00
async function getArtifactMetadata ( { artifactName } ) {
const artifactClient = new DefaultArtifactClient ( )
2023-10-27 16:13:35 -04:00
2023-12-22 11:40:57 -06:00
// 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'
2023-12-22 13:27:24 -06:00
} ,
body : { }
2023-12-22 11:40:57 -06:00
}
2023-10-27 16:13:35 -04:00
try {
2023-12-22 13:16:13 -06:00
core . info ( ` Fetching artifact metadata for " ${ artifactName } " in this workflow run ` )
2023-12-19 14:46:02 -06:00
2023-12-22 11:40:57 -06:00
let response
try {
const twirpResponse = await artifactClient . listArtifacts ( )
response = wrapTwirpResponseLikeOctokit ( twirpResponse , requestOptions )
} catch ( twirpError ) {
2023-12-22 12:53:15 -06:00
core . error ( 'Listing artifact metadata failed' , twirpError )
2023-12-22 11:40:57 -06:00
const octokitError = wrapTwirpErrorLikeOctokit ( twirpError , requestOptions )
throw octokitError
}
2023-12-19 14:46:02 -06:00
2023-12-22 11:40:57 -06:00
const filteredArtifacts = response . data . artifacts . filter ( artifact => artifact . name === artifactName )
2023-12-19 14:46:02 -06:00
const artifactCount = filteredArtifacts . length
2023-10-27 17:40:12 -04:00
core . debug ( ` List artifact count: ${ artifactCount } ` )
if ( artifactCount === 0 ) {
2023-10-30 14:58:12 -04:00
throw new Error (
2024-01-06 12:34:08 +00:00
` No artifacts named " ${ artifactName } " were found for this workflow run. Ensure artifacts are uploaded with actions/upload-artifact@v4 or later. `
2023-10-30 14:58:12 -04:00
)
2023-10-27 17:40:12 -04:00
} else if ( artifactCount > 1 ) {
2023-10-30 14:58:12 -04:00
throw new Error (
2023-12-22 13:16:13 -06:00
` Multiple artifacts named " ${ artifactName } " were unexpectedly found for this workflow run. Artifact count is ${ artifactCount } . `
2023-10-30 14:58:12 -04:00
)
2023-10-27 17:40:12 -04:00
}
2023-10-30 14:58:12 -04:00
2023-12-19 14:46:02 -06:00
const artifact = filteredArtifacts [ 0 ]
2023-10-27 17:40:12 -04:00
core . debug ( ` Artifact: ${ JSON . stringify ( artifact ) } ` )
2023-12-19 14:46:02 -06:00
if ( ! artifact . size ) {
2023-10-27 17:40:12 -04:00
core . warning ( 'Artifact size was not found. Unable to verify if artifact size exceeds the allowed size.' )
}
2023-10-30 14:58:12 -04:00
2023-12-19 14:46:02 -06:00
return artifact
2023-10-27 16:13:35 -04:00
} catch ( error ) {
2023-10-30 15:35:32 -04:00
core . error (
2023-12-22 12:52:56 -06:00
'Fetching artifact metadata failed. Is githubstatus.com reporting issues with API requests, Pages, or Actions? Please re-run the deployment at a later time.' ,
2023-10-30 15:35:32 -04:00
error
)
2023-10-27 16:13:35 -04:00
throw error
}
}
2023-10-27 17:50:16 -04:00
async function createPagesDeployment ( { githubToken , artifactId , buildVersion , idToken , isPreview = false } ) {
2023-02-22 07:55:03 -06:00
const octokit = github . getOctokit ( githubToken )
const payload = {
2023-10-27 17:50:16 -04:00
artifact _id : artifactId ,
2023-02-22 07:55:03 -06:00
pages _build _version : buildVersion ,
oidc _token : idToken
}
if ( isPreview === true ) {
payload . preview = true
}
core . info ( ` Creating Pages deployment with payload: \n ${ JSON . stringify ( payload , null , '\t' ) } ` )
try {
2023-03-15 15:33:59 -04:00
const response = await octokit . request ( 'POST /repos/{owner}/{repo}/pages/deployments' , {
2023-02-22 07:55:03 -06:00
owner : github . context . repo . owner ,
repo : github . context . repo . repo ,
... payload
} )
return response . data
} catch ( error ) {
core . error ( 'Creating Pages deployment failed' , error )
throw error
}
}
async function getPagesDeploymentStatus ( { githubToken , deploymentId } ) {
const octokit = github . getOctokit ( githubToken )
core . info ( 'Getting Pages deployment status...' )
try {
2023-03-15 15:33:59 -04:00
const response = await octokit . request ( 'GET /repos/{owner}/{repo}/pages/deployments/{deploymentId}' , {
2023-02-22 07:55:03 -06:00
owner : github . context . repo . owner ,
repo : github . context . repo . repo ,
deploymentId
} )
return response . data
} catch ( error ) {
core . error ( 'Getting Pages deployment status failed' , error )
throw error
}
}
async function cancelPagesDeployment ( { githubToken , deploymentId } ) {
const octokit = github . getOctokit ( githubToken )
core . info ( 'Canceling Pages deployment...' )
try {
2023-03-15 15:33:59 -04:00
const response = await octokit . request ( 'POST /repos/{owner}/{repo}/pages/deployments/{deploymentId}/cancel' , {
2023-02-22 07:55:03 -06:00
owner : github . context . repo . owner ,
repo : github . context . repo . repo ,
deploymentId
} )
return response . data
} catch ( error ) {
core . error ( 'Canceling Pages deployment failed' , error )
throw error
}
}
module . exports = {
2023-10-27 16:13:35 -04:00
getArtifactMetadata ,
2023-02-22 07:55:03 -06:00
createPagesDeployment ,
getPagesDeploymentStatus ,
cancelPagesDeployment
}