Skip to content

15 add dependabot alert information #23

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

Merged
merged 5 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ An example of use is below. Note that the custom inputs, such as if you are wan

```yaml
- name: CSV export
uses: some-natalie/ghas-to-csv@v1
uses: some-natalie/ghas-to-csv@v2
env:
GITHUB_PAT: ${{ secrets.PAT }} # you need to set a PAT
- name: Upload CSV
Expand All @@ -51,7 +51,7 @@ To run this targeting an organization, here's an example:

```yaml
- name: CSV export
uses: some-natalie/ghas-to-csv@v1
uses: some-natalie/ghas-to-csv@v2
env:
GITHUB_PAT: ${{ secrets.PAT }}
GITHUB_REPORT_SCOPE: "organization"
Expand All @@ -62,7 +62,7 @@ Or for an enterprise:

```yaml
- name: CSV export
uses: some-natalie/ghas-to-csv@v1
uses: some-natalie/ghas-to-csv@v2
env:
GITHUB_PAT: ${{ secrets.PAT }}
GITHUB_REPORT_SCOPE: "enterprise"
Expand All @@ -75,7 +75,7 @@ Or for an enterprise:
| --- | --- | --- | --- | --- |
| Secret scanning | :white_check_mark: Repo<br>:white_check_mark: Org<br>:white_check_mark: Enterprise | :white_check_mark: Repo<br>:white_check_mark: Org<br>:white_check_mark: Enterprise | :white_check_mark: Repo<br>:x: Org<br>:x: Enterprise | [API docs](https://docs.github.com/en/enterprise-cloud@latest/rest/reference/secret-scanning) |
| Code scanning | :white_check_mark: Repo<br>:white_check_mark: Org<br>:white_check_mark: Enterprise | :white_check_mark: Repo<br>:white_check_mark: Org<br>:curly_loop: Enterprise | :white_check_mark: Repo<br>:x: Org<br>:curly_loop: Enterprise | [API docs](https://docs.github.com/en/enterprise-cloud@latest/rest/reference/code-scanning) |
| Dependabot | :x: | :x: | :x: | Waiting on [this API](https://github.com/github/roadmap/issues/495) to :ship: |
| Dependabot | :white_check_mark: Repo<br>:x: Org<br>:x: Enterprise | :x: | :x: | [API docs](https://docs.github.com/en/enterprise-cloud@latest/rest/dependabot/alerts) |

:information_source: All of this reporting requires either public repositories or a GitHub Advanced Security license.

Expand All @@ -99,7 +99,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: CSV export
uses: some-natalie/ghas-to-csv@v1
uses: some-natalie/ghas-to-csv@v2
env:
GITHUB_PAT: ${{ secrets.PAT }} # needed if not running against the current repository
SCOPE_NAME: "OWNER-NAME/REPO-NAME" # repository name, needed only if not running against the current repository
Expand Down
10 changes: 9 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""

# Import modules
from src import code_scanning, enterprise, secret_scanning
from src import code_scanning, dependabot, enterprise, secret_scanning
import os

# Read in config values
Expand Down Expand Up @@ -84,6 +84,14 @@
api_endpoint, github_pat, scope_name
)
code_scanning.write_repo_cs_list(cs_list)
# dependabot alerts
if enterprise.get_enterprise_version(api_endpoint) == "GHEC":
dependabot_list = dependabot.list_repo_dependabot_alerts(
api_endpoint, github_pat, scope_name
)
dependabot.write_repo_dependabot_list(dependabot_list)
else:
pass
# secret scanning
secrets_list = secret_scanning.get_repo_secret_scanning_alerts(
api_endpoint, github_pat, scope_name
Expand Down
2 changes: 2 additions & 0 deletions src/code_scanning.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def list_repo_code_scanning_alerts(api_endpoint, github_pat, repo_name):
response = requests.get(response.links["next"]["url"], headers=headers)
response_json.extend(response.json())

print("Found {} code scanning alerts in {}".format(len(response_json), repo_name))

# Return code scanning alerts
return response_json

Expand Down
107 changes: 107 additions & 0 deletions src/dependabot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# This holds all the things that do stuff for code scanning API

# Imports
from defusedcsv import csv
import requests


def list_repo_dependabot_alerts(api_endpoint, github_pat, repo_name):
"""
Get all the code scanning alerts on a given repository.

Inputs:
- API endpoint (for GHES/GHAE compatibility)
- PAT of appropriate scope
- Repository name

Outputs:
- List of _all_ dependency alerts on the repository
"""

# Get code scanning alerts
url = "{}/repos/{}/dependabot/alerts?per_page=100&page=1".format(
api_endpoint, repo_name
)
response = requests.get(
url,
headers={
"Authorization": "token {}".format(github_pat),
"Accept": "application/vnd.github+json",
},
)
response_json = response.json()
while "next" in response.links.keys():
response = requests.get(
response.links["next"]["url"],
headers={"Authorization": "token {}".format(github_pat)},
)
response_json.extend(response.json())

print("Found {} dependabot alerts in {}".format(len(response_json), repo_name))

# Return code scanning alerts
return response_json


def write_repo_dependabot_list(dependabot_list):
"""
Write the list of dependabot alerts to a CSV file.

Inputs:
- List of dependabot alerts

Outputs:
- CSV file of dependabot alerts
"""
with open("dependabot_list.csv", "w") as f:
writer = csv.writer(f)
writer.writerow(
[
"number",
"state",
"created_at",
"updated_at",
"fixed_at",
"dismissed_at",
"dismissed_by",
"dismissed_reason",
"html_url",
"dependency_manifest",
"dependency_ecosystem",
"dependency_name",
"severity",
"ghsa_id",
"cve_id",
]
)
for alert in dependabot_list:
if alert["state"] == "open":
alert["fixed_at"] = "none"
alert["dismissed_by"] = "none"
alert["dismissed_at"] = "none"
alert["dismissed_reason"] = "none"
if alert["state"] == "dismissed":
alert["fixed_at"] = "none"
if alert["state"] == "fixed":
alert["dismissed_by"] = "none"
alert["dismissed_at"] = "none"
alert["dismissed_reason"] = "none"
writer.writerow(
[
alert["number"],
alert["state"],
alert["created_at"],
alert["updated_at"],
alert["fixed_at"],
alert["dismissed_at"],
alert["dismissed_by"],
alert["dismissed_reason"],
alert["html_url"],
alert["dependency"]["manifest_path"],
alert["dependency"]["package"]["ecosystem"],
alert["dependency"]["package"]["name"],
alert["security_vulnerability"]["severity"],
alert["security_advisory"]["ghsa_id"],
alert["security_advisory"]["cve_id"],
]
)