-
Notifications
You must be signed in to change notification settings - Fork 26
feat(deps): SBOM ingestion + a standalone coverage-measurement script… #402
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
exploreriii
merged 6 commits into
hiero-hackers:main
from
iron-prog:feat/dependency-network
Sep 26, 2026
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
848d2ca
feat(deps): SBOM ingestion + a standalone coverage-measurement script…
iron-prog 049f299
style(deps): shorten SBOM fetch comments
iron-prog 51fe1f9
fix: address PR review feedback
iron-prog ac144ef
fix: only 404 means SBOM disabled; validate SBOM schema before ok
iron-prog ed55e51
fix(deps): address SBOM review feedback
iron-prog 6a76efe
lint fixes
iron-prog File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| """Measure real SBOM coverage for an org — the gating question on #338. | ||
|
|
||
| Not a registered pipeline; this is throwaway measurement code to answer | ||
| "how many repos have a readable dependency-graph SBOM" before investing in | ||
| the resolution heuristic or the chart. Run directly: | ||
|
|
||
| uv run python measure_sbom_coverage.py | ||
|
|
||
| Requires GITHUB_TOKEN in the environment (same as any other pipeline run). | ||
| Prints a coverage breakdown and writes the raw per-repo results to | ||
| sbom_coverage_raw.csv for closer inspection. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import csv | ||
|
|
||
| from hiero_analytics.config.paths import ORG | ||
| from hiero_analytics.data_sources.github_client import GitHubClient | ||
| from hiero_analytics.data_sources.github_ingest import fetch_org_repos_graphql | ||
| from hiero_analytics.data_sources.github_rest import fetch_org_sbom_data | ||
|
|
||
|
|
||
| def main(org: str = ORG) -> None: | ||
| """Fetch SBOM coverage for every repo in ``org`` and print a summary.""" | ||
| client = GitHubClient() | ||
|
|
||
| repos = fetch_org_repos_graphql(client, org) | ||
| if not repos: | ||
| print(f"No repositories found for org: {org}") | ||
| return | ||
|
|
||
| repo_names = [r.name for r in repos] | ||
| print(f"Fetching SBOM data for {len(repo_names)} repos in {org}...") | ||
|
|
||
| coverage, packages = fetch_org_sbom_data(client, org, repo_names) | ||
|
|
||
| by_status: dict[str, list] = {} | ||
| for c in coverage: | ||
| by_status.setdefault(c.status, []).append(c) | ||
|
|
||
| print() | ||
| print("=== Coverage summary ===") | ||
| for status in ("ok", "disabled", "error"): | ||
| rows = by_status.get(status, []) | ||
| print(f"{status:>10}: {len(rows)} repos") | ||
|
|
||
| ok_rows = by_status.get("ok", []) | ||
| nonzero = [c for c in ok_rows if c.package_count > 0] | ||
| zero = [c for c in ok_rows if c.package_count == 0] | ||
| print() | ||
| print(f"Of the {len(ok_rows)} repos with a readable SBOM:") | ||
| print(f" {len(nonzero)} have at least one dependency ({sum(c.package_count for c in nonzero)} packages total)") | ||
| print(f" {len(zero)} have a readable but empty manifest") | ||
|
|
||
| print() | ||
| print(f"Total dependency edges (all ecosystems, unresolved to org repos yet): {len(packages)}") | ||
| ecosystems: dict[str, int] = {} | ||
| for p in packages: | ||
| ecosystems[p.ecosystem] = ecosystems.get(p.ecosystem, 0) + 1 | ||
| for eco, n in sorted(ecosystems.items(), key=lambda kv: -kv[1]): | ||
| print(f" {eco}: {n}") | ||
|
|
||
| with open("sbom_coverage_raw.csv", "w", newline="", encoding="utf-8") as f: | ||
| writer = csv.writer(f) | ||
| writer.writerow(["repo", "status", "package_count"]) | ||
| for c in sorted(coverage, key=lambda c: c.repo): | ||
| writer.writerow([c.repo, c.status, c.package_count]) | ||
|
|
||
| print() | ||
| print("Wrote per-repo detail to sbom_coverage_raw.csv") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.