feat: initial commit
@@ -0,0 +1,17 @@
|
||||
# Project Rules - CI Observer
|
||||
|
||||
## Scope
|
||||
This folder contains CI Observer source and handover materials.
|
||||
|
||||
## Structure
|
||||
- `ci-observer-dashboard/` = git repo and source code
|
||||
- `ci-observer-handover/` = local codex-only context, screenshots, runbooks
|
||||
|
||||
## Working Rules
|
||||
- Production deploy target is defined in handover context.
|
||||
- Test first in isolated runner folder/port, then merge to `main`, then production deploy.
|
||||
- Do not commit files from `ci-observer-handover/` to git.
|
||||
|
||||
## Must Read First
|
||||
- `ci-observer-handover/contexts/CI_OBSERVER_COMPACT_DUMP.md`
|
||||
- `ci-observer-handover/AGENTS.md`
|
||||
@@ -0,0 +1,44 @@
|
||||
# CI Observer Agent Handover
|
||||
|
||||
## Scope
|
||||
This handover applies to CI Observer dashboard work only.
|
||||
|
||||
## Current Truth
|
||||
- Production runs from: `/webapps/ci-observer-dashboard-prod`
|
||||
- Production branch: `main`
|
||||
- Production port: `8089`
|
||||
- Production container: `ci-observer-dashboard-prod`
|
||||
|
||||
## Working Style Requirements
|
||||
- Keep solutions explicit and simple.
|
||||
- Avoid hidden abstractions and unnecessary variables.
|
||||
- Prefer readable, direct changes over clever patterns.
|
||||
- Test changes on a temporary `/webapps/ci-observer-dashboard-<feature>` folder first.
|
||||
- Only after approval, merge to `main` and deploy production.
|
||||
|
||||
## Safe Release Flow
|
||||
1. Create feature branch in repo.
|
||||
2. Implement and push.
|
||||
3. Test on dedicated test folder + test port.
|
||||
4. Collect user approval.
|
||||
5. Merge feature branch to `main`.
|
||||
6. Deploy from `/webapps/ci-observer-dashboard-prod`.
|
||||
7. Cleanup test container/folder.
|
||||
|
||||
## App Behavior Notes
|
||||
- Backend: Python + FastAPI.
|
||||
- Frontend: HTML/CSS/Vanilla JS.
|
||||
- Storage: SQLite in mounted volume.
|
||||
- Polling requires BOTH `GH_REPOS` and `GH_WORKFLOWS`.
|
||||
|
||||
## Required Checks Before Saying "Done"
|
||||
- `docker ps` shows correct container and port.
|
||||
- `curl http://127.0.0.1:8089/api/config` returns expected JSON.
|
||||
- UI shows data (not empty dashboard).
|
||||
- Browser hard refresh tested when frontend changes (`Ctrl+Shift+R`).
|
||||
|
||||
## Where to Read More
|
||||
- `docs/OPERATIONS_RUNBOOK.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/STACK_OVERVIEW.md`
|
||||
- `ci-observer-handover/contexts/CI_OBSERVER_CONTEXT_LATEST_2026-02-11.md`
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 321 B |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 884 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,59 @@
|
||||
# CI Observer Compact Dump
|
||||
|
||||
## Current Production (authoritative)
|
||||
- Server path: `/webapps/ci-observer-dashboard-prod`
|
||||
- Container: `ci-observer-dashboard-prod`
|
||||
- Port: `8089 -> 8088`
|
||||
- Deploy branch: `main`
|
||||
- Health check: `curl -s http://127.0.0.1:8089/api/config`
|
||||
|
||||
## Stack
|
||||
- FE: HTML + CSS + Vanilla JavaScript
|
||||
- BE: Python + FastAPI
|
||||
- FE-BE bridge: REST API (`/api/runs`, `/api/filters`, `/api/config`)
|
||||
- Data layer: SQLite + GitHub Actions API
|
||||
|
||||
## Required Env
|
||||
- `GITHUB_TOKEN`
|
||||
- `GH_REPOS`
|
||||
- `GH_WORKFLOWS` (required for polling in current logic)
|
||||
- `REFRESH_SECONDS`
|
||||
- `DASHBOARD_TITLE`
|
||||
|
||||
## Key Features in main
|
||||
- Metadata-rich run cards (event, actor, author, commit SHA, message, date, duration)
|
||||
- Repo short name display (without org prefix)
|
||||
- Race-style clock (`HH:MM:SS.cc`) + date in same panel
|
||||
- Light mode toggle (hanging bulb), default dark, preference in localStorage
|
||||
- Light mode contrast tuned for pass/fail (medium)
|
||||
|
||||
## Recent Important Commits on main
|
||||
- `689a78c` merge: metadata cards + race clock
|
||||
- `a719b7d` docs: runbook + architecture + stack overview
|
||||
- `d33f96e` merge: light mode toggle + contrast tuning
|
||||
|
||||
## Standard Production Update
|
||||
```bash
|
||||
cd /webapps/ci-observer-dashboard-prod
|
||||
git checkout main
|
||||
git pull
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
## Troubleshooting Fast Path
|
||||
- UI loads but no runs:
|
||||
- check `.env` (`GH_WORKFLOWS` not empty)
|
||||
- `docker compose up -d --build`
|
||||
- FE change not visible:
|
||||
- browser hard refresh `Ctrl+Shift+R`
|
||||
|
||||
## Test Workflow Pattern
|
||||
- Create isolated test folder: `/webapps/ci-observer-dashboard-<feature>`
|
||||
- Use separate port (e.g. 8090)
|
||||
- Validate, then merge to `main`, deploy prod, cleanup test folder
|
||||
|
||||
## Canonical Docs
|
||||
- `docs/OPERATIONS_RUNBOOK.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/STACK_OVERVIEW.md`
|
||||
- `ci-observer-handover/AGENTS.md`
|
||||
@@ -0,0 +1,78 @@
|
||||
# CI Observer - Latest Context (2026-02-11)
|
||||
|
||||
## Final Production State
|
||||
- Production folder on runner: `/webapps/ci-observer-dashboard-prod`
|
||||
- Production container: `ci-observer-dashboard-prod`
|
||||
- Production port: `8089 -> 8088`
|
||||
- Production branch policy: deploy from `main`
|
||||
- Current app is running and data is visible.
|
||||
|
||||
## Repository
|
||||
- Repo: `Wolkabout/ci-observer-dashboard`
|
||||
- Local path used for development: `/home/nikola/codex-cli/ci-observer-dashboard`
|
||||
|
||||
## Important Commits on main
|
||||
- `689a78c` merge: GHA metadata cards + race clock improvements
|
||||
- `a719b7d` docs: runbook + architecture + stack overview
|
||||
- `d33f96e` merge: light mode bulb toggle + light contrast tuning
|
||||
|
||||
## Major Features Implemented
|
||||
1. Metadata-rich run cards:
|
||||
- Added event, actor, author, commit short SHA, commit message, date, duration.
|
||||
|
||||
2. Repo name simplification:
|
||||
- Card header shows short repo name (`IoT-Platform-Core`, `argocd`) instead of `Org/repo`.
|
||||
|
||||
3. Race clock UI:
|
||||
- Large 24h digital time in top-right: `HH:MM:SS.cc`
|
||||
- Seconds and centiseconds visually de-emphasized.
|
||||
- Subtle pulse each second.
|
||||
- Date shown with clock (`YYYY-MM-DD`).
|
||||
|
||||
4. Light mode + bulb toggle:
|
||||
- Default: dark mode.
|
||||
- User toggle: hanging bulb button placed between title and clock.
|
||||
- Theme saved in browser localStorage.
|
||||
- Light mode pass/fail contrast tuned (medium level).
|
||||
|
||||
5. Documentation added to repo:
|
||||
- `docs/OPERATIONS_RUNBOOK.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/STACK_OVERVIEW.md`
|
||||
|
||||
## Runtime Config Notes
|
||||
- App currently requires both `GH_REPOS` and `GH_WORKFLOWS`.
|
||||
- If `GH_WORKFLOWS` is empty, polling does not start (UI loads but no runs).
|
||||
- Required `.env` keys:
|
||||
- `GITHUB_TOKEN`
|
||||
- `GH_REPOS`
|
||||
- `GH_WORKFLOWS`
|
||||
- `REFRESH_SECONDS`
|
||||
- `DASHBOARD_TITLE`
|
||||
|
||||
## Current Cleanup Status
|
||||
- Old test containers and folders were cleaned.
|
||||
- `/webapps` now keeps production folder only for CI Observer.
|
||||
|
||||
## Standard Production Update Command
|
||||
```bash
|
||||
cd /webapps/ci-observer-dashboard-prod
|
||||
git checkout main
|
||||
git pull
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
## If Data Disappears But UI Loads
|
||||
- Check `.env` first (`GH_WORKFLOWS` is usually the cause).
|
||||
- Then rebuild:
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
## Next Session Starting Point
|
||||
- Start from production folder: `/webapps/ci-observer-dashboard-prod`
|
||||
- Verify status:
|
||||
```bash
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep ci-observer-dashboard-prod
|
||||
curl -s http://127.0.0.1:8089/api/config
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
# Codex Work Context (Wolkabout GHA Diagram)
|
||||
|
||||
## Project
|
||||
- Repo: `/home/nikola/codex-cli`
|
||||
- Task: Create/iterate Wolkabout GHA pipeline SVG with 2D and 3D variants.
|
||||
|
||||
## Latest User Request
|
||||
- Keep the current 2D diagram unchanged.
|
||||
- Produce a separate 3D version where **all elements except text are skewed** (nagnuto), and 3D depth is stronger.
|
||||
|
||||
## Key Output Files
|
||||
- 2D (approved):
|
||||
- `/home/nikola/codex-cli/Wolkabout-platform-pipeline-GHA-v3.svg`
|
||||
- `/home/nikola/codex-cli/Wolkabout-platform-pipeline-GHA-v3.png`
|
||||
- 3D (working version, skewed):
|
||||
- `/home/nikola/codex-cli/Wolkabout-platform-pipeline-GHA-v3-3d.svg`
|
||||
- `/home/nikola/codex-cli/Wolkabout-platform-pipeline-GHA-v3-3d.png`
|
||||
|
||||
## What Was Done (Summary)
|
||||
- Built a richer 2D diagram with 3 lanes (IoT, ArgoCD, WTF), per-workflow card details, start/end chevrons, subtle lane backgrounds, and rectangular handoff arrows that route along outer edges.
|
||||
- Added runner/env/deploy info and detailed step descriptions based on workflow files in:
|
||||
- `/home/nikola/WA-git/IoT-Platform-Core/.github/workflows/all-in-one.yml`
|
||||
- `/home/nikola/WA-git/IoT-Platform-Core/.github/workflows/unit-tests.yml`
|
||||
- `/home/nikola/WA-git/argocd/.github/workflows/deploy-be.yml` (branch: `atest1`)
|
||||
- `/home/nikola/WA-git/Wolkabout-Test-Framework/.github/workflows/new-parallel-wtf.yml`
|
||||
- Handoff arrows updated to rectangular paths:
|
||||
- `M 2530 300 L 2530 440 L 30 440 L 30 590 L 40 590`
|
||||
- `M 2530 590 L 2530 780 L 30 780 L 30 900 L 40 900`
|
||||
- Increased lane background visibility and added deeper card shadows + gradient fills.
|
||||
|
||||
## 3D Variant Adjustments
|
||||
- Created a new file: `Wolkabout-platform-pipeline-GHA-v3-3d.svg`.
|
||||
- Applied stronger depth via:
|
||||
- Card gradient (`#1a2742` -> `#0a0f18`)
|
||||
- Deeper shadow filters `card-shadow-deep` and `card-shadow-soft`
|
||||
- Heavier shadow on start/end tags (`flow-shadow`) with offset
|
||||
- Applied **global skew** so everything except text tilts:
|
||||
- Wrapped all content in `<g id="tilt" transform="skewX(-6)"> ... </g>`
|
||||
- Added `transform="skewX(6)"` to every `<text ...>` to keep text visually upright.
|
||||
|
||||
## Notes on Tools/Warnings
|
||||
- `inkscape` export used to generate PNGs.
|
||||
- Inkscape warns about unimplemented style property 109 (safe to ignore).
|
||||
|
||||
## Next Steps / Open Items
|
||||
- Validate the 3D skew visual to confirm the tilt is strong enough.
|
||||
- If needed: increase skew (e.g., `skewX(-8)` or `-10`) and adjust text counter-skew.
|
||||
- Optional: add more 3D depth (side faces) if requested.
|
||||
|
||||
## Location of Current 3D Edits in SVG
|
||||
- Global skew group added near root:
|
||||
- `<g id="tilt" transform="skewX(-6)">` wrapping the entire scene
|
||||
- Closing `</g>` before `</svg>`
|
||||
- Text counter-skew applied by replacing `<text ...>` with `<text transform="skewX(6)" ...>`.
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# Codex Context: Terraform VM + Docker Compose Test (Single Node)
|
||||
|
||||
## Goal
|
||||
Test a single-node Docker Compose deployment on a Terraform-provisioned VM (no k3s), using the same layout as swarm. Ensure backend + FE + proxies come up and healthcheck works. This is a throwaway, clean environment.
|
||||
|
||||
## Current State
|
||||
- VM created via Terraform: `terraform-testvm-1` on Proxmox node `rbmk2`.
|
||||
- IP: `10.1.50.125/24`, gateway `10.1.50.1`.
|
||||
- SSH: `ssh devops@10.1.50.125 -p42315` (company policy non-22).
|
||||
- Docker installed via `get.docker.com` on the VM.
|
||||
- Compose location on VM: `/webapps/wolkabout`.
|
||||
- Volume/config location on VM: `/mnt/docker-volumes/wolkabout`.
|
||||
- HAProxy fixed by ensuring `options.http` ends with a blank line.
|
||||
|
||||
## Files on laptop
|
||||
- New compose file with MySQL + Cassandra: `/home/nikola/codex-cli/docker-compose.with-dbs.yml` (version 2.4).
|
||||
- This file was copied to the VM as `/webapps/wolkabout/docker-compose.yml`.
|
||||
|
||||
## Compose contents (high level)
|
||||
- Services: `mysql8`, `cassandra`, `cloud-config`, `rabbitmq`, `mosquitto`, `backend`, `frontend`, `frontend-federated`, `http2amqp`, `mqtt2amqp`, `loki`, `haproxy`.
|
||||
- Ordered startup using `depends_on` + healthchecks (DBs first, then base infra, then app/FE).
|
||||
- Network name: `core-net` (kept same name).
|
||||
- MySQL image: `mysql:8.0.32-debian` with:
|
||||
- root password `password`
|
||||
- DB `swarm`, user `wolk`, password `Test1234`
|
||||
- volumes: `/mnt/docker-volumes/wolkabout/mysql8`, init folder `/mnt/docker-volumes/wolkabout/mysql8-init`, config `/mnt/docker-volumes/wolkabout/config/mysql-custom.cnf`
|
||||
- Cassandra image: `cassandra:4.1.2`, volume `/mnt/docker-volumes/wolkabout/cassandra`, heap env.
|
||||
|
||||
## Config changes still needed on VM
|
||||
Update these to point to local DBs/containers:
|
||||
- `/mnt/docker-volumes/wolkabout/config/wolk-commons.yml`
|
||||
- `spring.datasource.url` -> `jdbc:mysql://mysql8:3306/swarm?...`
|
||||
- `spring.datasource.username` -> `wolk`
|
||||
- `spring.datasource.password` -> `Test1234`
|
||||
- `spring.cassandra.contact-points` -> `cassandra`
|
||||
- `/mnt/docker-volumes/wolkabout/config/mosquitto.conf`
|
||||
- `auth_opt_host mysql8`
|
||||
- `auth_opt_dbname swarm`
|
||||
- `auth_opt_user wolk`
|
||||
- `auth_opt_pass Test1234`
|
||||
|
||||
## MySQL/Cassandra init
|
||||
No dump yet. We want a clean environment. Create minimal init:
|
||||
- MySQL init dir: `/mnt/docker-volumes/wolkabout/mysql8-init/init.sql`
|
||||
- For now can just `CREATE DATABASE IF NOT EXISTS swarm;`.
|
||||
- Cassandra keyspace: `swarm` (from `wolk-commons.yml`).
|
||||
|
||||
Recommended scripts on VM (create in `/webapps/wolkabout`):
|
||||
- `init-mysql.sh` waits for mysql, applies init.sql if present.
|
||||
- `init-cassandra.sh` waits for cassandra, creates keyspace `swarm`.
|
||||
|
||||
## Docker registry login
|
||||
ECR images require login on the VM. On swarm1 there is `~/.aws/credentials` and `~/.aws/config` (region `eu-west-1`). Use those creds (copy from swarm1 or your internal source) and run:
|
||||
- `aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 629307322585.dkr.ecr.eu-west-1.amazonaws.com`
|
||||
|
||||
## Known runtime issue
|
||||
- `mosquitto` fails if MySQL schema/tables do not exist (`MosquittoUser`, `MosquittoTopic`). Backend may not auto-create them. If needed, we must add minimal SQL schema later.
|
||||
|
||||
## Healthcheck target
|
||||
Backend is considered ready when:
|
||||
- `https://<domain>.wolkabout.com/api/infos/server` returns JSON.
|
||||
|
||||
## Next Actions (expected)
|
||||
1. Create `/mnt/docker-volumes/wolkabout/config/mysql-custom.cnf` (utf8mb4 + mysql_native_password + max_connections + bind-address).
|
||||
2. Update `wolk-commons.yml` + `mosquitto.conf` to local DB hostnames.
|
||||
3. Create init scripts + minimal init.sql.
|
||||
4. `docker compose down` then `up -d`.
|
||||
5. Run init scripts and validate with `docker compose ps`.
|
||||
@@ -0,0 +1,80 @@
|
||||
# Codex Work Context (New Pipeline Experiment)
|
||||
|
||||
## Goal
|
||||
|
||||
Create a simplified, stable pipeline that provisions a dynamic Integration/Atest
|
||||
environment via Terraform and deploys the platform using Docker Compose on a
|
||||
single-node VM. This is a PoC to validate the flow end-to-end.
|
||||
|
||||
## Guiding Principles
|
||||
|
||||
- Keep everything basic and transparent. No hidden logic or magic variables.
|
||||
- Prefer explicit, readable configuration over abstraction.
|
||||
- Security hardening is not a priority at this stage.
|
||||
- The goal is: it works, and it is easy to see why it works or fails.
|
||||
|
||||
## Current Plan (High-Level)
|
||||
|
||||
1. Terraform provisions a VM from Proxmox template `debian12-tf-template`.
|
||||
2. Docker Compose is used to deploy the platform on that VM.
|
||||
3. HAProxy handles routing for API and frontends (TLS enabled).
|
||||
4. Healthcheck confirms readiness via:
|
||||
`https://<domain>.wolkabout.com/api/infos/server`
|
||||
5. Tear down the VM after the run (if/when automated).
|
||||
|
||||
## Compose Package Location
|
||||
|
||||
Prepared in:
|
||||
|
||||
- `/home/nikola/codex-cli/terraform-vm-docker`
|
||||
|
||||
Contains:
|
||||
|
||||
- `docker-compose.yml`
|
||||
- `.env`
|
||||
- `bring-up.md`
|
||||
- `healthcheck.sh`
|
||||
- `config/` (wolk config YAMLs + firebase JSON)
|
||||
- `haproxy_config/` (haproxy.cfg + options.http)
|
||||
- `ssl/2026-SSL-WA-full.pem`
|
||||
- `custom-assets/federation.manifest.json`
|
||||
- `whiteLabeling/` (generated by backend on first successful start)
|
||||
|
||||
## Runtime Assumptions (from existing Swarm setup)
|
||||
|
||||
Images in use:
|
||||
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/mono-web:150`
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/wolkabout:cloudconfig-22.8.2`
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/wolkabout:wafels-112.federation-poc-1`
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/wolkabout:frontend-federated`
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/utils-http2amqp:151`
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/utils-mqtt2amqp:151`
|
||||
- `629307322585.dkr.ecr.eu-west-1.amazonaws.com/wolkabout:mqtt_ws`
|
||||
- `rabbitmq:4.1-management-alpine`
|
||||
- `grafana/loki:3.4.1`
|
||||
- `haproxy:2.6`
|
||||
|
||||
Known dependencies:
|
||||
|
||||
- MySQL: `10.0.50.157:3306` (schema `swarm`, user `wolk`, pass `Test1234`)
|
||||
- Cassandra: `10.0.50.163` (keyspace `swarm`)
|
||||
|
||||
## Healthcheck
|
||||
|
||||
Use `healthcheck.sh` to verify readiness:
|
||||
|
||||
- `https://<domain>.wolkabout.com/api/infos/server`
|
||||
- Expects HTTP 200 and JSON with `organization` key.
|
||||
|
||||
## Networking
|
||||
|
||||
- Compose network name: `core-net`
|
||||
- Single-node bridge network (no overlay)
|
||||
- Ports exposed: `80`, `443`, `2883`, `8883`, `3100`
|
||||
|
||||
## Notes
|
||||
|
||||
- MQTT/HTTP2AMQP config mounts are present but commented in Compose.
|
||||
- All secrets are kept inline for now to reduce moving parts.
|
||||
- Debugging should be obvious from config + logs without additional tooling.
|
||||
@@ -0,0 +1,51 @@
|
||||
# CI Observer Dashboard Context
|
||||
|
||||
> Superseded by: `ci-observer-handover/contexts/CI_OBSERVER_CONTEXT_LATEST_2026-02-11.md`
|
||||
> Use the newer file for current production/runtime state.
|
||||
|
||||
## Why this exists
|
||||
- Need a read-only, always-on CI status wall for CTO/DevOps.
|
||||
- Must not affect existing CI/CD pipelines or protected branches.
|
||||
- Quick POC required using local infra and GitHub Actions metadata.
|
||||
|
||||
## What we built
|
||||
- Standalone dashboard service that polls GitHub Actions and renders a live view.
|
||||
- Runs on the runner VM as a Docker container.
|
||||
- Uses a classic GitHub PAT (read-only scopes) to read workflow runs.
|
||||
|
||||
## Current behavior
|
||||
- Polls GitHub Actions workflow runs every `REFRESH_SECONDS` (default 5s).
|
||||
- Shows last 10 runs by updated time.
|
||||
- Status colors:
|
||||
- green = pass
|
||||
- orange = partial (cancelled/skipped/etc.)
|
||||
- red = fail
|
||||
- blue = running/info
|
||||
- Cards show run number, workflow, branch, start time, duration, and a link to the run.
|
||||
- UI tuned for 23–24" monitor: 5 cards per row.
|
||||
|
||||
## Repo and runtime
|
||||
- Repo: `Wolkabout/ci-observer-dashboard`
|
||||
- Deploy path on runner VM: `/webapps/ci-observer-dashboard`
|
||||
- Default port: `8088`
|
||||
- URL: `http://10.1.50.20:8088`
|
||||
|
||||
## How to run (POC)
|
||||
```
|
||||
cd /webapps/ci-observer-dashboard
|
||||
cp .env.example .env
|
||||
# set GITHUB_TOKEN, GH_REPOS, GH_WORKFLOWS, REFRESH_SECONDS
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
## Current config (example)
|
||||
```
|
||||
GH_REPOS=Wolkabout/IoT-Platform-Core
|
||||
GH_WORKFLOWS=unit-tests.yml
|
||||
REFRESH_SECONDS=5
|
||||
```
|
||||
|
||||
## Notes for future Codex sessions
|
||||
- This is read-only and independent of CI pipelines.
|
||||
- To add more repos/workflows, extend `GH_REPOS` and `GH_WORKFLOWS` (comma-separated).
|
||||
- AI summary integration (Ollama) is planned but not implemented yet.
|
||||
@@ -0,0 +1,72 @@
|
||||
# CI Observer Architecture
|
||||
|
||||
## What It Is
|
||||
CI Observer is a read-only dashboard that polls GitHub Actions run data and renders a live CI status wall.
|
||||
|
||||
## Core Technologies
|
||||
- Backend: Python 3.11 + FastAPI
|
||||
- HTTP client: `httpx`
|
||||
- Storage: SQLite (`/app/data/ci_observer.db`)
|
||||
- Frontend: server-rendered static HTML/CSS/JS (no SPA framework)
|
||||
- Runtime: Docker + Docker Compose
|
||||
- Source control: GitHub
|
||||
|
||||
## High-Level Flow
|
||||
```mermaid
|
||||
flowchart LR
|
||||
GH[GitHub Actions API] -->|poll runs| APP[FastAPI Poller]
|
||||
APP -->|upsert| DB[(SQLite)]
|
||||
UI[Browser] -->|GET /api/runs /api/filters /api/config| APP
|
||||
APP -->|query| DB
|
||||
APP -->|JSON + static assets| UI
|
||||
```
|
||||
|
||||
## Runtime Components
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph Runner_VM
|
||||
C[Docker Container: ci-observer-dashboard-prod]
|
||||
D[(Volume ./data -> /app/data)]
|
||||
S[Static UI: index.html + app.js + styles.css]
|
||||
A[FastAPI app/main.py]
|
||||
C --> A
|
||||
C --> S
|
||||
C --> D
|
||||
end
|
||||
|
||||
Browser -->|HTTP :8089| C
|
||||
A -->|HTTPS calls| GitHubAPI[api.github.com]
|
||||
```
|
||||
|
||||
## Data Model (Main Fields)
|
||||
Stored run fields include:
|
||||
- `repo`, `workflow`, `run_id`, `status`, `conclusion`
|
||||
- `head_branch`, `head_sha`, `actor`
|
||||
- `started_at`, `updated_at`, `duration_seconds`
|
||||
- `html_url`
|
||||
- `raw_json` (full run payload for future extensions)
|
||||
|
||||
## App Principles
|
||||
- Read-only by design: no write-back to GitHub or pipeline control.
|
||||
- Operational simplicity: one container, one DB file, one compose file per instance.
|
||||
- Clear rollout model: feature branch on test port, then merge to `main`, then production deploy.
|
||||
- Low blast radius: test instances isolated by folder, port, and SQLite volume path.
|
||||
|
||||
## Config Contract
|
||||
Environment variables:
|
||||
- `GITHUB_TOKEN`
|
||||
- `GH_REPOS` (comma-separated)
|
||||
- `GH_WORKFLOWS` (comma-separated workflow file names)
|
||||
- `REFRESH_SECONDS`
|
||||
- `DASHBOARD_TITLE`
|
||||
|
||||
Important:
|
||||
- Current polling logic requires both `GH_REPOS` and `GH_WORKFLOWS`.
|
||||
- If `GH_WORKFLOWS` is empty, polling does not start.
|
||||
|
||||
## Deployment Model Used
|
||||
1. Build/test on temporary instance in `/webapps/ci-observer-dashboard-<feature>` on test port.
|
||||
2. Validate UI/behavior.
|
||||
3. Merge approved branch to `main`.
|
||||
4. Production update from `/webapps/ci-observer-dashboard-prod` on `8089`.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# CI Observer Operations Runbook
|
||||
|
||||
## Purpose
|
||||
Operational guide for running CI Observer on the runner VM with one stable production instance and optional temporary test instances.
|
||||
|
||||
## Standard Layout on Runner
|
||||
- Production folder: `/webapps/ci-observer-dashboard-prod`
|
||||
- Temporary test folder example: `/webapps/ci-observer-dashboard-<feature>`
|
||||
- One folder per instance. No nested folder-in-folder setup.
|
||||
|
||||
## Production Deploy (main branch)
|
||||
```bash
|
||||
cd /webapps/ci-observer-dashboard-prod
|
||||
git checkout main
|
||||
git pull
|
||||
docker compose up -d --build
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
## Required `.env`
|
||||
```env
|
||||
GITHUB_TOKEN=...
|
||||
GH_REPOS=Wolkabout/IoT-Platform-Core,Wolkabout/argocd
|
||||
GH_WORKFLOWS=unit-tests.yml,deploy-be.yml,deploy-fe.yml
|
||||
REFRESH_SECONDS=5
|
||||
DASHBOARD_TITLE="CI Observer Dashboard"
|
||||
```
|
||||
|
||||
Notes:
|
||||
- `GH_WORKFLOWS` must be set in current app behavior.
|
||||
- Private repos require PAT scopes: `repo`, `read:org`, `workflow`.
|
||||
|
||||
## Production Compose (8089)
|
||||
`docker-compose.yml` should use:
|
||||
- `container_name: ci-observer-dashboard-prod`
|
||||
- `ports: "8089:8088"`
|
||||
- `volumes: ./data:/app/data`
|
||||
|
||||
## Quick Health Check
|
||||
```bash
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep ci-observer-dashboard-prod
|
||||
curl -s http://127.0.0.1:8089/api/config
|
||||
curl -s http://127.0.0.1:8089/api/runs | head -c 800; echo
|
||||
```
|
||||
|
||||
## Temporary Test Instance Flow
|
||||
```bash
|
||||
cd /webapps
|
||||
git clone https://github.com/Wolkabout/ci-observer-dashboard.git ci-observer-dashboard-mytest
|
||||
cd ci-observer-dashboard-mytest
|
||||
cp /webapps/ci-observer-dashboard-prod/.env .env
|
||||
git checkout <feature-branch>
|
||||
```
|
||||
|
||||
Edit `docker-compose.yml` for test:
|
||||
- `container_name: ci-observer-dashboard-mytest`
|
||||
- `ports: "8090:8088"` (or any free test port)
|
||||
- `volumes: ./data-mytest:/app/data`
|
||||
|
||||
Run:
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Cleanup after test:
|
||||
```bash
|
||||
docker compose down --remove-orphans
|
||||
cd /webapps
|
||||
rm -rf /webapps/ci-observer-dashboard-mytest
|
||||
```
|
||||
|
||||
## Final Cleanup Checklist
|
||||
```bash
|
||||
docker rm -f ci-observer-dashboard ci-observer-dashboard-filters ci-observer-dashboard-metadata-test 2>/dev/null || true
|
||||
find /webapps -maxdepth 1 -type d -name "ci-observer-dashboard-*" ! -name "ci-observer-dashboard-prod"
|
||||
```
|
||||
|
||||
Expected final state:
|
||||
- Only `/webapps/ci-observer-dashboard-prod` is active for production.
|
||||
- Production container on `8089`.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# CI Observer Dashboard (POC)
|
||||
|
||||
Minimal read-only dashboard that polls GitHub Actions runs and renders a live status wall.
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Copy env template:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. Edit `.env` and set:
|
||||
|
||||
- `GITHUB_TOKEN` (classic PAT with `repo`, `read:org`, `workflow`)
|
||||
- `GH_REPOS` (e.g. `Wolkabout/IoT-Platform-Core`)
|
||||
- `GH_WORKFLOWS` (e.g. `unit-tests.yml`)
|
||||
|
||||
3. Run:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
4. Open:
|
||||
|
||||
```
|
||||
http://<runner-ip>:8088
|
||||
```
|
||||
|
||||
## Filters preview (separate instance)
|
||||
|
||||
If testing the filters branch in parallel, use:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.filters.yml up -d --build
|
||||
```
|
||||
|
||||
This runs on port `8089` and uses `./data-filters`.
|
||||
|
||||
### Parallel instance on VM
|
||||
|
||||
```bash
|
||||
cd /webapps
|
||||
git clone https://github.com/Wolkabout/ci-observer-dashboard.git ci-observer-dashboard-filters
|
||||
cd ci-observer-dashboard-filters
|
||||
git checkout feature/filters
|
||||
cp .env.example .env
|
||||
docker compose -f docker-compose.filters.yml up -d --build
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- This is read-only; no CI/CD impact.
|
||||
- For private repos, a token is required.
|
||||
- Data stored locally in `./data/ci_observer.db`.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Operations runbook: `docs/OPERATIONS_RUNBOOK.md`
|
||||
- Architecture + diagrams: `docs/ARCHITECTURE.md`
|
||||
|
||||
## Appendix: Reverse proxy (NPM)
|
||||
|
||||
- Nginx Proxy Manager runs at `10.0.50.78`.
|
||||
- DNS/hosts should point `ci-observer.wolkabout.com` to `10.0.50.78`.
|
||||
- NPM forwards to the dashboard on `10.1.50.20:8089`.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Stack Overview
|
||||
|
||||
- FE: HTML + CSS + Vanilla JavaScript
|
||||
- BE: Python + FastAPI
|
||||
- Between FE and BE: REST API over HTTP (`/api/runs`, `/api/filters`, `/api/config`)
|
||||
- Under BE: SQLite database + GitHub Actions API as the external data source
|
||||
|
||||
|
After Width: | Height: | Size: 158 KiB |
|
After Width: | Height: | Size: 643 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 762 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 969 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 530 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 447 KiB |