Skip to content

Commit 497da40

Browse files
authored
Merge pull request #124 from actions/actions-http-client
Use the `@actions/http-client` and `@actions/github` modules for proxy support
2 parents 3adc03e + ce35ecd commit 497da40

File tree

9 files changed

+8267
-7914
lines changed

9 files changed

+8267
-7914
lines changed

dist/index.js

Lines changed: 6857 additions & 7225 deletions
Large diffs are not rendered by default.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/licenses.txt

Lines changed: 436 additions & 151 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 430 additions & 204 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
"main": "./dist/index.js",
66
"dependencies": {
77
"@actions/core": "^1.10.0",
8-
"axios": "^1.3.3",
9-
"axios-retry": "^3.2.4"
8+
"@actions/github": "^5.1.1",
9+
"@actions/http-client": "^2.0.1",
10+
"@octokit/request-error": "^3.0.3",
11+
"http-status-messages": "^1.1.0"
1012
},
1113
"devDependencies": {
1214
"@vercel/ncc": "^0.31.1",

src/api-client.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
const core = require('@actions/core')
2+
const github = require('@actions/github')
3+
const hc = require('@actions/http-client')
4+
const { RequestError } = require('@octokit/request-error')
5+
const HttpStatusMessages = require('http-status-messages')
6+
7+
// All variables we need from the runtime are loaded here
8+
const getContext = require('./context')
9+
10+
async function processRuntimeResponse(res, requestOptions) {
11+
// Parse the response body as JSON
12+
let obj = null
13+
try {
14+
const contents = await res.readBody()
15+
if (contents && contents.length > 0) {
16+
obj = JSON.parse(contents)
17+
}
18+
} catch (error) {
19+
// Invalid resource (contents not json); leaving resulting obj as null
20+
}
21+
22+
// Specific response shape aligned with Octokit
23+
const response = {
24+
url: res.message?.url || requestOptions.url,
25+
status: res.message?.statusCode || 0,
26+
headers: {
27+
...res.message?.headers
28+
},
29+
data: obj
30+
}
31+
32+
// Forcibly throw errors for negative HTTP status codes!
33+
// @actions/http-client doesn't do this by default.
34+
// Mimic the errors thrown by Octokit for consistency.
35+
if (response.status >= 400) {
36+
// Try to get an error message from the response body
37+
const errorMsg =
38+
(typeof response.data === 'string' && response.data) ||
39+
response.data?.error ||
40+
response.data?.message ||
41+
// Try the Node HTTP IncomingMessage's statusMessage property
42+
res.message?.statusMessage ||
43+
// Fallback to the HTTP status message based on the status code
44+
HttpStatusMessages[response.status] ||
45+
// Or if the status code is unexpected...
46+
`Unknown error (${response.status})`
47+
48+
throw new RequestError(errorMsg, response.status, {
49+
response,
50+
request: requestOptions
51+
})
52+
}
53+
54+
return response
55+
}
56+
57+
async function getSignedArtifactUrl({ runtimeToken, workflowRunId, artifactName }) {
58+
const { runTimeUrl: RUNTIME_URL } = getContext()
59+
const artifactExchangeUrl = `${RUNTIME_URL}_apis/pipelines/workflows/${workflowRunId}/artifacts?api-version=6.0-preview`
60+
61+
const httpClient = new hc.HttpClient()
62+
let data = null
63+
64+
try {
65+
const requestHeaders = {
66+
accept: 'application/json',
67+
authorization: `Bearer ${runtimeToken}`
68+
}
69+
const requestOptions = {
70+
method: 'GET',
71+
url: artifactExchangeUrl,
72+
headers: {
73+
...requestHeaders
74+
},
75+
body: null
76+
}
77+
78+
core.info(`Artifact exchange URL: ${artifactExchangeUrl}`)
79+
const res = await httpClient.get(artifactExchangeUrl, requestHeaders)
80+
81+
// May throw a RequestError (HttpError)
82+
const response = await processRuntimeResponse(res, requestOptions)
83+
84+
data = response.data
85+
core.debug(JSON.stringify(data))
86+
} catch (error) {
87+
core.error('Getting signed artifact URL failed', error)
88+
throw error
89+
}
90+
91+
const artifactRawUrl = data?.value?.find(artifact => artifact.name === artifactName)?.url
92+
if (!artifactRawUrl) {
93+
throw new Error(
94+
'No uploaded artifact was found! Please check if there are any errors at build step, or uploaded artifact name is correct.'
95+
)
96+
}
97+
98+
const signedArtifactUrl = `${artifactRawUrl}&%24expand=SignedContent`
99+
return signedArtifactUrl
100+
}
101+
102+
async function createPagesDeployment({ githubToken, artifactUrl, buildVersion, idToken, isPreview = false }) {
103+
const octokit = github.getOctokit(githubToken)
104+
105+
const payload = {
106+
artifact_url: artifactUrl,
107+
pages_build_version: buildVersion,
108+
oidc_token: idToken
109+
}
110+
if (isPreview === true) {
111+
payload.preview = true
112+
}
113+
core.info(`Creating Pages deployment with payload:\n${JSON.stringify(payload, null, '\t')}`)
114+
115+
try {
116+
const response = await octokit.request('POST /repos/{owner}/{repo}/pages/deployment', {
117+
owner: github.context.repo.owner,
118+
repo: github.context.repo.repo,
119+
...payload
120+
})
121+
122+
return response.data
123+
} catch (error) {
124+
core.error('Creating Pages deployment failed', error)
125+
throw error
126+
}
127+
}
128+
129+
async function getPagesDeploymentStatus({ githubToken, deploymentId }) {
130+
const octokit = github.getOctokit(githubToken)
131+
132+
core.info('Getting Pages deployment status...')
133+
try {
134+
const response = await octokit.request('GET /repos/{owner}/{repo}/pages/deployment/status/{deploymentId}', {
135+
owner: github.context.repo.owner,
136+
repo: github.context.repo.repo,
137+
deploymentId
138+
})
139+
140+
return response.data
141+
} catch (error) {
142+
core.error('Getting Pages deployment status failed', error)
143+
throw error
144+
}
145+
}
146+
147+
async function cancelPagesDeployment({ githubToken, deploymentId }) {
148+
const octokit = github.getOctokit(githubToken)
149+
150+
core.info('Canceling Pages deployment...')
151+
try {
152+
const response = await octokit.request('PUT /repos/{owner}/{repo}/pages/deployment/cancel/{deploymentId}', {
153+
owner: github.context.repo.owner,
154+
repo: github.context.repo.repo,
155+
deploymentId
156+
})
157+
158+
return response.data
159+
} catch (error) {
160+
core.error('Canceling Pages deployment failed', error)
161+
throw error
162+
}
163+
}
164+
165+
module.exports = {
166+
getSignedArtifactUrl,
167+
createPagesDeployment,
168+
getPagesDeploymentStatus,
169+
cancelPagesDeployment
170+
}

0 commit comments

Comments
 (0)