|
1 | 1 | <div align="center"> |
2 | 2 | <img src="assets/icon.svg" alt="CodeBoarding Logo" height="150" /> |
3 | | - |
4 | | - # CodeBoarding [Diagram-First Documentation] |
5 | | - |
6 | | - [](https://github.com/marketplace/actions/codeboarding-diagram-first-documentation) |
| 3 | + |
| 4 | + # CodeBoarding Architecture Diff (Mermaid) |
| 5 | + |
| 6 | + Posts a PR comment with a **Mermaid** architecture diagram showing which components changed — **green** added, **yellow** modified, **red** deleted — for both nodes and arrows. |
7 | 7 | </div> |
8 | 8 |
|
9 | | -Generates diagram-first visualizations of your codebase using static analysis and large language models. |
| 9 | +## What it does |
| 10 | + |
| 11 | +On every pull request, this action: |
| 12 | + |
| 13 | +1. Resolves a **base ("before") analysis**: it reads the `.codeboarding/analysis.json` committed at the PR base commit if one exists; otherwise it runs a full CodeBoarding analysis on the base commit to produce one. |
| 14 | +2. Runs an **incremental analysis on the PR head**, seeded from the base analysis — only LLM-calling the components whose code actually changed, so a typical PR costs a handful of LLM calls. |
| 15 | +3. **Diffs the two analyses** and renders the architecture graph as a Mermaid block with changed components and relations colored: |
| 16 | + - **green** — added |
| 17 | + - **yellow** — modified |
| 18 | + - **red** (dashed) — deleted |
| 19 | +4. Posts a sticky PR comment containing the Mermaid block. **GitHub renders the diagram inline** — no image, no Playwright, no extra branch. |
10 | 20 |
|
11 | 21 | ## Usage |
12 | 22 |
|
13 | 23 | ```yaml |
14 | | -name: Generate Documentation |
| 24 | +name: Architecture diff |
15 | 25 | on: |
16 | | - push: |
17 | | - branches: [ main ] |
18 | 26 | pull_request: |
19 | | - branches: [ main ] |
20 | | - types: [opened, synchronize, reopened] |
| 27 | + types: [opened, synchronize, reopened, ready_for_review] |
| 28 | + |
| 29 | +permissions: |
| 30 | + pull-requests: write # the only permission needed — nothing is pushed |
21 | 31 |
|
22 | 32 | jobs: |
23 | | - documentation: |
| 33 | + diagram: |
24 | 34 | runs-on: ubuntu-latest |
| 35 | + if: github.event.pull_request.draft == false |
| 36 | + timeout-minutes: 60 |
25 | 37 | steps: |
26 | | - - name: Checkout |
27 | | - uses: actions/checkout@v4 |
28 | | - with: |
29 | | - fetch-depth: 0 # Required to access branch history |
30 | | - |
31 | | - - name: Generate Documentation |
32 | | - uses: codeboarding/codeboarding-ghaction@v1 |
| 38 | + - uses: codeboarding/codeboarding-action@v1 |
33 | 39 | with: |
34 | | - repository_url: ${{ github.server_url }}/${{ github.repository }} |
35 | | - source_branch: ${{ github.head_ref || github.ref_name }} |
36 | | - target_branch: ${{ github.base_ref || 'main' }} |
37 | | - output_directory: 'docs' |
38 | | - output_format: '.md' |
39 | | - |
40 | | - - name: Upload Documentation |
41 | | - uses: actions/upload-artifact@v4 |
42 | | - with: |
43 | | - name: documentation |
44 | | - path: | |
45 | | - docs/ |
46 | | - .codeboarding/ |
| 40 | + llm_api_key: ${{ secrets.OPENROUTER_API_KEY }} |
47 | 41 | ``` |
48 | 42 |
|
| 43 | +You need **one secret**: an LLM API key. OpenRouter is the default; pass your own model via the `agent_model` / `parsing_model` inputs if you prefer. |
| 44 | + |
49 | 45 | ## Inputs |
50 | 46 |
|
51 | | -| Input | Description | Required | Default | |
52 | | -|-------|-------------|----------|---------| |
53 | | -| `repository_url` | Repository URL for which documentation will be generated | Yes | - | |
54 | | -| `source_branch` | Source branch for comparison (typically the PR branch) | Yes | - | |
55 | | -| `target_branch` | Target branch for comparison (typically the base branch) | Yes | - | |
56 | | -| `output_directory` | Directory where documentation files will be saved | No | `docs` | |
57 | | -| `output_format` | Format for documentation files (either `.md` or `.rst`) | No | `.md` | |
| 47 | +| Input | Default | Description | |
| 48 | +|---|---|---| |
| 49 | +| `llm_api_key` | (required) | LLM API key. Currently OpenRouter (`OPENROUTER_API_KEY`). | |
| 50 | +| `github_token` | `${{ github.token }}` | Token used to post the comment. | |
| 51 | +| `engine_ref` | `main` | Git ref of `CodeBoarding/CodeBoarding`. Pin in production. | |
| 52 | +| `depth_level` | `1` | Diagram depth (1–3). Higher = slower + more detail. | |
| 53 | +| `agent_model` | `openrouter/anthropic/claude-sonnet-4` | LLM for analysis. | |
| 54 | +| `parsing_model` | `openrouter/anthropic/claude-sonnet-4` | LLM for parsing. | |
| 55 | +| `comment_header` | `Architecture review` | Header line of the PR comment. | |
| 56 | +| `diagram_direction` | `LR` | Mermaid layout direction: `LR`, `TD`, `TB`, `RL`, or `BT`. | |
| 57 | +| `changed_only` | `false` | Draw only changed components and their incident edges. | |
| 58 | +| `nested` | `false` | Draw depth>1 sub-components as nested subgraphs (pair with `depth_level >= 2`). | |
58 | 59 |
|
59 | 60 | ## Outputs |
60 | 61 |
|
61 | 62 | | Output | Description | |
62 | | -|--------|-------------| |
63 | | -| `markdown_files_created` | Number of documentation files created | |
64 | | -| `json_files_created` | Number of JSON files created | |
65 | | -| `output_directory` | Directory where documentation files were saved | |
66 | | -| `json_directory` | Directory where JSON files were saved (always `.codeboarding`) | |
67 | | -| `has_changes` | Whether any files were created or changed | |
| 63 | +|---|---| |
| 64 | +| `diagram_md` | Path to the rendered ```` ```mermaid ```` block in the runner workspace. | |
| 65 | +| `n_changed` | Number of top-level components added/modified/deleted. | |
| 66 | +| `truncated` | `true` if the diagram was reduced to changed-only to fit GitHub's Mermaid limit. | |
| 67 | + |
| 68 | +## How the diff is colored |
| 69 | + |
| 70 | +Nodes are styled with Mermaid `classDef` / `class`; arrows are styled with positional `linkStyle`. A relation counts as **modified** when its endpoints are unchanged but its label text changed. Example of the emitted block: |
| 71 | + |
| 72 | +```mermaid |
| 73 | +graph LR |
| 74 | + Api["API Gateway"] |
| 75 | + Auth["Auth Service"] |
| 76 | + Cache["Cache"] |
| 77 | + Api -- "routes to" --> Auth |
| 78 | + Auth -- "reads/writes" --> Cache |
| 79 | + classDef added fill:#1f883d,stroke:#0b5d23,color:#ffffff; |
| 80 | + classDef modified fill:#bf8700,stroke:#7d4e00,color:#ffffff; |
| 81 | + classDef deleted fill:#cf222e,stroke:#82071e,color:#ffffff,stroke-dasharray:5 3; |
| 82 | + class Cache added; |
| 83 | + class Auth modified; |
| 84 | + class Api deleted; |
| 85 | + linkStyle 0 stroke:#cf222e,stroke-width:2px,stroke-dasharray:5 3; |
| 86 | + linkStyle 1 stroke:#1f883d,stroke-width:2px; |
| 87 | +``` |
68 | 88 |
|
69 | | -## How It Works |
| 89 | +## No baseline required |
70 | 90 |
|
71 | | -The action works by: |
| 91 | +If `.codeboarding/analysis.json` isn't committed at the PR base commit, the action **generates the baseline itself** by running a full analysis on the base commit, then diffs the head against it. Committing a baseline on your default branch makes runs cheaper (the base run is skipped) and the diff more stable, but it is not required. |
72 | 92 |
|
73 | | -1. Analyzing the differences introduced in the source branch and putting the results in the target branch |
74 | | -2. Generating documentation files based on the latest version of the source branch |
75 | | -3. Outputting two types of files: |
76 | | - - Documentation files (Markdown or RST) in the specified output directory |
77 | | - - Metadata files in the `.codeboarding` directory |
| 93 | +## Fork PRs |
78 | 94 |
|
79 | | -## License |
| 95 | +Because nothing is pushed (the diagram is inline Mermaid), there is no image step to skip on forks. The one caveat is GitHub's own policy: **secrets are withheld from `pull_request`-triggered runs on forks**, so the LLM key is unavailable and the run fails early with a clear message. A maintainer can re-run from the Actions tab, or use `pull_request_target` if you understand its security implications. |
80 | 96 |
|
81 | | -MIT License - see [LICENSE](LICENSE) file for details. |
| 97 | +## Limitations |
82 | 98 |
|
83 | | -# CodeBoarding GitHub Action |
| 99 | +- **GitHub Mermaid caps.** Inline Mermaid in comments is capped (≈500 edges / 50 000 chars). The action stays under this by auto-falling-back to a changed-only graph; if even that overflows it posts a text summary instead of a broken diagram. |
| 100 | +- **Nesting.** By default only the top-level component graph is drawn (matching the engine's default `graph LR`). Set `nested: true` with `depth_level >= 2` to draw sub-components as nested subgraphs — leaf nodes filled, parent containers outlined, both colored by status. Large nested graphs are more likely to hit GitHub's Mermaid caps (above), in which case the action degrades to changed-only or a text summary. |
| 101 | +- **Renames show as remove + add.** Components are matched across the two analyses by name (the stable join), so a renamed component appears as a red removal plus a green addition rather than a single yellow change. |
| 102 | +- **No click-through.** GitHub renders Mermaid in strict security mode, so node hyperlinks are disabled. |
84 | 103 |
|
85 | | -## Important: Timeout Configuration |
| 104 | +## Local testing |
86 | 105 |
|
87 | | -For large repositories, the analysis can take 15-45 minutes. Make sure to configure appropriate timeouts in your workflow: |
| 106 | +A GitHub run is slow (engine install + two analyses). To iterate locally, use `scripts/run_local.sh`. It mirrors `action.yml` and writes `.cb-local/diagram.md` plus a `.cb-local/preview.html` you open in a browser (rendered with mermaid.js in GitHub's strict mode, so it looks like the comment will). |
88 | 107 |
|
89 | | -```yaml |
90 | | -jobs: |
91 | | - generate-docs: |
92 | | - runs-on: ubuntu-latest |
93 | | - timeout-minutes: 60 # Set to 60+ minutes for large repositories |
94 | | - steps: |
95 | | - - uses: actions/checkout@v4 |
96 | | - - uses: your-username/codeboarding-ghaction@v1 |
97 | | - with: |
98 | | - # your inputs here |
| 108 | +**Fast — no LLM, instant.** Diff two existing `analysis.json` files. Great for iterating on colors/layout. For a realistic pair, pull two revisions of a committed analysis: |
| 109 | + |
| 110 | +```bash |
| 111 | +git show <old-sha>:.codeboarding/analysis.json > /tmp/base.json |
| 112 | +git show <new-sha>:.codeboarding/analysis.json > /tmp/head.json |
| 113 | +scripts/run_local.sh --base-json /tmp/base.json --head-json /tmp/head.json |
99 | 114 | ``` |
100 | 115 |
|
101 | | -## Timeout Guidelines |
| 116 | +**Full pipeline — needs an LLM key.** Runs the engine on two refs of a local repo exactly like the action (committed-or-generated base, then incremental head): |
| 117 | + |
| 118 | +```bash |
| 119 | +export OPENROUTER_API_KEY=sk-or-... |
| 120 | +scripts/run_local.sh --repo /path/to/repo --base <base-ref> --head <head-ref> \ |
| 121 | + --engine /path/to/CodeBoarding # defaults to ../CodeBoarding |
| 122 | +``` |
102 | 123 |
|
103 | | -- **Small repositories** (<1k files): 10-15 minutes |
104 | | -- **Medium repositories** (1k-5k files): 20-30 minutes |
105 | | -- **Large repositories** (5k+ files): 30-60 minutes |
106 | | -- **Very large repositories** (10k+ files): 45-90 minutes |
| 124 | +Flags: `--depth N`, `--direction LR|TD|…`, `--nested`, `--changed-only`, `--no-edge-labels`, `--out DIR`, `--no-open`. |
| 125 | + |
| 126 | +The diagram step alone is also directly runnable: |
| 127 | + |
| 128 | +```bash |
| 129 | +python3 scripts/diff_to_mermaid.py --base base/analysis.json --head head/analysis.json --out diagram.md |
| 130 | +``` |
| 131 | + |
| 132 | +## License |
107 | 133 |
|
108 | | -If your workflow consistently times out, consider: |
109 | | -1. Increasing `timeout-minutes` to 90 or higher |
110 | | -2. Running the action on a schedule during off-peak hours |
111 | | -3. Analyzing specific branches with smaller diffs |
| 134 | +MIT — see [LICENSE](LICENSE). |
0 commit comments