Skip to content
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

Add Base and Ref support to inputs #121

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
8 changes: 8 additions & 0 deletions ghascompliance/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
github_arguments.add_argument("--github-repository", default=GITHUB_REPOSITORY)
# github_arguments.add_argument("--github-event", default=GITHUB_EVENT_PATH)
github_arguments.add_argument("--github-ref", default=GITHUB_REF)
github_arguments.add_argument("--github-base-ref", default=None)
github_arguments.add_argument("--github-head-ref", default=None)
# github_arguments.add_argument("--workflow-event", default=GITHUB_EVENT_NAME)
github_arguments.add_argument("--github-policy")
github_arguments.add_argument("--github-policy-branch", default="main")
Expand Down Expand Up @@ -101,6 +103,10 @@
)
Octokit.info(f"GitHub Instance :: {GitHub.instance}")
Octokit.info(f"GitHub Reference (branch/pr) :: {GitHub.repository.reference}")
if arguments.github_base_ref:
Octokit.info(f"GitHub Base Reference :: {arguments.github_base_ref}")
if arguments.github_head_ref:
Octokit.info(f"GitHub Head Reference :: {arguments.github_head_ref}")

if arguments.list_severities:
for severity in SEVERITIES:
Expand Down Expand Up @@ -186,6 +192,8 @@
display=arguments.display,
results_path=results,
caching=arguments.disable_caching,
base_ref=arguments.github_base_ref,
head_ref=arguments.github_head_ref,
)

errors = 0
Expand Down
95 changes: 75 additions & 20 deletions ghascompliance/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def __init__(
debugging: bool = False,
results_path: str = ".compliance",
caching: bool = True,
base_ref: str = None,
head_ref: str = None,
):
self.policy = policy

