Skip to content

Commit bcb8e6f

Browse files
committed
Allow vuln scans on arbitrary N|Solid branches by probing available dependencies
1 parent ba643e2 commit bcb8e6f

2 files changed

Lines changed: 54 additions & 10 deletions

File tree

.github/workflows/check-vulns.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
nsolidStream:
77
type: string
88
default: 'main'
9+
description: 'N|Solid branch or ref to scan'
910
secrets:
1011
NVD_API_KEY:
1112
required: true
@@ -14,6 +15,7 @@ on:
1415
nsolidStream:
1516
type: string
1617
default: 'main'
18+
description: 'N|Solid branch or ref to scan'
1719

1820

1921
permissions:

dep_checker/main.py

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,53 @@ def default(self, obj):
103103
)
104104

105105

106+
def resolve_dependencies(
107+
repo_path: Path, repo_branch: str
108+
) -> dict[str, Dependency]:
109+
"""Return the dependencies that can be parsed from the checked-out repo.
110+
111+
Known branches still use their curated dependency list. Unknown branches fall
112+
back to probing every tracked dependency definition and keeping only the ones
113+
whose version parser succeeds against the checkout.
114+
"""
115+
116+
configured_names = dependencies_per_branch.get(repo_branch)
117+
if configured_names is None:
118+
candidate_dependencies = dependencies_info
119+
print(
120+
f"Info: '{repo_branch}' is not explicitly configured; scanning all known dependency definitions"
121+
)
122+
else:
123+
candidate_dependencies = {
124+
name: dep
125+
for name, dep in dependencies_info.items()
126+
if name in configured_names
127+
}
128+
129+
available_dependencies: dict[str, Dependency] = {}
130+
skipped_dependencies: list[str] = []
131+
132+
for name, dep in candidate_dependencies.items():
133+
try:
134+
dep.version_parser(repo_path)
135+
except (FileNotFoundError, RuntimeError, ValueError) as exc:
136+
skipped_dependencies.append(f"{name}: {exc}")
137+
continue
138+
available_dependencies[name] = dep
139+
140+
if not available_dependencies:
141+
raise RuntimeError(
142+
f"No supported dependencies could be resolved from '{repo_branch}'"
143+
)
144+
145+
if skipped_dependencies:
146+
print(
147+
f"Info: Skipping {len(skipped_dependencies)} dependencies that are not present or not parseable in '{repo_branch}'"
148+
)
149+
150+
return available_dependencies
151+
152+
106153
def query_ghad(
107154
dependencies: dict[str, Dependency], gh_token: str, repo_path: Path
108155
) -> list[Vulnerability]:
@@ -237,7 +284,10 @@ def main() -> int:
237284
parser.add_argument(
238285
"node_repo_branch",
239286
metavar="NODE_REPO_BRANCH",
240-
help=f"the current branch of the Node repository (supports {supported_branches})",
287+
help=(
288+
"the current branch of the Node/N|Solid repository; known branches use "
289+
f"curated dependency lists, other branches are scanned by probing available dependencies ({supported_branches})"
290+
),
241291
)
242292
parser.add_argument(
243293
"--gh-token",
@@ -281,10 +331,6 @@ def main() -> int:
281331
raise RuntimeError(
282332
"Invalid argument: '{repo_path}' is not a valid Node git repository"
283333
)
284-
if repo_branch not in dependencies_per_branch:
285-
raise RuntimeError(
286-
f"Invalid argument: '{repo_branch}' is not a supported branch. Please use one of: {supported_branches}"
287-
)
288334
if gh_token is None:
289335
print(
290336
"Warning: GitHub authentication token not provided, skipping GitHub Advisory Database queries",
@@ -296,11 +342,7 @@ def main() -> int:
296342
file=sys.stderr,
297343
)
298344

299-
dependencies = {
300-
name: dep
301-
for name, dep in dependencies_info.items()
302-
if name in dependencies_per_branch[repo_branch]
303-
}
345+
dependencies = resolve_dependencies(repo_path, repo_branch)
304346

305347
# Track whether every vulnerability source completed successfully. A partial scan must not
306348
# cause the reconciler to close issues for vulns that simply weren't queried this run.

0 commit comments

Comments
 (0)