Skip to content

Commit 9993a95

Browse files
committed
Add: Extend GitHub API for code scanning analyses
Add GitHub API for getting and deleting code scanning analyses.
1 parent efe1544 commit 9993a95

File tree

4 files changed

+493
-0
lines changed

4 files changed

+493
-0
lines changed

pontos/github/api/code_scanning.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pontos.github.models.code_scanning import (
1010
AlertSort,
1111
AlertState,
12+
Analysis,
1213
CodeScanningAlert,
1314
DismissedReason,
1415
Instance,
@@ -309,3 +310,148 @@ async def instances(
309310
async for response in self._client.get_all(api, params=params):
310311
for alert in response.json():
311312
yield Instance.from_dict(alert)
313+
314+
async def analyses(
315+
self,
316+
repo: str,
317+
*,
318+
tool_name: Optional[str] = None,
319+
tool_guid: Optional[str] = "",
320+
ref: Optional[str] = None,
321+
sarif_id: Optional[str] = None,
322+
direction: Union[str, SortOrder] = SortOrder.DESC,
323+
) -> AsyncIterator[Analysis]:
324+
"""
325+
Lists the details of all code scanning analyses for a repository,
326+
starting with the most recent.
327+
328+
https://docs.github.com/en/rest/code-scanning/code-scanning#list-code-scanning-analyses-for-a-repository
329+
330+
Args:
331+
repo: GitHub repository (owner/name)
332+
tool_name: The name of a code scanning tool. Only results by this
333+
tool will be listed. You can specify the tool by using either
334+
tool_name or tool_guid, but not both.
335+
tool_guid: The GUID of a code scanning tool. Only results by this
336+
tool will be listed. Note that some code scanning tools may not
337+
include a GUID in their analysis data. You can specify the tool
338+
by using either tool_guid or tool_name, but not both
339+
ref: The Git reference for the analyses you want to list. The ref
340+
for a branch can be formatted either as refs/heads/<branch name>
341+
or simply <branch name>. To reference a pull request use
342+
refs/pull/<number>/merge.
343+
sarif_id: Filter analyses belonging to the same SARIF upload
344+
345+
Raises:
346+
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
347+
failed.
348+
349+
Returns:
350+
An async iterator yielding the code scanning alert analysis data
351+
352+
Example:
353+
.. code-block:: python
354+
355+
from pontos.github.api import GitHubAsyncRESTApi
356+
357+
async with GitHubAsyncRESTApi(token) as api:
358+
async for data in api.code_scanning.analyses(
359+
"org/repo"
360+
):
361+
print(data)
362+
"""
363+
364+
api = f"/repos/{repo}/code-scanning/analyses"
365+
params: dict[str, Union[str, None]] = {"per_page": "100"}
366+
367+
if tool_name:
368+
params["tool_name"] = tool_name
369+
if tool_guid or tool_guid is None:
370+
params["tool_guid"] = tool_guid
371+
if ref:
372+
params["ref"] = ref
373+
if sarif_id:
374+
params["sarif_id"] = sarif_id
375+
if direction:
376+
params["direction"] = enum_or_value(direction)
377+
378+
async for response in self._client.get_all(api, params=params):
379+
response.raise_for_status()
380+
381+
for alert in response.json():
382+
yield Analysis.from_dict(alert)
383+
384+
async def analysis(
385+
self,
386+
repo: str,
387+
analysis_id: Union[int, str],
388+
) -> Analysis:
389+
"""
390+
Gets a specified code scanning analysis for a repository
391+
392+
https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-analysis-for-a-repository
393+
394+
Args:
395+
repo: GitHub repository (owner/name)
396+
analysis_id: The ID of the analysis
397+
398+
Raises:
399+
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
400+
failed.
401+
402+
Returns:
403+
Code scanning alert analysis data
404+
405+
Example:
406+
.. code-block:: python
407+
408+
from pontos.github.api import GitHubAsyncRESTApi
409+
410+
async with GitHubAsyncRESTApi(token) as api:
411+
analysis = await api.code_scanning.analysis(
412+
"org/repo", 123
413+
)
414+
print(analysis)
415+
"""
416+
417+
api = f"/repos/{repo}/code-scanning/analyses/{analysis_id}"
418+
response = await self._client.get(api)
419+
response.raise_for_status()
420+
return Analysis.from_dict(response.json())
421+
422+
async def delete_analysis(
423+
self,
424+
repo: str,
425+
analysis_id: Union[int, str],
426+
) -> dict[str, str]:
427+
"""
428+
Delete a specified code scanning analysis from a repository
429+
430+
https://docs.github.com/en/rest/code-scanning/code-scanning#delete-a-code-scanning-analysis-from-a-repository
431+
432+
Args:
433+
repo: GitHub repository (owner/name)
434+
analysis_id: The ID of the analysis
435+
436+
Raises:
437+
HTTPStatusError: A httpx.HTTPStatusError is raised if the request
438+
failed.
439+
440+
Returns:
441+
See the GitHub documentation for the response object
442+
443+
Example:
444+
.. code-block:: python
445+
446+
from pontos.github.api import GitHubAsyncRESTApi
447+
448+
async with GitHubAsyncRESTApi(token) as api:
449+
await api.code_scanning.delete(
450+
"org/repo", 123
451+
)
452+
"""
453+
454+
api = f"/repos/{repo}/code-scanning/analyses/{analysis_id}"
455+
response = await self._client.delete(api)
456+
response.raise_for_status()
457+
return response.json()

pontos/github/models/code_scanning.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,51 @@ class CodeScanningAlert(GitHubModel):
233233
dismissed_at: Optional[datetime] = None
234234
dismissed_reason: Optional[DismissedReason] = None
235235
dismissed_comment: Optional[str] = None
236+
237+
238+
@dataclass
239+
class Analysis(GitHubModel):
240+
"""
241+
Details for a code scanning analyses
242+
243+
Attributes:
244+
ref: The full Git reference, formatted as `refs/heads/<branch name>`,
245+
`refs/pull/<number>/merge`, or `refs/pull/<number>/head`
246+
commit_sha: The SHA of the commit to which the analysis you are
247+
uploading relates
248+
analysis_key: Identifies the configuration under which the analysis was
249+
executed. For example, in GitHub Actions this includes the workflow
250+
filename and job name
251+
environment: Identifies the variable values associated with the
252+
environment in which this analysis was performed
253+
category: Identifies the configuration under which the analysis was
254+
executed. Used to distinguish between multiple analyses for the same
255+
tool and commit, but performed on different languages or different
256+
parts of the code
257+
error: Error generated when processing the analysis
258+
created_at: The time that the analysis was created
259+
results_count: The total number of results in the analysis
260+
rules_count: The total number of rules used in the analysis
261+
id: Unique identifier for this analysis
262+
url: The REST API URL of the analysis resource
263+
sarif_id: An identifier for the upload
264+
tool: The tool used to generate the code scanning analysis
265+
deletable:
266+
warning: Warning generated when processing the analysis
267+
"""
268+
269+
ref: str
270+
commit_sha: str
271+
analysis_key: str
272+
environment: str
273+
category: str
274+
error: str
275+
created_at: datetime
276+
results_count: int
277+
rules_count: int
278+
id: int
279+
url: str
280+
sarif_id: str
281+
tool: Tool
282+
deletable: bool
283+
warning: str

0 commit comments

Comments
 (0)