113 lines
4.4 KiB
Markdown
113 lines
4.4 KiB
Markdown
# dossiers-ngi — dynamic edition bar + 10‑min rebuild
|
||
|
||
SoT for the sticky edition bar on **dossiers.ngi.hacktivism.ch**. Live freezes
|
||
sit under `editions/<slug>/` on koopa; cookie `tdpd_edition` selects the build.
|
||
The bar renders a **semi-graphic parent→children tree** from
|
||
`/branch-status.json` (all `origin/*` tips, not a hard-coded ladder).
|
||
|
||
| Path | Role |
|
||
|------|------|
|
||
| `sites/…/_cascade/` | Sticky bar shell + JS tree renderer |
|
||
| `editions/` on koopa www | Full freezes switched by the bar |
|
||
| `sites/…/cascade/` | Legacy tip stubs (optional) |
|
||
| `scripts/dossiers-ngi/branch-status-hourly.py` | Fetch remotes → tree JSON → on-demand rebuild |
|
||
| `scripts/dossiers-ngi/smoke-branch-tree.sh` | Temp-branch smoke (creates/deletes local origin only) |
|
||
| `configs/systemd/user/dossiers-ngi-branch-status.{timer,service}` | Every **10 min** oneshot on koopa (`flock` against overlap) |
|
||
|
||
## Env
|
||
|
||
| Var | Default | Meaning |
|
||
|-----|---------|---------|
|
||
| `TDPD_ROOT` | `$HOME/git/src/ngi/tech-dossier-project-data` | tdpd git checkout (may be git-dir only) |
|
||
| `TDPD_VENV` | `(TDPD_ROOT)/.venv` | Frozen-Flask venv; symlinked into worktrees |
|
||
| `OUT` | kal `sites/…/branch-status.json` | write path (live www on koopa) |
|
||
| `EDITIONS_ROOT` | (none) | `…/editions` — required for `--rebuild` |
|
||
| `REBUILD` / `--rebuild` | off | rebuild when `.edition-tip` ≠ tip |
|
||
| `FORCE_REBUILD` / `--force` | off | rebuild every branch (timing) |
|
||
| `FETCH` / `--no-fetch` | fetch on | `git fetch --prune origin` |
|
||
| `FREEZE_CMD` | (make/venv freeze) | stub for smoke tests; `{root}` `{branch}` `{slug}` |
|
||
| `DEFAULT_BRANCH` | `feat/website-views` | behind cookie `flask` |
|
||
| `HOST` | `https://dossiers.ngi.hacktivism.ch` | public host in JSON |
|
||
|
||
On koopa: `%h/src/koopa/koopa-admin-log` +
|
||
`~/.config/dossiers-ngi/branch-status.env` for path overrides.
|
||
NGI clone token lives in **koopa-admin-secrets-enc** (not this tree).
|
||
|
||
## Manual run
|
||
|
||
```bash
|
||
# JSON only
|
||
python3 scripts/dossiers-ngi/branch-status-hourly.py
|
||
|
||
# rebuild stale freezes + timing block in JSON
|
||
EDITIONS_ROOT=/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/editions \
|
||
python3 scripts/dossiers-ngi/branch-status-hourly.py --rebuild
|
||
|
||
# force all branches (wall clock → rebuild_timing)
|
||
… --rebuild --force
|
||
```
|
||
|
||
`rebuild_timing` fields: `wall_seconds`, `built`, `skipped`, `errors`,
|
||
`built_seconds_sum`, `built_seconds_max`. Per-branch `rebuild[name].seconds`.
|
||
|
||
Per branch in JSON / sticky bar:
|
||
|
||
| Field | Meaning |
|
||
|-------|---------|
|
||
| `tip` | short SHA |
|
||
| `tip_time` | committer time of tip (`%cI`) |
|
||
| `built_at` | when this edition freeze was written |
|
||
| `build_seconds` | wall time of that freeze |
|
||
|
||
Rebuild runs **only when** `.edition-tip` ≠ current tip (timer never forces).
|
||
Each run also: `git fetch --prune`, `worktree prune`, drop stale
|
||
`editions/<slug>/` (gone remotes), purge leftover `tdpd-*` tmp dirs.
|
||
|
||
## Smoke
|
||
|
||
```bash
|
||
bash scripts/dossiers-ngi/smoke-branch-tree.sh
|
||
# → SMOKE_OK (temp origin + smoke/temp-sibling deleted)
|
||
```
|
||
|
||
## Deploy landing (Freigabe)
|
||
|
||
Do **not** `--delete` the whole www root. Sync:
|
||
|
||
```bash
|
||
SITE="$HOME/git/admin-logs/local/koopa-admin-log/sites/dossiers.ngi.hacktivism.ch"
|
||
WWW=hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch
|
||
rsync -avz --exclude .DS_Store "$SITE/_cascade/" "$WWW/_cascade/"
|
||
rsync -avz --exclude .DS_Store "$SITE/branch-status.json" "$WWW/branch-status.json"
|
||
# editions/ from a --rebuild run
|
||
```
|
||
|
||
## Sticky cascade bar
|
||
|
||
`bar.js` fetches `/branch-status.json` and draws:
|
||
|
||
```
|
||
main @ d2fbd79 · tip 2026-09-01 16:52 · build 8.4s · at 2026-09-30 15:23
|
||
├── feat/sm-content @ … · tip YYYY-MM-DD HH:MM · …
|
||
│ └── …
|
||
└── project_template @ …
|
||
```
|
||
|
||
`tip` / `at` always include **date + HH:MM** (ISO already in JSON; clock-only was misleading across days). The bar is **viewport-centered** (max-width 45em, mobile-friendly). Poll every 30s **updates tip/build/at text in place** when the branch structure is unchanged (no full tree remount).
|
||
|
||
Each name links to `/_cascade/use/<edition>` (cookie + 302 `/`). Caddy map:
|
||
|
||
```
|
||
~^[A-Za-z0-9_-]+$ {http.request.cookie.tdpd_edition}
|
||
```
|
||
|
||
Also serve `/cascade/*` from the site www root (path stubs). Live Caddy must not use a trailing `~.* flask` catch-all.
|
||
|
||
so new branches need no Caddy edit — only an `editions/<slug>/` tree.
|
||
|
||
```bash
|
||
bash ~/bin/apply-dossiers-ngi-edition-switch.sh
|
||
sudo ~/bin/caddy-apply
|
||
```
|
||
|
||
Stanza SoT: `scripts/dossiers-ngi/caddy-dossiers-ngi.snippet`.
|