koopa-admin-log/scripts/dossiers-ngi/README.md

5.6 KiB
Raw Blame History

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

# 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
vs_parent_plus / vs_parent_minus git diff --numstat tip vs parent tip (sticky bar +grün/−rot; omitted when no parent)

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 scripts/dossiers-ngi/smoke-branch-tree.sh
# → SMOKE_OK (temp origin + smoke/temp-sibling deleted)

feat/website-views freeze can omit {% include "_cascade/bar.html" %}. Cookie tdpd_edition then has no switcher. No zypper / Caddy plugin. Way back: https://dossiers.ngi.hacktivism.ch/_cascade/use/flask or /_cascade/ (index.html switcher).

On koopa (hernani, no root):

bash scripts/dossiers-ngi/inject-editions-bar.sh

Hourly rebuild injects on skip and freeze-error (keep existing HTML + include).

The bar is position: fixed (not sticky); 100vw overflow is avoided.

Deploy landing (Freigabe)

Do not --delete the whole www root. Sync:

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.

Edition purity: responses send Vary: Cookie and Cache-Control: private, no-cache so /static/css/style.css (same path, different bodies per edition) cannot stick the green design CSS onto main after a views visit.

so new branches need no Caddy edit — only an editions/<slug>/ tree.

bash ~/bin/apply-dossiers-ngi-edition-switch.sh
sudo ~/bin/caddy-apply

Stanza SoT: scripts/dossiers-ngi/caddy-dossiers-ngi.snippet.

Caddy edition map must list each editions/<slug> explicitly. A map output of {http.request.cookie.tdpd_edition} did not expand on Caddy v2.11.4 (only flask worked → 404 for main/views). After new tips appear, refresh the snippet map (or regenerate from ls editions) before apply-dossiers-ngi-edition-switch + caddy-apply.