Skip to content

Commit ba5d778

Browse files
Merge remote-tracking branch 'origin/main' into link-gh-action-with-webview
# Conflicts: # .codeboarding/analysis.json # .codeboarding/health/health_report.json
2 parents d1a2dcc + 0e47270 commit ba5d778

3 files changed

Lines changed: 233 additions & 23 deletions

File tree

.codeboarding/analysis.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"metadata": {
3-
"generated_at": "2026-06-11T15:51:00.405452+00:00",
4-
"commit_hash": "7e07060289fb7516657e6c428fdec5e631fbfd72",
3+
"generated_at": "2026-06-11T16:36:04.958976+00:00",
4+
"commit_hash": "e9aa6435ce9f0ffe6726d5c1a3758980f79f1c3b",
55
"repo_name": "CodeBoarding-action",
66
"depth_level": 1,
77
"file_coverage_summary": {
@@ -14,7 +14,7 @@
1414
}
1515
}
1616
},
17-
"description": "The CodeBoarding-action pipeline automates structural code analysis and visualization by orchestrating engine execution across Git branches, generating visual diffs of code changes, and integrating these insights into GitHub PRs via IDE-specific deep links.",
17+
"description": "The CodeBoarding system orchestrates the analysis of git repositories, performs structural diffing between analysis states, and generates actionable visual feedback for pull requests by integrating with developer environments.",
1818
"files": {
1919
"scripts/cb_engine.py": {
2020
"method_keys": [
@@ -377,8 +377,8 @@
377377
},
378378
"components": [
379379
{
380-
"name": "Analysis Orchestrator",
381-
"description": "Coordinates the execution flow of the CodeBoarding engine, managing the lifecycle of base, head, and health analysis runs. The unclustered connections reveal a complex internal state machine (scripts.cb_engine.run_base, scripts.cb_engine.run_head, scripts.cb_engine.run_health, scripts.cb_engine.validate_base_analysis) that defines the core pipeline logic of the GitHub Action.",
380+
"name": "Engine Orchestrator",
381+
"description": "Manages the execution environment and lifecycle of the CodeBoarding analysis engine. It handles the checkout of different git references, executes the analysis, and validates the integrity of the generated data before downstream processing.",
382382
"key_entities": [
383383
{
384384
"qualified_name": "scripts.cb_engine.main",
@@ -429,8 +429,8 @@
429429
"can_expand": true
430430
},
431431
{
432-
"name": "Visual Diff Generator",
433-
"description": "Transforms raw analysis data and structural changes into visual representations, specifically Mermaid.js diagrams, highlighting architectural shifts. The new connections (scripts.diff_to_mermaid._diff_components, scripts.diff_to_mermaid._diff_relations, scripts.diff_to_mermaid._has_structural_changes) indicate a sophisticated logic for identifying architectural regressions or evolutions.",
432+
"name": "Visual Diff Engine",
433+
"description": "The core analytical component that compares two sets of analysis data. It identifies structural modifications (additions, removals, or changes in relationships), filters for relevance to reduce diagram noise, and renders the final architectural diff using Mermaid.js syntax.",
434434
"key_entities": [
435435
{
436436
"qualified_name": "scripts.diff_to_mermaid.main",
@@ -451,10 +451,10 @@
451451
"reference_end_line": 521
452452
},
453453
{
454-
"qualified_name": "scripts.diff_to_mermaid._diff_components",
454+
"qualified_name": "scripts.diff_to_mermaid._filter_changed",
455455
"reference_file": "scripts/diff_to_mermaid.py",
456-
"reference_start_line": 162,
457-
"reference_end_line": 207
456+
"reference_start_line": 312,
457+
"reference_end_line": 354
458458
}
459459
],
460460
"source_cluster_ids": [
@@ -503,8 +503,8 @@
503503
"can_expand": true
504504
},
505505
{
506-
"name": "UX & Integration Layer",
507-
"description": "Manages the interaction between the action and the GitHub environment, including the generation of PR comments, status updates, and user-facing links. The addition of scripts.build_cta.py introduces specific logic for generating 'Call to Action' links and webview integrations, expanding the layer's responsibility from simple reporting to interactive developer experience (DevEx) tooling.",
506+
"name": "Engagement & Feedback Manager",
507+
"description": "Enhances the PR comment with interactive elements. It detects the developer's environment and generates deep-links to local IDEs or the CodeBoarding dashboard, transforming a static diagram into an actionable entry point for code review.",
508508
"key_entities": [
509509
{
510510
"qualified_name": "scripts.build_cta.main",
@@ -545,18 +545,18 @@
545545
],
546546
"components_relations": [
547547
{
548-
"relation": "Provides analysis artifacts to",
549-
"src_name": "Analysis Orchestrator",
550-
"dst_name": "Visual Diff Generator",
548+
"relation": "Supplies validated JSON analysis files to",
549+
"src_name": "Engine Orchestrator",
550+
"dst_name": "Visual Diff Engine",
551551
"src_id": "1",
552552
"dst_id": "2",
553553
"edge_count": 0,
554554
"is_static": false
555555
},
556556
{
557-
"relation": "Passes rendered diagrams to",
558-
"src_name": "Visual Diff Generator",
559-
"dst_name": "UX & Integration Layer",
557+
"relation": "Provides structural context and identified changes to",
558+
"src_name": "Visual Diff Engine",
559+
"dst_name": "Engagement & Feedback Manager",
560560
"src_id": "2",
561561
"dst_id": "3",
562562
"edge_count": 0,

.codeboarding/health/health_report.json

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"repository_name": "CodeBoarding-action",
3-
"timestamp": "2026-06-11T15:50:45.582495+00:00",
4-
"overall_score": 0.9996183206106869,
3+
"timestamp": "2026-06-11T16:35:41.927521+00:00",
4+
"overall_score": 0.999609375,
55
"check_summaries": [
66
{
77
"check_name": "function_size",
88
"description": "Checks that functions/methods do not exceed line count thresholds",
99
"check_type": "standard",
10-
"total_entities_checked": 43,
10+
"total_entities_checked": 42,
1111
"findings_count": 0,
1212
"warning_count": 0,
1313
"score": 1.0,
@@ -17,7 +17,7 @@
1717
"check_name": "fan_out",
1818
"description": "Checks efferent coupling: how many other functions each function calls",
1919
"check_type": "standard",
20-
"total_entities_checked": 43,
20+
"total_entities_checked": 42,
2121
"findings_count": 0,
2222
"warning_count": 0,
2323
"score": 1.0,
@@ -27,7 +27,7 @@
2727
"check_name": "fan_in",
2828
"description": "Checks afferent coupling: how many other functions call each function",
2929
"check_type": "standard",
30-
"total_entities_checked": 43,
30+
"total_entities_checked": 42,
3131
"findings_count": 0,
3232
"warning_count": 0,
3333
"score": 1.0,
@@ -43,6 +43,24 @@
4343
"score": 1.0,
4444
"finding_groups": []
4545
},
46+
{
47+
"check_name": "circular_dependencies",
48+
"description": "Detects circular dependencies between packages",
49+
"check_type": "circular_dependencies",
50+
"cycles": [],
51+
"packages_checked": 1,
52+
"packages_in_cycles": 0
53+
},
54+
{
55+
"check_name": "package_instability",
56+
"description": "Computes Martin's instability metric (I = Ce / (Ca + Ce)) per package",
57+
"check_type": "standard",
58+
"total_entities_checked": 0,
59+
"findings_count": 0,
60+
"warning_count": 0,
61+
"score": 1.0,
62+
"finding_groups": []
63+
},
4664
{
4765
"check_name": "unused_code_diagnostics",
4866
"description": "Detects unused imports, variables, functions, and dead code via LSP diagnostics",
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# One-off / on-demand baseline refresh for THIS repo's own committed analysis.
2+
#
3+
# Why this exists: the webview "explore in browser" link compares a PR's head
4+
# against the analysis.json committed at the PR base (a commit on main). That base
5+
# is only meaningful if main's committed analysis.json is current. The PR review
6+
# workflow never writes to main, so without this, main's baseline goes stale and
7+
# every PR diffs against an outdated snapshot.
8+
#
9+
# Run it manually (Actions -> "Refresh CodeBoarding baseline" -> Run workflow) to
10+
# regenerate .codeboarding/analysis.json against main's current tree and commit it.
11+
# It generates a FRESH full analysis (LLM) for main's HEAD, so commit_hash matches
12+
# the commit it lands on. This is the manually-triggered form of the "baseline
13+
# keeper" described in docs/COMMIT_STRATEGY.md.
14+
15+
name: Refresh CodeBoarding baseline
16+
17+
on:
18+
workflow_dispatch:
19+
inputs:
20+
depth_level:
21+
description: 'Analysis depth (1-3). Match the review workflow for a comparable baseline.'
22+
required: false
23+
default: '1'
24+
25+
permissions:
26+
contents: write # commit the regenerated analysis.json to main
27+
28+
concurrency:
29+
group: codeboarding-refresh-baseline
30+
cancel-in-progress: false
31+
32+
jobs:
33+
refresh:
34+
runs-on: ubuntu-latest
35+
timeout-minutes: 60
36+
steps:
37+
# Root checkout: provides the action's own scripts (cb_engine.py) AND is where
38+
# the regenerated analysis.json is committed back. The engine and the analyzed
39+
# tree go into SEPARATE subdirectories so the engine never analyzes itself.
40+
- name: Checkout this repo (main)
41+
uses: actions/checkout@v4
42+
with:
43+
fetch-depth: 0
44+
45+
# Second checkout of this same repo as the analysis TARGET, isolated from the
46+
# action scripts + engine at the workspace root (mirrors the review action's
47+
# target-repo/ layout so the engine analyzes only the repo's own tree).
48+
- name: Checkout analysis target
49+
uses: actions/checkout@v4
50+
with:
51+
path: target-repo
52+
fetch-depth: 0
53+
54+
- name: Read engine ref from action.yml
55+
id: engine
56+
shell: bash
57+
run: |
58+
# Default the engine ref to the action.yml input default, so the baseline
59+
# is generated with the same engine the review workflow pins.
60+
REF="$(grep -A3 "engine_ref:" action.yml | grep "default:" | head -1 | sed -E "s/.*default: *'?([^'\"]+)'?.*/\1/")"
61+
echo "ref=${REF:-v0.12.0}" >> "$GITHUB_OUTPUT"
62+
echo "Engine ref: ${REF:-v0.12.0}"
63+
64+
- name: Checkout CodeBoarding engine
65+
uses: actions/checkout@v4
66+
with:
67+
repository: CodeBoarding/CodeBoarding
68+
ref: ${{ steps.engine.outputs.ref }}
69+
path: codeboarding-engine
70+
persist-credentials: false
71+
72+
- uses: actions/setup-python@v5
73+
with:
74+
python-version: '3.13'
75+
- uses: actions/setup-node@v4
76+
with:
77+
node-version: '20'
78+
- uses: astral-sh/setup-uv@v4
79+
with:
80+
enable-cache: true
81+
82+
- name: Cache uv venv (engine)
83+
uses: actions/cache@v4
84+
with:
85+
path: codeboarding-engine/.venv
86+
key: cb-uv-${{ runner.os }}-${{ hashFiles('codeboarding-engine/pyproject.toml', 'codeboarding-engine/uv.lock') }}
87+
88+
- name: Cache LSP servers
89+
uses: actions/cache@v4
90+
with:
91+
path: |
92+
codeboarding-engine/static_analyzer/servers/node_modules
93+
codeboarding-engine/static_analyzer/servers/bin
94+
key: cb-lsp-${{ runner.os }}-v1
95+
restore-keys: cb-lsp-${{ runner.os }}-
96+
97+
- name: Install Python dependencies
98+
working-directory: codeboarding-engine
99+
shell: bash
100+
run: |
101+
test -d .venv || uv venv
102+
uv pip install -e .
103+
104+
- name: Install LSP servers
105+
working-directory: codeboarding-engine
106+
shell: bash
107+
run: uv run python install.py --auto-install-npm
108+
109+
- name: Generate baseline analysis for main
110+
id: gen
111+
working-directory: codeboarding-engine
112+
shell: bash
113+
env:
114+
STATIC_ANALYSIS_CONFIG: ${{ github.workspace }}/codeboarding-engine/static_analysis_config.yml
115+
PROJECT_ROOT: ${{ github.workspace }}/codeboarding-engine
116+
DIAGRAM_DEPTH_LEVEL: ${{ inputs.depth_level }}
117+
CACHING_DOCUMENTATION: 'false'
118+
ENABLE_MONITORING: 'false'
119+
ACTION_PATH: ${{ github.workspace }}
120+
TARGET: ${{ github.workspace }}/target-repo
121+
OUT_DIR: ${{ runner.temp }}/cb-baseline
122+
REPO_NAME: ${{ github.event.repository.name }}
123+
DEPTH: ${{ inputs.depth_level }}
124+
MAIN_SHA: ${{ github.sha }}
125+
# Key + model pins live in SECRETS (not vars) in this repo, same as the
126+
# review workflow consumes them. Read raw here; normalize in the script.
127+
RAW_OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
128+
RAW_AGENT_MODEL: ${{ secrets.AGENT_MODEL }}
129+
RAW_PARSING_MODEL: ${{ secrets.PARSING_MODEL }}
130+
run: |
131+
# Normalize EXACTLY like the review action's key prep (action.yml). A raw
132+
# secret can carry surrounding whitespace/newlines, wrapping quotes, or a
133+
# leading "OPENROUTER_API_KEY=" prefix; any of those land in the
134+
# Authorization header and OpenRouter rejects it as "Missing Authentication
135+
# header" (a 401 that looks like a bad key but is a malformed header).
136+
# The previous fix stripped only whitespace, leaving quotes/prefix → still 401.
137+
_strip() { printf '%s' "$1" | tr -d '[:space:]' | sed -e 's/^"//;s/"$//' -e "s/^'//;s/'\$//"; }
138+
KEY="$(_strip "$RAW_OPENROUTER_API_KEY")"
139+
# Drop a leading "OPENROUTER_API_KEY=" if the secret was stored with it.
140+
case "$KEY" in OPENROUTER_API_KEY=*) KEY="${KEY#OPENROUTER_API_KEY=}";; esac
141+
KEY="$(_strip "$KEY")"
142+
[ -n "$KEY" ] || { echo "::error::OPENROUTER_API_KEY secret is not set."; exit 1; }
143+
echo "::add-mask::$KEY"
144+
export OPENROUTER_API_KEY="$KEY"
145+
AGENT_MODEL="$(_strip "$RAW_AGENT_MODEL")"
146+
PARSING_MODEL="$(_strip "$RAW_PARSING_MODEL")"
147+
export AGENT_MODEL="${AGENT_MODEL:-google/gemini-3-flash-preview}"
148+
export PARSING_MODEL="${PARSING_MODEL:-google/gemini-3.1-flash-lite-preview}"
149+
echo "Provider: openrouter; key length: ${#OPENROUTER_API_KEY}"
150+
# Preflight the key against OpenRouter so a malformed/expired key fails here
151+
# with a clear message instead of deep inside the engine's retry loop.
152+
PRE=$(curl -sS -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $OPENROUTER_API_KEY" \
153+
--max-time 10 https://openrouter.ai/api/v1/auth/key || echo "curl-fail")
154+
echo "OpenRouter /auth/key preflight: HTTP $PRE"
155+
[ "$PRE" = "200" ] || { echo "::error::OpenRouter rejected the key (HTTP $PRE). Check the OPENROUTER_API_KEY secret value (no quotes/prefix/newline)."; exit 1; }
156+
mkdir -p "$OUT_DIR"
157+
# Run the same full-analysis path the review action uses for a base.
158+
uv run python "$ACTION_PATH/scripts/cb_engine.py" base \
159+
--repo "$TARGET" \
160+
--out "$OUT_DIR" \
161+
--name "$REPO_NAME" \
162+
--run-id "${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-baseline" \
163+
--depth "$DEPTH" \
164+
--source-sha "$MAIN_SHA"
165+
[ -f "$OUT_DIR/analysis.json" ] || { echo "::error::Baseline analysis ran but analysis.json is missing."; exit 1; }
166+
# Optional health report, if the engine produced one.
167+
uv run python "$ACTION_PATH/scripts/cb_engine.py" health \
168+
--artifact-dir "$OUT_DIR" \
169+
--repo "$TARGET" \
170+
--name "$REPO_NAME" \
171+
--issues-out "${RUNNER_TEMP}/cb-issues.txt" || true
172+
173+
- name: Commit baseline to main
174+
shell: bash
175+
env:
176+
OUT_DIR: ${{ runner.temp }}/cb-baseline
177+
run: |
178+
mkdir -p .codeboarding/health
179+
cp "$OUT_DIR/analysis.json" .codeboarding/analysis.json
180+
if [ -f "$OUT_DIR/health/health_report.json" ]; then
181+
cp "$OUT_DIR/health/health_report.json" .codeboarding/health/health_report.json
182+
fi
183+
git add .codeboarding/analysis.json .codeboarding/health/health_report.json 2>/dev/null || git add .codeboarding/analysis.json
184+
if git diff --cached --quiet; then
185+
echo "::notice::Baseline already current; nothing to commit."
186+
exit 0
187+
fi
188+
git config user.name "codeboarding[bot]"
189+
git config user.email "codeboarding[bot]@users.noreply.github.com"
190+
git commit -m "chore(codeboarding): refresh architecture baseline [skip ci]"
191+
git push
192+
echo "Committed refreshed baseline to ${GITHUB_REF_NAME} ($(git rev-parse --short HEAD))."

0 commit comments

Comments
 (0)