Commit 2272f4bf41
Unsigned ci/build: success ci/lint: success
Layout: unified · split
build.py +41
| @@ -25,6 +25,7 @@ Author: | |||
| 25 | Christian Cleberg <hello@cleberg.net> | 25 | Christian Cleberg <hello@cleberg.net> |
| 26 | """ | 26 | """ |
| 27 | 27 | ||
| 28 | import hashlib | ||
| 28 | import os | 29 | import os |
| 29 | import re | 30 | import re |
| 30 | import subprocess | 31 | import subprocess |
| @@ -135,6 +136,45 @@ def rewrite_orgo_version(build_dir): | |||
| 135 | print(f"Set the footer orgo version to {version} on {count} pages") | 136 | print(f"Set the footer orgo version to {version} on {count} pages") |
| 136 | 137 | ||
| 137 | 138 | ||
| 139 | # Stylesheet links, with or without a ?v= from an earlier build. Cloudflare and browsers | ||
| 140 | # cache these for a year, so the URL has to change whenever the file does. | ||
| 141 | STYLESHEETS = ("styles.css", "syntax.css") | ||
| 142 | STYLESHEET_LINK = re.compile( | ||
| 143 | r'(<link rel="stylesheet" href="[^"]*?)(styles\.css|syntax\.css)(?:\?v=[0-9a-f]+)?(")' | ||
| 144 | ) | ||
| 145 | |||
| 146 | |||
| 147 | def rewrite_stylesheet_versions(build_dir): | ||
| 148 | """Append ?v=<content hash> to every page's stylesheet links. | ||
| 149 | |||
| 150 | Runs over every page for the same reason as rewrite_orgo_version: a page carried | ||
| 151 | over from an earlier build still names the old hash. A build that matches no link | ||
| 152 | fails, because shipping unversioned links means the next CSS change sits behind | ||
| 153 | a year-long cache. | ||
| 154 | """ | ||
| 155 | versions = { | ||
| 156 | name: hashlib.sha256((Path(build_dir) / name).read_bytes()).hexdigest()[:10] | ||
| 157 | for name in STYLESHEETS | ||
| 158 | } | ||
| 159 | count = 0 | ||
| 160 | for html in Path(build_dir).rglob("*.html"): | ||
| 161 | text = html.read_text(encoding="utf-8") | ||
| 162 | new_text, n = STYLESHEET_LINK.subn( | ||
| 163 | lambda m: f"{m[1]}{m[2]}?v={versions[m[2]]}{m[3]}", text | ||
| 164 | ) | ||
| 165 | if n and new_text != text: | ||
| 166 | html.write_text(new_text, encoding="utf-8") | ||
| 167 | count += n | ||
| 168 | if count == 0: | ||
| 169 | print( | ||
| 170 | "No stylesheet links found in the build — the <link> tags in " | ||
| 171 | "content/templates/base.html no longer match STYLESHEET_LINK", | ||
| 172 | file=sys.stderr, | ||
| 173 | ) | ||
| 174 | sys.exit(1) | ||
| 175 | print(f"Versioned {count} stylesheet links: {versions}") | ||
| 176 | |||
| 177 | |||
| 138 | def run_orgo_build(build_dir): | 178 | def run_orgo_build(build_dir): |
| 139 | """ | 179 | """ |
| 140 | Build the site with orgo. | 180 | Build the site with orgo. |
| @@ -226,6 +266,7 @@ def main(): | |||
| 226 | if os.environ.get("BUILD", "").casefold() == "true": | 266 | if os.environ.get("BUILD", "").casefold() == "true": |
| 227 | run_orgo_build(build_dir) | 267 | run_orgo_build(build_dir) |
| 228 | rewrite_orgo_version(build_dir) | 268 | rewrite_orgo_version(build_dir) |
| 269 | rewrite_stylesheet_versions(build_dir) | ||
| 229 | # The onion needs same-origin images; dev previews keep the absolute URLs. | 270 | # The onion needs same-origin images; dev previews keep the absolute URLs. |
| 230 | # Runs over every page, not just the re-rendered ones, so a page carried over | 271 | # Runs over every page, not just the re-rendered ones, so a page carried over |
| 231 | # from an earlier build is rewritten too. | 272 | # from an earlier build is rewritten too. |