#!/usr/bin/env python3 """Render the nginx vhost (asset/nginx/site.conf.tmpl) from the environment. Both .gitea/workflows/deploy.yml (deploy-web) and refresh.yml call this, so the two pipelines can never disagree about what they substitute. They did once: the WEB_LISTEN placeholder was added to the template and to deploy.yml but not to refresh.yml, so the nightly refresh shipped a literal `listen {{WEB_LISTEN}};` to oolon. `nginx -t` then failed for the whole edge, and because the file is rsynced straight into the live conf.d before it is tested, every vhost's reload -- including the step@ cert renewals -- stayed frozen for days while renewed certs piled up unserved on disk. Guard rails, so that can't recur: * every {{PLACEHOLDER}} in the template must have a matching environment variable, or the render fails before anything leaves the runner; * no {{...}} may survive substitution. A forgotten or misnamed variable is now a red build, not a broken edge. usage: render-site-conf.py [OUTPUT] (default: rendered/site.conf) """ import os import re import sys TEMPLATE = "asset/nginx/site.conf.tmpl" PLACEHOLDER = re.compile(r"\{\{(\w+)\}\}") def main() -> int: out = sys.argv[1] if len(sys.argv) > 1 else "rendered/site.conf" with open(TEMPLATE, encoding="utf-8") as fh: text = fh.read() names = sorted(set(PLACEHOLDER.findall(text))) missing = [n for n in names if n not in os.environ] if missing: sys.stderr.write( "render-site-conf: no environment value for placeholder(s): " + ", ".join(missing) + "\n") return 1 for name in names: text = text.replace("{{%s}}" % name, os.environ[name]) leftover = sorted(set(PLACEHOLDER.findall(text))) if leftover: sys.stderr.write( "render-site-conf: unrendered placeholder(s) after substitution: " + ", ".join(leftover) + "\n") return 1 os.makedirs(os.path.dirname(out) or ".", exist_ok=True) with open(out, "w", encoding="utf-8") as fh: fh.write(text) sys.stderr.write( "render-site-conf: wrote %s (%d substitutions: %s)\n" % (out, len(names), ", ".join(names))) return 0 if __name__ == "__main__": raise SystemExit(main())