feat/dossiers-ngi: inject-editions-bar.sh for freeze HTML missing include
This commit is contained in:
parent
b24dd17ee9
commit
3feb694084
9 changed files with 218 additions and 46 deletions
|
|
@ -71,6 +71,23 @@ bash scripts/dossiers-ngi/smoke-branch-tree.sh
|
|||
# → SMOKE_OK (temp origin + smoke/temp-sibling deleted)
|
||||
```
|
||||
|
||||
## Edition freeze missing the bar (cookie trap)
|
||||
|
||||
`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
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ def diff_numstat(repo: Path, parent_tip: str, tip: str) -> tuple[int, int]:
|
|||
"""Insertions/deletions of tip vs parent tip (git diff --numstat)."""
|
||||
if not parent_tip or not tip or parent_tip == tip:
|
||||
return 0, 0
|
||||
cp = git(repo, "diff", "--numstat", main_tip, tip, check=False)
|
||||
cp = git(repo, "diff", "--numstat", parent_tip, tip, check=False)
|
||||
if cp.returncode != 0:
|
||||
return 0, 0
|
||||
plus = minus = 0
|
||||
|
|
@ -392,13 +392,19 @@ def run_freeze(work: Path, branch: str, slug: str) -> None:
|
|||
|
||||
def inject_bar(edition_dir: Path) -> None:
|
||||
if not INJECT.is_file():
|
||||
print(f"WARN: inject script missing: {INJECT}", file=sys.stderr)
|
||||
return
|
||||
subprocess.run(
|
||||
cp = subprocess.run(
|
||||
[sys.executable, str(INJECT), str(edition_dir)],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if cp.stdout:
|
||||
print(cp.stdout, end="" if str(cp.stdout).endswith("\n") else "\n", file=sys.stderr)
|
||||
if cp.returncode != 0:
|
||||
err = (cp.stderr or "").strip()[:300]
|
||||
print(f"WARN: inject_bar {edition_dir}: {err}", file=sys.stderr)
|
||||
|
||||
|
||||
def rebuild_edition(repo: Path, branch: str, tip: str, editions: Path) -> dict:
|
||||
|
|
@ -425,6 +431,7 @@ def rebuild_edition(repo: Path, branch: str, tip: str, editions: Path) -> dict:
|
|||
cp = git(repo, "worktree", "add", "--detach", str(wt), tip, check=False)
|
||||
if cp.returncode != 0:
|
||||
ensure_placeholder(editions, slug, tip)
|
||||
inject_bar(dest)
|
||||
return {
|
||||
"status": f"error:worktree:{cp.stderr.strip()[:200]}",
|
||||
"seconds": round(time.perf_counter() - t0, 3),
|
||||
|
|
@ -434,6 +441,7 @@ def rebuild_edition(repo: Path, branch: str, tip: str, editions: Path) -> dict:
|
|||
build = wt / "website" / "build"
|
||||
if not build.is_dir():
|
||||
ensure_placeholder(editions, slug, tip)
|
||||
inject_bar(dest)
|
||||
return {"status": "error:no-build", "seconds": round(time.perf_counter() - t0, 3)}
|
||||
|
||||
dest.mkdir(parents=True, exist_ok=True)
|
||||
|
|
@ -462,6 +470,7 @@ def rebuild_edition(repo: Path, branch: str, tip: str, editions: Path) -> dict:
|
|||
return {"status": "built", "seconds": secs}
|
||||
except Exception as exc: # noqa: BLE001 — hourly must continue
|
||||
ensure_placeholder(editions, slug, tip)
|
||||
inject_bar(dest)
|
||||
return {
|
||||
"status": f"error:{type(exc).__name__}:{exc}",
|
||||
"seconds": round(time.perf_counter() - t0, 3),
|
||||
|
|
|
|||
80
scripts/dossiers-ngi/inject-editions-bar.sh
Executable file
80
scripts/dossiers-ngi/inject-editions-bar.sh
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/env bash
|
||||
# Inject cascade-bar include into every editions/<slug> freeze on koopa.
|
||||
# No zypper, no Caddy plugin, no root — hernani must own $WWW.
|
||||
#
|
||||
# bash scripts/dossiers-ngi/inject-editions-bar.sh
|
||||
# WWW=/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch bash …
|
||||
#
|
||||
# Way back without the bar: https://dossiers.ngi.hacktivism.ch/_cascade/use/flask
|
||||
set -euo pipefail
|
||||
|
||||
WWW="${WWW:-/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch}"
|
||||
ED="${ED:-$WWW/editions}"
|
||||
|
||||
if [[ ! -d "$ED" ]]; then
|
||||
echo "FAIL: not a dir: $ED" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
python3 - "$ED" <<'PY'
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
INCLUDE = '{% include "_cascade/bar.html" . %}'
|
||||
BODY_RE = re.compile(r"(<body[^>]*>)", re.IGNORECASE)
|
||||
|
||||
|
||||
def inject(text: str) -> str | None:
|
||||
if INCLUDE in text or "_cascade/bar" in text:
|
||||
return None
|
||||
m = BODY_RE.search(text)
|
||||
if not m:
|
||||
return None
|
||||
i = m.end()
|
||||
return text[:i] + "\n" + INCLUDE + "\n" + text[i:]
|
||||
|
||||
|
||||
root = Path(sys.argv[1]).resolve()
|
||||
scanned = changed = skipped = nobody = 0
|
||||
print(f"ED={root}")
|
||||
for slug_dir in sorted(p for p in root.iterdir() if p.is_dir()):
|
||||
for path in slug_dir.rglob("*.html"):
|
||||
posix = path.as_posix()
|
||||
if "/_cascade/" in posix + "/":
|
||||
continue
|
||||
scanned += 1
|
||||
raw = path.read_text(encoding="utf-8", errors="ignore")
|
||||
if INCLUDE in raw or "_cascade/bar" in raw:
|
||||
skipped += 1
|
||||
continue
|
||||
out = inject(raw)
|
||||
if out is None:
|
||||
nobody += 1
|
||||
print(f"NOBODY {path.relative_to(root)}")
|
||||
continue
|
||||
path.write_text(out, encoding="utf-8")
|
||||
changed += 1
|
||||
print(f"INJECT {path.relative_to(root)}")
|
||||
|
||||
print(f"OK scanned={scanned} injected={changed} already={skipped} nobody={nobody}")
|
||||
if nobody:
|
||||
sys.exit(1)
|
||||
PY
|
||||
|
||||
echo "----- index.html bar? -----"
|
||||
python3 - "$ED" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
root = Path(sys.argv[1])
|
||||
for d in sorted(p for p in root.iterdir() if p.is_dir()):
|
||||
idx = d / "index.html"
|
||||
if not idx.is_file():
|
||||
print(f"MISSING {d.name}/index.html")
|
||||
continue
|
||||
t = idx.read_text(encoding="utf-8", errors="ignore")
|
||||
flag = "BAR" if ("cascade-bar" in t or "_cascade/bar" in t) else "NOBAR"
|
||||
print(f"{flag} {d.name}")
|
||||
PY
|
||||
Loading…
Add table
Add a link
Reference in a new issue