FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
codeql-action/src/api-client.ts at v4.30.8 · github/codeql-action · GitHub
github
/
codeql-action
Public
Notifications
You must be signed in to change notification settings
Fork
493
Star
1.6k
Code
Issues
157
Pull requests
32
Actions
Security and quality
2
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Security and quality
Insights
Expand file tree
Breadcrumbs
codeql-action
/
src
/
api-client.ts
Copy path
More file actions
More file actions
Latest commit
History
History
History
301 lines (261 loc) · 8.95 KB
Breadcrumbs
codeql-action
/
src
/
api-client.ts
Copy path
File metadata and controls
301 lines (261 loc) · 8.95 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
import
*
as
core
from
"@actions/core"
;
import
*
as
githubUtils
from
"@actions/github/lib/utils"
;
import
*
as
retry
from
"@octokit/plugin-retry"
;
import
consoleLogLevel
from
"console-log-level"
;
import
{
getActionVersion
,
getRequiredInput
}
from
"./actions-util"
;
import
{
Logger
}
from
"./logging"
;
import
{
getRepositoryNwo
,
RepositoryNwo
}
from
"./repository"
;
import
{
ConfigurationError
,
getRequiredEnvParam
,
GITHUB_DOTCOM_URL
,
GitHubVariant
,
GitHubVersion
,
isHTTPError
,
parseGitHubUrl
,
parseMatrixInput
,
}
from
"./util"
;
const
GITHUB_ENTERPRISE_VERSION_HEADER
=
"x-github-enterprise-version"
;
export
enum
DisallowedAPIVersionReason
{
ACTION_TOO_OLD
,
ACTION_TOO_NEW
,
}
export
type
GitHubApiCombinedDetails
=
GitHubApiDetails
&
GitHubApiExternalRepoDetails
;
export
interface
GitHubApiDetails
{
auth
:
string
;
url
:
string
;
apiURL
:
string
|
undefined
;
}
export
interface
GitHubApiExternalRepoDetails
{
externalRepoAuth
?:
string
;
url
:
string
;
apiURL
:
string
|
undefined
;
}
function
createApiClientWithDetails
(
apiDetails
:
GitHubApiCombinedDetails
,
{
allowExternal
=
false
}
=
{
}
,
)
{
const
auth
=
(
allowExternal
&&
apiDetails
.
externalRepoAuth
)
||
apiDetails
.
auth
;
const
retryingOctokit
=
githubUtils
.
GitHub
.
plugin
(
retry
.
retry
)
;
return
new
retryingOctokit
(
githubUtils
.
getOctokitOptions
(
auth
,
{
baseUrl
:
apiDetails
.
apiURL
,
userAgent
:
`CodeQL-Action/
${
getActionVersion
(
)
}
`
,
log
:
consoleLogLevel
(
{
level
:
"debug"
}
)
,
}
)
,
)
;
}
export
function
getApiDetails
(
)
:
GitHubApiDetails
{
return
{
auth
:
getRequiredInput
(
"token"
)
,
url
:
getRequiredEnvParam
(
"GITHUB_SERVER_URL"
)
,
apiURL
:
getRequiredEnvParam
(
"GITHUB_API_URL"
)
,
}
;
}
export
function
getApiClient
(
)
{
return
createApiClientWithDetails
(
getApiDetails
(
)
)
;
}
export
function
getApiClientWithExternalAuth
(
apiDetails
:
GitHubApiCombinedDetails
,
)
{
return
createApiClientWithDetails
(
apiDetails
,
{
allowExternal
:
true
}
)
;
}
/**
* Gets a value for the `Authorization` header for a request to `url`; or `undefined` if the
* `Authorization` header should not be set for `url`.
*
*
@param
logger The logger to use for debugging messages.
*
@param
apiDetails Details of the GitHub API we are using.
*
@param
url The URL for which we want to add an `Authorization` header.
*
*
@returns
The value for the `Authorization` header or `undefined` if it shouldn't be populated.
*/
export
function
getAuthorizationHeaderFor
(
logger
:
Logger
,
apiDetails
:
GitHubApiDetails
,
url
:
string
,
)
:
string
|
undefined
{
// We only want to provide an authorization header if we are downloading
// from the same GitHub instance the Action is running on.
// This avoids leaking Enterprise tokens to dotcom.
if
(
url
.
startsWith
(
`
${
apiDetails
.
url
}
/`
)
||
(
apiDetails
.
apiURL
&&
url
.
startsWith
(
`
${
apiDetails
.
apiURL
}
/`
)
)
)
{
logger
.
debug
(
`Providing an authorization token.`
)
;
return
`token
${
apiDetails
.
auth
}
`
;
}
logger
.
debug
(
`Not using an authorization token.`
)
;
return
undefined
;
}
let
cachedGitHubVersion
:
GitHubVersion
|
undefined
=
undefined
;
export
async
function
getGitHubVersionFromApi
(
apiClient
:
any
,
apiDetails
:
GitHubApiDetails
,
)
:
Promise
<
GitHubVersion
>
{
// We can avoid making an API request in the standard dotcom case
if
(
parseGitHubUrl
(
apiDetails
.
url
)
===
GITHUB_DOTCOM_URL
)
{
return
{
type
:
GitHubVariant
.
DOTCOM
}
;
}
// Doesn't strictly have to be the meta endpoint as we're only
// using the response headers which are available on every request.
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const
response
=
await
apiClient
.
rest
.
meta
.
get
(
)
;
// This happens on dotcom, although we expect to have already returned in that
// case. This can also serve as a fallback in cases we haven't foreseen.
if
(
response
.
headers
[
GITHUB_ENTERPRISE_VERSION_HEADER
]
===
undefined
)
{
return
{
type
:
GitHubVariant
.
DOTCOM
}
;
}
if
(
response
.
headers
[
GITHUB_ENTERPRISE_VERSION_HEADER
]
===
"ghe.com"
)
{
return
{
type
:
GitHubVariant
.
GHE_DOTCOM
}
;
}
const
version
=
response
.
headers
[
GITHUB_ENTERPRISE_VERSION_HEADER
]
as
string
;
return
{
type
:
GitHubVariant
.
GHES
,
version
}
;
}
/**
* Report the GitHub server version. This is a wrapper around
* util.getGitHubVersion() that automatically supplies GitHub API details using
* GitHub Action inputs.
*
*
@returns
GitHub version
*/
export
async
function
getGitHubVersion
(
)
:
Promise
<
GitHubVersion
>
{
if
(
cachedGitHubVersion
===
undefined
)
{
cachedGitHubVersion
=
await
getGitHubVersionFromApi
(
getApiClient
(
)
,
getApiDetails
(
)
,
)
;
}
return
cachedGitHubVersion
;
}
/**
* Get the path of the currently executing workflow relative to the repository root.
*/
export
async
function
getWorkflowRelativePath
(
)
:
Promise
<
string
>
{
const
repo_nwo
=
getRepositoryNwo
(
)
;
const
run_id
=
Number
(
getRequiredEnvParam
(
"GITHUB_RUN_ID"
)
)
;
const
apiClient
=
getApiClient
(
)
;
const
runsResponse
=
await
apiClient
.
request
(
"GET /repos/:owner/:repo/actions/runs/:run_id?exclude_pull_requests=true"
,
{
owner
:
repo_nwo
.
owner
,
repo
:
repo_nwo
.
repo
,
run_id
,
}
,
)
;
const
workflowUrl
=
runsResponse
.
data
.
workflow_url
;
const
requiredWorkflowRegex
=
/
\/
r
e
p
o
s
\/
[
^
/
]
+
\/
[
^
/
]
+
\/
a
c
t
i
o
n
s
\/
r
e
q
u
i
r
e
d
_
w
o
r
k
f
l
o
w
s
\/
[
^
/
]
+
/
;
if
(
!
workflowUrl
||
requiredWorkflowRegex
.
test
(
workflowUrl
as
string
)
)
{
// For required workflows, the workflowUrl is invalid so we cannot fetch more informations
// about the workflow.
// However, the path is available in the original response.
return
runsResponse
.
data
.
path
as
string
;
}
const
workflowResponse
=
await
apiClient
.
request
(
`GET
${
workflowUrl
}
`
)
;
return
workflowResponse
.
data
.
path
as
string
;
}
/**
* Get the analysis key parameter for the current job.
*
* This will combine the workflow path and current job name.
* Computing this the first time requires making requests to
* the GitHub API, but after that the result will be cached.
*/
export
async
function
getAnalysisKey
(
)
:
Promise
<
string
>
{
const
analysisKeyEnvVar
=
"CODEQL_ACTION_ANALYSIS_KEY"
;
let
analysisKey
=
process
.
env
[
analysisKeyEnvVar
]
;
if
(
analysisKey
!==
undefined
)
{
return
analysisKey
;
}
const
workflowPath
=
await
getWorkflowRelativePath
(
)
;
const
jobName
=
getRequiredEnvParam
(
"GITHUB_JOB"
)
;
analysisKey
=
`
${
workflowPath
}
:
${
jobName
}
`
;
core
.
exportVariable
(
analysisKeyEnvVar
,
analysisKey
)
;
return
analysisKey
;
}
export
async
function
getAutomationID
(
)
:
Promise
<
string
>
{
const
analysis_key
=
await
getAnalysisKey
(
)
;
const
environment
=
getRequiredInput
(
"matrix"
)
;
return
computeAutomationID
(
analysis_key
,
environment
)
;
}
export
function
computeAutomationID
(
analysis_key
:
string
,
environment
:
string
|
undefined
,
)
:
string
{
let
automationID
=
`
${
analysis_key
}
/`
;
const
matrix
=
parseMatrixInput
(
environment
)
;
if
(
matrix
!==
undefined
)
{
// the id has to be deterministic so we sort the fields
for
(
const
entry
of
Object
.
entries
(
matrix
)
.
sort
(
)
)
{
if
(
typeof
entry
[
1
]
===
"string"
)
{
automationID
+=
`
${
entry
[
0
]
}
:
${
entry
[
1
]
}
/`
;
}
else
{
// In code scanning we just handle the string values,
// the rest get converted to the empty string
automationID
+=
`
${
entry
[
0
]
}
:/`
;
}
}
}
return
automationID
;
}
export
interface
ActionsCacheItem
{
created_at
?:
string
;
id
?:
number
;
key
?:
string
;
size_in_bytes
?:
number
;
}
/** List all Actions cache entries matching the provided key and ref. */
export
async
function
listActionsCaches
(
key
:
string
,
ref
?:
string
,
)
:
Promise
<
ActionsCacheItem
[
]
>
{
const
repositoryNwo
=
getRepositoryNwo
(
)
;
return
await
getApiClient
(
)
.
paginate
(
"GET /repos/{owner}/{repo}/actions/caches"
,
{
owner
:
repositoryNwo
.
owner
,
repo
:
repositoryNwo
.
repo
,
key
,
ref
,
}
,
)
;
}
/** Delete an Actions cache item by its ID. */
export
async
function
deleteActionsCache
(
id
:
number
)
{
const
repositoryNwo
=
getRepositoryNwo
(
)
;
await
getApiClient
(
)
.
rest
.
actions
.
deleteActionsCacheById
(
{
owner
:
repositoryNwo
.
owner
,
repo
:
repositoryNwo
.
repo
,
cache_id
:
id
,
}
)
;
}
/** Retrieve all custom repository properties. */
export
async
function
getRepositoryProperties
(
repositoryNwo
:
RepositoryNwo
)
{
return
getApiClient
(
)
.
request
(
"GET /repos/:owner/:repo/properties/values"
,
{
owner
:
repositoryNwo
.
owner
,
repo
:
repositoryNwo
.
repo
,
}
)
;
}
export
function
wrapApiConfigurationError
(
e
:
unknown
)
{
if
(
isHTTPError
(
e
)
)
{
if
(
e
.
message
.
includes
(
"API rate limit exceeded for installation"
)
||
e
.
message
.
includes
(
"commit not found"
)
||
e
.
message
.
includes
(
"Resource not accessible by integration"
)
||
/
r
e
f
.
*
n
o
t
f
o
u
n
d
i
n
t
h
i
s
r
e
p
o
s
i
t
o
r
y
/
.
test
(
e
.
message
)
)
{
return
new
ConfigurationError
(
e
.
message
)
;
}
else
if
(
e
.
message
.
includes
(
"Bad credentials"
)
||
e
.
message
.
includes
(
"Not Found"
)
)
{
return
new
ConfigurationError
(
"Please check that your token is valid and has the required permissions: contents: read, security-events: write"
,
)
;
}
}
return
e
;
}
Back
|
FazBrowse Home
|
New Git URL