-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathapi-client.js
180 lines (153 loc) · 5.23 KB
/
api-client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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 getSignedArtifactMetadata({ 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) {
core.error('Getting signed artifact URL failed', error)
throw error
}
const artifact = data?.value?.find(artifact => artifact.name === artifactName)
const artifactRawUrl = artifact?.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`
const artifactSize = artifact?.size
if (!artifactSize) {
core.warning('Artifact size was not found. Unable to verify if artifact size exceeds the allowed size.')
}
return {
url: signedArtifactUrl,
size: artifactSize
}
}
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/deployments', {
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/deployments/{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('POST /repos/{owner}/{repo}/pages/deployments/{deploymentId}/cancel', {
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 = {
getSignedArtifactMetadata,
createPagesDeployment,
getPagesDeploymentStatus,
cancelPagesDeployment
}