Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the @actions/http-client and @actions/github modules for proxy support #124

Merged
merged 38 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
a7cb42f
Switch dependencies
JamesMGreene Feb 16, 2023
93c1fe6
Add a module to wrap GitHub REST API and Actions Runtime API requests
JamesMGreene Feb 22, 2023
20fe504
Clarify references to Action ID and Workflow Run ID in logging
JamesMGreene Feb 22, 2023
c291820
Swap out the Artifact Exchange interaction for the wrapped one from a…
JamesMGreene Feb 22, 2023
e7873ec
Swap out the Pages Deployment creation interaction for the wrapped on…
JamesMGreene Feb 22, 2023
12b8ec3
Move setting 'page_url' output variable to top-level index
JamesMGreene Feb 22, 2023
a0faa04
Swap out the Pages Deployment status check interaction for the wrappe…
JamesMGreene Feb 22, 2023
f577a41
Swap out the Pages Deployment canceling interaction for the wrapped o…
JamesMGreene Feb 22, 2023
29db692
JS polishing
JamesMGreene Feb 22, 2023
594fd8f
Remove axios reference from code
JamesMGreene Feb 22, 2023
65f1527
Fix bad references, run the formatter
JamesMGreene Feb 22, 2023
cb00670
Update distributables
JamesMGreene Feb 22, 2023
4d06ee6
Update Deployment class methods to enforce presence of this.deploymen…
JamesMGreene Feb 22, 2023
36aae3e
Update Octokit usage to use request.js for deployment creation
JamesMGreene Feb 24, 2023
e47a74e
Update distributables
JamesMGreene Feb 24, 2023
f3ccae1
Update status handling function for Octokit request
JamesMGreene Mar 3, 2023
1947635
Update distributables
JamesMGreene Mar 3, 2023
c8c985c
Defer looking up RUNTIME_URL until JIT
JamesMGreene Mar 5, 2023
c981f59
Tweak verbosity levels
JamesMGreene Mar 7, 2023
452af0a
Update distributables
JamesMGreene Mar 7, 2023
6f75b99
Lots of test updates
JamesMGreene Mar 7, 2023
93872af
Update test with module wrapper
JamesMGreene Mar 7, 2023
b88aa87
Consolidate before functions
JamesMGreene Mar 7, 2023
b4ef3c2
Add test for cancellation
JamesMGreene Mar 7, 2023
973ee9b
Update distributables
JamesMGreene Mar 7, 2023
f2ea9e9
Merge branch 'main' into actions-http-client
JamesMGreene Mar 7, 2023
4c19579
Merge branch 'main' into actions-http-client
JamesMGreene Mar 8, 2023
8ca11f2
Add some packages for error management
JamesMGreene Mar 9, 2023
54e5e8c
Update error handling for artifact exchange
JamesMGreene Mar 9, 2023
7ee7a04
Update distributables
JamesMGreene Mar 9, 2023
360f95f
Extract response processing logic from Artifact Exchange method
JamesMGreene Mar 9, 2023
02bdb05
Update distributables
JamesMGreene Mar 9, 2023
f824564
Make sure we received a deployment response before setting deployment…
JamesMGreene Mar 9, 2023
df61277
Update distributables
JamesMGreene Mar 9, 2023
7e85efa
Remove redundant safe navigation operators
JamesMGreene Mar 9, 2023
44b836a
Update distributables
JamesMGreene Mar 9, 2023
a8d1a4c
Prefer elevated RequestError#status, if present
JamesMGreene Mar 9, 2023
ce35ecd
Update distributables
JamesMGreene Mar 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14,082 changes: 6,857 additions & 7,225 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

587 changes: 436 additions & 151 deletions dist/licenses.txt

Large diffs are not rendered by default.

634 changes: 430 additions & 204 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
"main": "./dist/index.js",
"dependencies": {
"@actions/core": "^1.10.0",
"axios": "^1.3.3",
"axios-retry": "^3.2.4"
"@actions/github": "^5.1.1",
"@actions/http-client": "^2.0.1",
"@octokit/request-error": "^3.0.3",
"http-status-messages": "^1.1.0"
},
"devDependencies": {
"@vercel/ncc": "^0.31.1",
Expand Down
170 changes: 170 additions & 0 deletions src/api-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
const core = require('@actions/core')
const github = require('@actions/github')
const hc = require('@actions/http-client')
const { RequestError } = require('@octokit/request-error')
const HttpStatusMessages = require('http-status-messages')

// All variables we need from the runtime are loaded here
const getContext = require('./context')

async function processRuntimeResponse(res, requestOptions) {
// Parse the response body as JSON
let obj = null
try {
const contents = await res.readBody()
if (contents && contents.length > 0) {
obj = JSON.parse(contents)
}
} catch (error) {
// Invalid resource (contents not json); leaving resulting obj as null
}

// Specific response shape aligned with Octokit
const response = {
url: res.message?.url || requestOptions.url,
status: res.message?.statusCode || 0,
headers: {
...res.message?.headers
},
data: obj
}

// Forcibly throw errors for negative HTTP status codes!
// @actions/http-client doesn't do this by default.
// Mimic the errors thrown by Octokit for consistency.
if (response.status >= 400) {
// Try to get an error message from the response body
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 ||
// Fallback to the HTTP status message based on the status code
HttpStatusMessages[response.status] ||
// Or if the status code is unexpected...
`Unknown error (${response.status})`

throw new RequestError(errorMsg, response.status, {
response,
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',
url: artifactExchangeUrl,
headers: {
...requestHeaders
},
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
core.debug(JSON.stringify(data))
} catch (error) {
JamesMGreene marked this conversation as resolved.
Show resolved Hide resolved
core.error('Getting signed artifact URL failed', error)
throw error
}

const artifactRawUrl = data?.value?.find(artifact => artifact.name === artifactName)?.url
if (!artifactRawUrl) {
throw new Error(
'No uploaded artifact was found! Please check if there are any errors at build step, or uploaded artifact name is correct.'
)
}

const signedArtifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
return signedArtifactUrl
}

async function createPagesDeployment({ githubToken, artifactUrl, buildVersion, idToken, isPreview = false }) {
const octokit = github.getOctokit(githubToken)

const payload = {
artifact_url: artifactUrl,
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 {
const response = await octokit.request('POST /repos/{owner}/{repo}/pages/deployment', {
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 {
const response = await octokit.request('GET /repos/{owner}/{repo}/pages/deployment/status/{deploymentId}', {
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 {
const response = await octokit.request('PUT /repos/{owner}/{repo}/pages/deployment/cancel/{deploymentId}', {
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 = {
getSignedArtifactUrl,
createPagesDeployment,
getPagesDeploymentStatus,
cancelPagesDeployment
}
Loading