Skip to content
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
73 changes: 0 additions & 73 deletions .github/workflows/remove-adept-to-close-on-issue-close.yml

This file was deleted.

6 changes: 1 addition & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ target-version = ['py314']
force-exclude = '''test'''

[tool.coverage.run]
omit = [
"tests/*",
"src/security/derive_team_security_metrics.py",
"src/security/extract_team_security_stats.py",
]
omit = ["tests/*"]

[tool.mypy]
check_untyped_defs = true
Expand Down
7 changes: 2 additions & 5 deletions src/core/github/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,26 @@

import logging
import subprocess
from collections.abc import Mapping


def run_cmd(
cmd: list[str],
*,
capture_output: bool = True,
env: Mapping[str, str] | None = None,
) -> subprocess.CompletedProcess:
"""Run *cmd* as a subprocess and return the completed process."""
return subprocess.run(cmd, check=False, capture_output=capture_output, text=True, env=env)
return subprocess.run(cmd, check=False, capture_output=capture_output, text=True)


def run_gh(
args: list[str],
*,
capture_output: bool = True,
env: Mapping[str, str] | None = None,
) -> subprocess.CompletedProcess:
"""Run a ``gh`` CLI command and return the completed process."""
cmd = ["gh"] + args
try:
return run_cmd(cmd, capture_output=capture_output, env=env)
return run_cmd(cmd, capture_output=capture_output)
except FileNotFoundError as exc:
logging.error("gh CLI not found. Install and authenticate gh.")
raise SystemExit(1) from exc
15 changes: 15 additions & 0 deletions src/core/github/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,21 @@ def gh_issue_add_labels(repo: str, number: int, labels: list[str]) -> None:
logging.warning("Failed to add labels to #%d%s: %s", number, _not_found_hint(res), res.stderr)


def gh_issue_remove_labels(repo: str, number: int, labels: list[str]) -> None:
"""Remove *labels* from issue *number* (idempotent)."""
if not labels:
return

args: list[str] = ["issue", "edit", str(number), "--repo", repo]

for label in labels:
args += ["--remove-label", label]

res = run_gh(args)
if res.returncode != 0:
logging.warning("Failed to remove labels from #%d%s: %s", number, _not_found_hint(res), res.stderr)


def gh_issue_comment(repo: str, number: int, body: str) -> bool:
"""Post a comment with *body* on issue *number*.

Expand Down
16 changes: 2 additions & 14 deletions src/core/github/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

import json
import logging
import os
from collections.abc import Mapping
from dataclasses import dataclass
from typing import Any

Expand Down Expand Up @@ -52,21 +50,11 @@ class ProjectPriorityField:


def _run_graphql(query: str, variables: dict[str, Any] | None = None) -> dict[str, Any] | None:
"""Execute a GraphQL query via ``gh api graphql`` and return parsed JSON.

When ``GH_PROJECT_ONLY_TOKEN`` is set in the environment the GraphQL call is made
with that token instead of the default ``GH_TOKEN``. This allows cross-org
project access while the rest of the pipeline continues to use the scoped
``github.token``.
"""
"""Execute a GraphQL query via ``gh api graphql`` and return parsed JSON."""
args = ["api", "graphql", "-f", f"query={query}"]
for k, v in (variables or {}).items():
args += ["-F", f"{k}={v}"]
env: Mapping[str, str] | None = None
project_token = os.environ.get("GH_PROJECT_ONLY_TOKEN", "")
if project_token:
env = {**os.environ, "GH_TOKEN": project_token}
res = run_gh(args, env=env)
res = run_gh(args)
if res.returncode != 0:
logging.warning(f"GraphQL call failed: {res.stderr}")
return None
Expand Down
2 changes: 2 additions & 0 deletions src/security/alerts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AlertMetadata:
alert_url: str = ""
rule_id: str = ""
rule_name: str = ""
rule_description: str = ""
severity: str = ""
confidence: str = ""
tags: list[str] = field(default_factory=list)
Expand All @@ -51,6 +52,7 @@ class AlertMetadata:
def __post_init__(self) -> None:
self.rule_id = (self.rule_id or "").strip()
self.rule_name = (self.rule_name or "").strip()
self.rule_description = (self.rule_description or "").strip()
self.severity = (self.severity or "").strip() or "unknown"
self.state = (self.state or "").lower().strip()
self.tool = (self.tool or "").strip()
Expand Down
1 change: 1 addition & 0 deletions src/security/collect_alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def _normalise_alert(alert: dict) -> dict:
"alert_url": alert.get("html_url"),
"rule_id": rule.get("id"),
"rule_name": rule.get("name"),
"rule_description": rule.get("description"),
"severity": rule.get("security_severity_level"),
"confidence": rule.get("severity"),
"tags": rule.get("tags") or [],
Expand Down
3 changes: 0 additions & 3 deletions src/security/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
LABEL_EPIC = "epic"
LABEL_SEC_ADEPT_TO_CLOSE = "sec:adept-to-close"

SEC_EVENT_OPEN = "open"
SEC_EVENT_REOPEN = "reopen"

SECMETA_TYPE_PARENT = "parent"
SECMETA_TYPE_CHILD = "child"

Expand Down
Loading