From 536510b1483714d168af0b1eaa1c976ab0dc8377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Mon, 28 Sep 2026 11:27:55 -0300 Subject: [PATCH] fix: version the Site's scripts by content so a release never meets a cached old one The proxy in front of production caches .js and .css for hours. After the last release the Site got the new index.html with the old site-flow.js, which wrote to an element the new page no longer has; the error left "Adicionar ao carrinho" disabled. The web build now addresses every local script and stylesheet by a hash of its content, replacing the hand-kept ?v= markers, so a new release always loads its own files. Co-Authored-By: Claude Opus 5.5 --- deploy/Dockerfile.web | 3 ++- infra/Dockerfile.web | 3 ++- infra/compile_web.py | 19 ++++++++++++++++++- web/index.html | 2 +- web/kanban.html | 4 ++-- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/deploy/Dockerfile.web b/deploy/Dockerfile.web index a75b01f..733464a 100644 --- a/deploy/Dockerfile.web +++ b/deploy/Dockerfile.web @@ -22,7 +22,8 @@ LABEL org.opencontainers.image.title="DTF Site and Kanban" \ org.opencontainers.image.source="DTF System repository" ENV WEB_INDEX=index.html PUBLIC_HOST=invalid.example S3_PUBLIC_ENDPOINT=https://invalid.example COPY --from=policy /build/default.conf.template /etc/nginx/templates/default.conf.template -COPY web/ /usr/share/nginx/html/ +# The HTML from the policy stage, with every asset address versioned. +COPY --from=policy /build/web/ /usr/share/nginx/html/ # The official entrypoint renders the server configuration at startup and Nginx # writes its PID/cache files. Keep the service non-root while granting it diff --git a/infra/Dockerfile.web b/infra/Dockerfile.web index 3d03a8b..27d672d 100644 --- a/infra/Dockerfile.web +++ b/infra/Dockerfile.web @@ -10,5 +10,6 @@ RUN apk upgrade --no-cache ENV WEB_INDEX=index.html COPY --from=policy /build/default.conf.template /etc/nginx/templates/default.conf.template ENV S3_PUBLIC_ENDPOINT=http://localhost:9000 -COPY web/ /usr/share/nginx/html/ +# The HTML from the policy stage, with every asset address versioned. +COPY --from=policy /build/web/ /usr/share/nginx/html/ diff --git a/infra/compile_web.py b/infra/compile_web.py index 8a27fb0..f601076 100644 --- a/infra/compile_web.py +++ b/infra/compile_web.py @@ -1,4 +1,7 @@ -"""Compile the gateway configuration: hash any trusted inline script for the CSP. +"""Compile the gateway configuration and version the Site's assets. + +Inline scripts are hashed for the CSP; local scripts and stylesheets get a +content hash in their address. The Site's behaviour now lives in separate files, so normally there is nothing to hash and the policy is simply script-src 'self' — no allowlist to get wrong. The @@ -12,6 +15,20 @@ from pathlib import Path import re root = Path('/build') + +# Every local script and stylesheet is addressed by its content, so a release +# can never pair new HTML with an old cached file: the proxy in front of the +# stack caches assets for hours, and a new index.html calling an old script +# broke the Site (2026-09-28). The HTML itself is served no-cache. +def versioned(match): + attribute, path = match.group(1), match.group(2) + digest = hashlib.sha256((root / 'web' / path.lstrip('/')).read_bytes()).hexdigest()[:12] + return f'{attribute}="{path}?v={digest}"' + +for html in (root / 'web').glob('*.html'): + text = re.sub(r'\b(src|href)="(/[\w./-]+\.(?:js|css))(?:\?[^"]*)?"', versioned, html.read_text()) + html.write_text(text) + hashes = [] for html in (root / 'web').glob('*.html'): for attributes, script in re.findall(r']*)>(.*?)', html.read_text(), re.S | re.I): diff --git a/web/index.html b/web/index.html index 2cd04c3..6453612 100644 --- a/web/index.html +++ b/web/index.html @@ -747,7 +747,7 @@ footer a:hover{color:var(--laranja2)} justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:11px;color:#5A6570} @media(prefers-reduced-motion:reduce){*{transition:none!important;scroll-behavior:auto}} - + diff --git a/web/kanban.html b/web/kanban.html index 4bd2cca..1ad6bc6 100644 --- a/web/kanban.html +++ b/web/kanban.html @@ -3,7 +3,7 @@ Kanban DTF - +