Expand All @@ -40,6 +42,9 @@ def __init__(

self.caching = caching

self.base_ref = base_ref
self.head_ref = head_ref

os.makedirs(self.results, exist_ok=True)

def getResults(self, name: str, callback: Callable, file_type: str = "json"):
Expand Down Expand Up @@ -83,7 +88,11 @@ def checkCodeScanning(self):
Octokit.info("Code Scanning is not active in the policy")
return 0

if GitHub.repository.isInPullRequest():
if self.base_ref:
Octokit.info("Code Scanning Alerts from Base Ref (alert diff)")
alerts = codescanning.getAlertsInPR(self.base_ref)

elif GitHub.repository.isInPullRequest():
Octokit.info("Code Scanning Alerts from Pull Request (alert diff)")
pr_base = (
GitHub.repository.getPullRequestInfo().get("base", {}).get("ref", "")
Expand Down Expand Up @@ -187,7 +196,25 @@ def checkDependabot(self):

depgraph = DependencyGraph()

if GitHub.repository.isInPullRequest():
if self.base_ref and self.head_ref:
Octokit.info("Dependabot Alerts from Base Ref (alert diff)")
dependencies = depgraph.getDependenciesInPR(self.base_ref, self.head_ref)
alerts = []
try:
open_alerts = dependabot.getAlerts("open")
for pending_alert in open_alerts:
for alert in dependencies:
if pending_alert.manifest == alert.path:
# Compare the Purl
if alert.getPurl(version=False) == pending_alert.purl:
# check if the security_advisory ghsa_id matches the alert vulnerabilitity advisory_ghsa_id
for vuln in alert.alerts:
if vuln.advisory.ghsa_id == pending_alert.advisory.ghsa_id:
alerts.append(pending_alert)
break
except Exception as err:
Octokit.warning(f"Unable to get Dependabot alerts :: {err}")
elif GitHub.repository.isInPullRequest():
Octokit.info("Dependabot Alerts from Pull Request")
pr_info = GitHub.repository.getPullRequestInfo()
pr_base = pr_info.get("base", {}).get("ref", "")
Expand All @@ -196,8 +223,20 @@ def checkDependabot(self):
# note, need to use dep review API
dependencies = depgraph.getDependenciesInPR(pr_base, pr_head)
alerts = []
for dep in dependencies:
alerts.extend(dep.alerts)
try:
open_alerts = dependabot.getAlerts("open")
for pending_alert in open_alerts:
for alert in dependencies:
if pending_alert.manifest == alert.path:
# Compare the Purl
if alert.getPurl(version=False) == pending_alert.purl:
# check if the security_advisory ghsa_id matches the alert vulnerabilitity advisory_ghsa_id
for vuln in alert.alerts:
if vuln.advisory.ghsa_id == pending_alert.advisory.ghsa_id:
alerts.append(pending_alert)
break
except Exception as err:
Octokit.warning(f"Unable to get Dependabot alerts :: {err}")

else:
# Alerts
Expand All @@ -212,7 +251,6 @@ def checkDependabot(self):
dependencies = depgraph.getDependencies()

Octokit.info("Total Dependabot Alerts :: " + str(len(alerts)))

for alert in alerts:
if alert.get("dismissReason") is not None:
Octokit.debug(
Expand Down Expand Up @@ -312,12 +350,20 @@ def checkDependencyLicensing(self):
return 0

# TODO: Check if enabled

if GitHub.repository.isInPullRequest():
if self.base_ref and self.head_ref:
Octokit.info("Dependencies from Base Ref")
dependencies = depgraph.getDependenciesInPR(self.base_ref, self.head_ref)
elif GitHub.repository.isInPullRequest():
Octokit.info("Dependencies from Pull Request")
pr_info = GitHub.repository.getPullRequestInfo()
pr_base = pr_info.get("base", {}).get("ref", "")
pr_head = pr_info.get("head", {}).get("ref", "")
if self.base_ref:
pr_base = self.base_ref
else:
pr_base = pr_info.get("base", {}).get("ref", "")
if self.head_ref:
pr_head = self.head_ref
else:
pr_head = pr_info.get("head", {}).get("ref", "")
dependencies = depgraph.getDependenciesInPR(pr_base, pr_head)
else:
dependencies = depgraph.getDependencies()
Expand Down Expand Up @@ -392,7 +438,7 @@ def checkDependencyLicensing(self):
continue

licensing_violations.append(
[violation.fullname, violation.license if warning.license else "None"]
[violation.fullname, violation.license if violation.license else "None"]
)
if self.display:
Octokit.error(
Expand Down Expand Up @@ -456,12 +502,20 @@ def checkDependencies(self):
return 0

# TODO: Check if DependencyGraph is enabled in GitHub

if GitHub.repository.isInPullRequest():
if self.base_ref and self.head_ref:
Octokit.info("Dependencies from Base Ref")
dependencies = depgraph.getDependenciesInPR(self.base_ref, self.head_ref)
elif GitHub.repository.isInPullRequest():
Octokit.info("Dependencies from Pull Request")
pr_info = GitHub.repository.getPullRequestInfo()
pr_base = pr_info.get("base", {}).get("ref", "")
pr_head = pr_info.get("head", {}).get("ref", "")
if self.base_ref:
pr_base = self.base_ref
else:
pr_base = pr_info.get("base", {}).get("ref", "")
if self.head_ref:
pr_head = self.head_ref
else:
pr_head = pr_info.get("head", {}).get("ref", "")
dependencies = depgraph.getDependenciesInPR(pr_base, pr_head)

else:
Expand All @@ -480,12 +534,13 @@ def checkDependencies(self):
names.append(dependency.getPurl())

#  none is set to just check if the name or pattern is discovered
if self.policy.checkViolation("none", "dependencies", names=names, ids=ids):
dependency_violations.append([dependency.fullname])
if self.display:
Octokit.error(
"Dependency Graph Alert :: {}".format(dependency.fullname)
)
for alert in dependency.alerts:
if self.policy.checkViolation(alert.severity, "dependencies", names=names, ids=ids):
dependency_violations.append([dependency.fullname])
if self.display:
Octokit.error(
"Dependency Graph Alert :: {}".format(dependency.fullname)
)

violation_count = len(dependency_violations)
Octokit.info(f"Dependency Graph violations :: {violation_count}")
Expand Down
2 changes: 1 addition & 1 deletion vendor/ghastoolkit/supplychain/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def getPurl(self, version: bool = True) -> str:
if self.manager:
result += f"{self.manager.lower()}/"
if self.namespace:
result += f"{self.namespace}/"
result += f"{self.namespace}:"
result += f"{self.name}"
if version and self.version:
result += f"@{self.version}"
Expand Down
Loading