Skip to content

Commit 4ba0a17

Browse files
committed
feat: add readme
Signed-off-by: 7h3-3mp7y-m4n <emailtorash@gmail.com>
1 parent 050a2eb commit 4ba0a17

1 file changed

Lines changed: 213 additions & 0 deletions

File tree

README.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# urunc CI Dashboard
2+
3+
A real-time dashboard for monitoring urunc CI test status.
4+
5+
**Live Dashboard**: https://urunc-dev.github.io/ci-dashboard/
6+
7+
## Features
8+
9+
### Dashboard UI
10+
11+
- **Dual-period stats** — separate stat cards for the last 24 hours and all-time totals (success rate, runs executed, passed, failed)
12+
- **Workflow table** — sortable by name, last run conclusion, success rate, avg duration, and weather history
13+
- **7-run weather history** — colored dots showing the last 7 run outcomes at a glance (oldest → newest)
14+
- **Filter chips** — instantly filter by: All, Failing, Passing, Critical, Recent Failure, Recent Run, No Runs
15+
- **Expandable drawer** — click any workflow row to reveal:
16+
- **Runs table** — all recent runs with conclusion, date, duration, attempt number, and direct GitHub link
17+
- **Structured log viewer** — failure signals grouped by category with keyword highlighting
18+
- **Per-workflow charts** — avg job duration, pass/fail per run, duration trend
19+
- **Overview charts panel** — activated via the Charts chip:
20+
- Overall passed vs failed
21+
- Avg duration per workflow
22+
- Execution time last 7 runs per workflow
23+
- Success rate by workflow
24+
- **Auto-refresh indicator** — Data updates every cronjob run
25+
----------
26+
27+
## Architecture
28+
29+
```
30+
┌──────────────────────────────────────────────────────────────────────────┐
31+
│ Config layer — config.yaml │
32+
│ ├── settings repo, run limits │
33+
│ ├── log_analysis noise_patterns, failure categories + priority │
34+
│ ├── notify enabled, target_repo, label │
35+
│ └── workflows name, description, critical flag │
36+
└──────────────────────┬───────────────────────────────────────────────────┘
37+
│ loads
38+
┌──────────────────────▼───────────────────────────────────────────────────┐
39+
│ Log analysis pipeline — main.go │
40+
│ │
41+
│ GH Actions client ──► Stage 1: noise gate ──► Stage 2: category match │
42+
│ (workflows_raw.json matchesAny() strips priority sort │
43+
│ runs_raw.json) noise_patterns → LogSummary │
44+
│ │ ▲ │ │
45+
│ │ failed runs │ raw log lines │ LogSnippet │
46+
│ ▼ │ ▼ │
47+
│ fetchJobsAndEnrich() ─────────┘ renderSummary() │
48+
│ │ │ │
49+
│ └──────────────► buildSummary() ◄────────────┘ │
50+
│ WeatherHistory, WorkflowSummary │
51+
│ │ writes │
52+
│ stats.json │
53+
└──────────────────────┬─────────┴────────────────────────────────────────┘
54+
│ WorkflowSummary (critical workflows only)
55+
┌──────────────────────▼───────────────────────────────────────────────────┐
56+
│ Notification engine — notify.go │
57+
│ │
58+
│ Notifier.Process() │
59+
│ critical=true + anyFailed()? │
60+
│ │ └──── no ──► Skip │
61+
│ ▼ │
62+
│ findOpenIssue() (paginated title match) │
63+
│ / \ │
64+
│ no issue exists + 24 h passed │
65+
│ │ │ │
66+
│ createIssue() addComment() │
67+
└──────────────────────────────────────────────────────────────────────────┘
68+
69+
stats.json
70+
71+
┌──────────────────────▼───────────────────────────────────────────────────┐
72+
│ Frontend — index.html + styles.css + script.js │
73+
│ reads stats.json → renders dashboard │
74+
│ Chart.js 2.9 — pie, doughnut, bar, line charts │
75+
└──────────────────────────────────────────────────────────────────────────┘
76+
77+
```
78+
79+
## Repository Layout
80+
81+
```
82+
.
83+
├── .github/
84+
│ └── workflows/
85+
│ └── update-stats.yml # Cronjob, commits stats.json
86+
├── main.go # Data fetching, log analysis, stats generation
87+
├── notify.go # GitHub issue/comment notification engine
88+
├── config.yaml # All configuration
89+
├── index.html # Dashboard markup
90+
├── styles.css # Dark/light theme, table, chart, log viewer styles
91+
├── script.js # Dashboard logic — filters, charts, drawer, log renderer
92+
└── stats.json # Auto-generated by cronjob
93+
```
94+
95+
----------
96+
97+
## Configuration
98+
99+
All configuration lives in `config.yaml`.
100+
101+
### Settings
102+
103+
```yaml
104+
settings:
105+
source_repo: "urunc-dev/urunc" # Repo to monitor
106+
max_runs_per_workflow: 40 # Runs to fetch per workflow
107+
recent_runs_in_output: 40 # Runs included in stats.json
108+
```
109+
### Notifications
110+
111+
```yaml
112+
notify:
113+
enabled: true
114+
target_repo: "your-org/your-repo" # Where issues are opened
115+
label: "ci-failure" # Label applied to opened issues
116+
```
117+
118+
### Log analysis
119+
120+
```yaml
121+
log_analysis:
122+
max_signals_per_job: 40
123+
124+
noise_patterns: # Lines matching these are dropped before analysis
125+
- "sudo process started"
126+
- "/usr/lib/gcc/"
127+
128+
categories: # Lower priority number = more important
129+
- name: "Crash / Timeout"
130+
priority: 1
131+
patterns: ["panic:", "test timed out", "deadlock"]
132+
133+
- name: "Network Failure"
134+
priority: 2
135+
patterns: ["connection reset by peer", "i/o timeout"]
136+
137+
- name: "Test Failure"
138+
priority: 3
139+
patterns: ["--- fail:", "expected", "received"]
140+
141+
- name: "Build Failure"
142+
priority: 4
143+
patterns: ["make: ***", "##[error]", "compilation terminated"]
144+
145+
- name: "Fatal Runtime Error"
146+
priority: 5
147+
patterns: ["level=fatal", "fatal: "]
148+
```
149+
150+
The frontend log viewer maps these category names to colored badges automatically (`Crash / Timeout` → red, `Network Failure` → blue, `Test Failure` → orange, `Build Failure` → purple, `Fatal Runtime Error` → red).
151+
152+
### Workflows
153+
154+
```yaml
155+
workflows:
156+
- name: "ci"
157+
description: "Main CI workflow"
158+
critical: true # critical=true workflows trigger issue notifications
159+
# and show a red "critical" badge in the dashboard
160+
- name: "scorecard"
161+
description: "Security scorecard"
162+
critical: false # monitored in dashboard, no issue opened on failure
163+
```
164+
----------
165+
166+
## How It Works
167+
168+
1. **Github cronjob** fetches `workflows_raw.json` and `runs_raw.json` from the GitHub API using `gh CLI`, then progress with go app.
169+
2. For each configured workflow, the Go pipeline:
170+
- Fetches job-level data for recent runs
171+
- For failed jobs, downloads and time-windows the raw log, strips noise, categorises signals by priority
172+
- Falls back to check-run annotations if the log has expired
173+
- Builds a `WorkflowSummary` with weather history, failure rate, avg duration, and log snippets
174+
3. Writes `stats.json` and commits it back to the repo
175+
4. For each `critical: true` workflow with a recent failure, the notifier opens or updates a GitHub issue
176+
5. GitHub Pages serves `index.html` which fetches `stats.json` and renders the dashboard
177+
----------
178+
179+
180+
## Local Development
181+
182+
```bash
183+
# Fetch raw data (requires gh CLI and GITHUB_TOKEN in environment)
184+
export GITHUB_TOKEN=your_token
185+
186+
gh api repos/urunc-dev/urunc/actions/workflows \
187+
--paginate > workflows_raw.json
188+
189+
# Fetch runs for a specific workflow ID
190+
gh api "repos/urunc-dev/urunc/actions/workflows/<id>/runs?per_page=40" \
191+
> runs_raw.json
192+
193+
# Run the pipeline
194+
go run .
195+
196+
# Preview the dashboard
197+
python3 -m http.server 8080
198+
open http://localhost:8080
199+
```
200+
----------
201+
202+
203+
## Contributing
204+
205+
1. **Add new tests/modify failure/notify**: Edit `config.yaml` and add desirable configurations
206+
2. **UI changes**: Modify `index.html`, `style.css`, or `app.js`
207+
3. **Cronjob data processing**: Modify `github/workflows/updates.yaml`
208+
209+
----------
210+
211+
## License
212+
213+
Apache 2.0 - See [LICENSE](LICENSE)

0 commit comments

Comments
 (0)