actions_graph/
├── __init__.py # Package version
├── cli.py # Typer CLI app (tree, export, diff, audit commands)
├── models.py # Data models: ActionRef, ActionNode, RiskLevel
├── parser.py # YAML workflow parser — extracts `uses:` references
├── resolver.py # Recursive GitHub API resolution of composite actions
├── graph.py # NetworkX DAG builder from resolved nodes
├── render.py # Rich tree rendering for terminal output
├── export.py # Mermaid, DOT (pydot), JSON export
├── risk.py # Risk assessment logic (mutable tags, unverified, depth)
├── diff.py # Diff mode: compare two workflow files
├── cache.py # SQLite cache with TTL for API responses
└── github.py # GitHub API client (httpx) for fetching action.yml
Data classes for ActionRef (owner/repo@ref), ActionNode (resolved action with metadata), RiskLevel enum. These are used by everything else.
Parse workflow YAML files to extract all uses: references as ActionRef objects.
Handle job-level and step-level uses. Skip local actions (./path).
httpx-based client to fetch action.yml/action.yaml from a GitHub repo at a given ref. Needs GITHUB_TOKEN support for auth.
SQLite-based cache keyed on owner/repo@ref. Stores raw action.yml content. Configurable TTL (default 24h). Used by resolver to avoid redundant API calls.
Given a list of ActionRef, recursively resolve composite actions:
- Fetch action.yml via GitHub client (with cache)
- If action is composite, parse its steps for more
uses:refs - Build parent→child relationships
- Stop at non-composite actions or max depth
Take resolver output and build a NetworkX DiGraph. Nodes = ActionRef strings, edges = dependency relationships. Root nodes = workflow file actions.
Score each node: mutable tag (not a SHA), high depth (>3), unverified creator (not in a known-good list). Produce RiskLevel per node.
Render the graph as a Rich Tree for terminal display. Color-code by risk level. Support --depth flag to limit display depth.
- Mermaid: generate flowchart string from graph
- DOT: use pydot to create DOT format
- JSON: serialize graph as adjacency list with metadata
Parse two workflow files, build both dependency sets, compute added/removed actions. Display as colored terminal output.
Wire everything together with Typer:
actions-graph tree [FILES...] [--depth N]actions-graph export [FILES...] --format mermaid|dot|jsonactions-graph diff FILE1 FILE2actions-graph audit [FILES...]
Unit tests for each module. Integration tests for CLI commands. Use fixtures with sample workflow YAML files.
- SQLite cache — simple, zero-config, portable
- No async — httpx sync client is sufficient for CLI tool
- NetworkX DiGraph — mature, well-tested graph library
- Typer — modern CLI framework with good type hint support
- Mock GitHub API in tests — no real network calls in test suite
- ActionRef as frozen dataclass — hashable, usable as dict keys and set members