#!/bin/bash # build_site.sh — pull the images the docs reference from the artifact registry # (if not already present locally), stage them under docs/assets/, then build # the MkDocs site. The built site/ output is what gets pushed to gitea-pages — # never the source images themselves (see scripts/artifacts/push_artifacts.sh). set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$REPO_ROOT" ASSETS_DIR="docs/assets/images" mkdir -p "$ASSETS_DIR" # Frames referenced by the docs. The scene best/worst montages (proper # renderer: Onscreen/Offscreen panel + TPI/FPI/FN legend) live in the # montage-frames registry packages, one per film; pull any film that's missing. MONTAGE_ROOT="experiments/results/holdout/montage_bestworst" for film in Downton_Abbey__A_New_Era Lovelace Café_Society \ Valerian_and_the_City_of_a_Thousand_Plan The_Many_Saints_of_Newark; do if [ ! -d "${MONTAGE_ROOT}/${film}" ]; then echo "==> pulling montage-frames/${film} (not found locally)..." scripts/artifacts/pull_artifacts.sh montage-frames "$film" || true fi done # stage_frame : downscale to <=1920px wide for the site stage_frame() { if [ ! -f "$1" ]; then echo "WARN: $1 not present; keeping existing ${ASSETS_DIR}/$2 (if any)" return fi python3 - "$1" "${ASSETS_DIR}/$2" <<'PY' import sys from PIL import Image src, dst = sys.argv[1], sys.argv[2] im = Image.open(src) if im.width > 1920: im = im.resize((1920, round(im.height * 1920 / im.width)), Image.LANCZOS) im.save(dst, quality=88) print(f"staged {dst} ({im.width}x{im.height})") PY } echo "==> staging referenced frames into ${ASSETS_DIR}" stage_frame "${MONTAGE_ROOT}/Downton_Abbey__A_New_Era/scene_4/4_best_t000128.jpg" \ downton_wedding_couple.jpg stage_frame "${MONTAGE_ROOT}/Downton_Abbey__A_New_Era/scene_16/16_best_t007100.jpg" \ downton_funeral_19of20.jpg stage_frame "${MONTAGE_ROOT}/Downton_Abbey__A_New_Era/scene_7/7_worst_t001754.jpg" \ downton_crew_fn.jpg stage_frame "${MONTAGE_ROOT}/Lovelace/scene_24/24_best_t003607.jpg" \ lovelace_polygraph_bridged.jpg stage_frame "${MONTAGE_ROOT}/Lovelace/scene_6/6_worst_t000421.jpg" \ lovelace_robert_patrick_fpi.jpg stage_frame "${MONTAGE_ROOT}/Lovelace/scene_15/15_best_t002005.jpg" \ lovelace_perfect_second.jpg stage_frame "${MONTAGE_ROOT}/Café_Society/scene_20/20_best_t002430.jpg" \ cafe_society_rapid_cut.jpg stage_frame "${MONTAGE_ROOT}/Valerian_and_the_City_of_a_Thousand_Plan/scene_4/4_best_t001027.jpg" \ valerian_screen_call.jpg stage_frame "${MONTAGE_ROOT}/The_Many_Saints_of_Newark/out_of_cast_fpi/4_worst_t000871.jpg" \ many_saints_outofcast_fpi.jpg # debug-overlay example (extinction state drawn as frozen boxes) — from the # dump_error_frames output, not the montage package stage_frame "experiments/results/holdout/frames/many_saints/fpi/fpi_t03543.jpg" \ many_saints_ghost_fpi.jpg if [ ! -f "${ASSETS_DIR}/germar_beats_xray.jpg" ]; then echo "==> pulling report-highlights/germar_beats_xray.jpg..." scripts/artifacts/pull_artifacts.sh report-highlights germar_beats_xray.jpg fi # pipeline_topology.svg is small and hand-authored (not pulled from anywhere) — # committed directly at docs/assets/images/, not staged from the registry. if [ ! -d experiments/galleries ] || [ -z "$(ls -A experiments/galleries 2>/dev/null)" ]; then echo "==> pulling galleries (not found locally)..." scripts/artifacts/pull_artifacts.sh galleries fi echo "==> generating calibration curve chart" python3 scripts/docs/calibration_chart.py --out "${ASSETS_DIR}/calibration_curves.png" echo "==> generating experiment charts (16-combo ranking, DE landscape, held-out F1, ghost timeline)" python3 scripts/docs/experiment_charts.py --out-dir "${ASSETS_DIR}" echo "==> building site" mkdocs build # -- commit-pinned repo links ------------------------------------------------- # Docs reference repo files via the placeholder hosts https://REPOLINK/ # (this repo) and https://KPNLINK/ (the KPN++ submodule). Substitute them # with raw URLs pinned to the exact commit being published, and fail the build # if any linked path doesn't actually exist at that commit — no dead links. HEAD_SHA="$(git rev-parse HEAD)" KPN_SHA="$(git rev-parse HEAD:external/KPN)" REPO_RAW="https://gitea.tourolle.paris/dtourolle/scene-actor-extraction/raw/commit/${HEAD_SHA}" KPN_RAW="https://gitea.tourolle.paris/dtourolle/KPN/raw/commit/${KPN_SHA}" if [ -n "$(git status --porcelain -- docs scripts src experiments)" ]; then echo "WARN: working tree is dirty — commit-pinned links will point at ${HEAD_SHA}," >&2 echo " which may not contain your latest changes. Commit before deploying." >&2 fi echo "==> verifying repo-linked paths exist at ${HEAD_SHA}" missing=0 for p in $(grep -rhoE 'https://REPOLINK/[A-Za-z0-9_./-]+' docs/*.md | sed 's|https://REPOLINK/||' | sort -u); do if ! git cat-file -e "HEAD:${p}" 2>/dev/null; then echo "error: docs link to '${p}', which does not exist at HEAD" >&2 missing=1 fi done [ "$missing" -eq 0 ] || exit 1 echo "==> pinning repo links to ${HEAD_SHA} (KPN: ${KPN_SHA})" find site -name '*.html' -exec \ sed -i "s|https://REPOLINK|${REPO_RAW}|g; s|https://KPNLINK|${KPN_RAW}|g" {} + if grep -rq 'REPOLINK\|KPNLINK' site; then echo "error: unsubstituted REPOLINK/KPNLINK placeholder left in site/" >&2 exit 1 fi echo "==> done. site/ is ready to deploy to the gitea-pages branch."