"""Build phase — content prep (static) or docker image build.""" import os import shutil import subprocess import tempfile from pathlib import Path from utils import EXCLUDE_FILES, die, env, parse_site_yaml, run def build_static(site_dir, cfg): build_dir = site_dir / "build" html_dir = build_dir / "html" if build_dir.exists(): shutil.rmtree(build_dir) content_dir = cfg["content_dir"] src = site_dir / content_dir if content_dir else site_dir if cfg["type"] == "static": print(f"Copying static content from {src}") with tempfile.TemporaryDirectory() as tmp: tmp_path = Path(tmp) / "html" shutil.copytree(src, tmp_path, dirs_exist_ok=True) for name in EXCLUDE_FILES: p = tmp_path / name if p.is_dir(): shutil.rmtree(p) elif p.exists(): p.unlink() build_dir.mkdir(parents=True) shutil.move(str(tmp_path), str(html_dir)) elif cfg["type"] == "hugo": print(f"Building Hugo site from {src}") run(f"hugo --source {src} --destination {html_dir}") elif cfg["type"] == "mkdocs": print(f"Building MkDocs site from {src}") run(f"cd {src} && mkdocs build -d {html_dir}") if cfg.get("tidy", True): print("Running tidy on HTML files...") for html_file in html_dir.rglob("*.html"): subprocess.run( ["tidy", "-modify", "-quiet", "--wrap", "0", "--indent", "auto", "--indent-spaces", "2", "--drop-empty-elements", "no", "--tidy-mark", "no", "--show-warnings", "no", str(html_file)], check=False, ) print(f"Build complete — content at {html_dir}") def docker_login(): password = os.environ.get("REGISTRY_PASSWORD", "") user = env("CI_BOT_USER", "ci-bot") if not password: die("REGISTRY_PASSWORD is required for docker builds") subprocess.run( f"echo '{password}' | docker login code.fritzlab.net -u {user} --password-stdin", shell=True, check=True, ) def build_docker(site_dir, cfg): docker_login() image = cfg["image"] run_number = env("GITHUB_RUN_NUMBER", "0") tags = [f"{image}:latest", f"{image}:{run_number}"] cmd_parts = ["docker", "build"] for tag in tags: cmd_parts += ["-t", tag] cmd_parts += ["--network", "host", "--provenance=false"] for key, val in cfg.get("build_args", {}).items(): cmd_parts += ["--build-arg", f"{key}={val}"] cmd_parts.append(str(site_dir)) run(" ".join(cmd_parts)) print(f"Docker build complete — tags: {', '.join(tags)}") def cmd_build(): site_dir = Path(env("SITE_DIR")) cfg = parse_site_yaml(site_dir) if not cfg["enabled"]: print("Site disabled — skipping build") return if cfg["type"] == "docker": build_docker(site_dir, cfg) else: build_static(site_dir, cfg)