v0.316.0 shipped it dead. Every shell asked for `?v={{.AssetTag}}`, TestAssetTag_EveryShellUsesIt
passed, and the first live load through the public address rendered `/static/style.css?v=` —
EMPTY. addShellAssetData was called only by executeTemplateLang (the sign-in, claim, recovery,
guest-share and catch-all pages). The dashboard path had never needed it, because layout.html used
to ask for {{.Version}}, which baseData supplies; moving it to {{.AssetTag}} left nothing to
supply the value.
An empty buster is a CONSTANT. It would never have changed again — worse than the per-version one
it replaced, and invisible to a test that only checks the markup. executeTemplate now calls the
same function executeTemplateLang does, which is literally what the v0.255.0 comment above that
call asked for: "setting it at the single choke point every shell renders through means a new
shell cannot miss it". There were two choke points.
TestAssetTag_ReachesTheRenderedPage renders six real URLs through the production router and asserts
the buster is non-empty, 8 hex, and not a version. Red-proved by removing the call again: four
pages fail naming the empty value.
A PATCH VERSION, not a second push of 0.316.0 — the rule this release added, applied to its own
mistake rather than around it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
## v0.316.1 — the asset tag actually reaches the dashboard pages (2026-10-15)
|
||||
|
||||
**MinAgent: 0.155.0** (unchanged). A patch release because **a version number is pushed once** — the
|
||||
rule this release added, applied to its own mistake rather than around it.
|
||||
|
||||
- **v0.316.0 shipped the asset tag dead on every dashboard page.** Every shell asked for
|
||||
`?v={{.AssetTag}}` and the template test passed, but `addShellAssetData` was only ever called by
|
||||
`executeTemplateLang` — the stranger-facing pages. The dashboard path had never needed it, because
|
||||
`layout.html` used to ask for `{{.Version}}`, which `baseData` supplies. The first live page load
|
||||
rendered `/static/style.css?v=` — **empty, which is a constant, and a constant busts nothing.**
|
||||
Found in a browser on the public address; the markup was right and the value was absent.
|
||||
`executeTemplate` now calls the same one function, which is what v0.255.0's own comment asked for.
|
||||
- `TestAssetTag_ReachesTheRenderedPage` asserts the rendered buster is NON-EMPTY, 8 hex and not a
|
||||
version, on six real URLs through the production router. `TestAssetTag_EveryShellUsesIt` checks the
|
||||
markup; it could not see this, and asserting a link exists proves nothing about what it carries.
|
||||
|
||||
## v0.316.0 — the app page as one column; a version number is pushed once (2026-10-15)
|
||||
|
||||
**MinAgent: 0.155.0** (unchanged — no new agent call). No golden (`09` §3 decision 250). Design:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -64,6 +65,47 @@ func TestAssetTag_ChangesPerBuild(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAssetTag_ReachesTheRenderedPage — the half TestAssetTag_EveryShellUsesIt cannot see.
|
||||
//
|
||||
// THIS TEST EXISTS BECAUSE THE SUITE MISSED A DEAD FIX. Every shell asked for
|
||||
// `?v={{.AssetTag}}`, the template test passed, and the first live page load rendered
|
||||
// `/static/style.css?v=` — empty. `addShellAssetData` was called only by executeTemplateLang (the
|
||||
// stranger-facing pages); the dashboard path had never needed it, because layout.html used to ask
|
||||
// for `{{.Version}}`, which baseData supplies. The markup was right and the value was absent, which
|
||||
// is worse than the defect it replaced: an empty buster is a CONSTANT and never busts anything.
|
||||
//
|
||||
// Asserting the link EXISTS proves nothing. Assert it carries a value.
|
||||
//
|
||||
// RED-PROOF (REPORT.md): remove the addShellAssetData call from executeTemplate -> this fails with
|
||||
// an empty tag on every dashboard page. Reverted.
|
||||
func TestAssetTag_ReachesTheRenderedPage(t *testing.T) {
|
||||
s := appPageHarness(t)
|
||||
re := regexp.MustCompile(`/static/style\.css\?v=([^"']*)`)
|
||||
for _, p := range []string{"/apps/adventurelog", "/apps/adventurelog/data", "/apps/grocy",
|
||||
"/apps/grocy/install", "/stacks", "/dashboard"} {
|
||||
rec := appGet(t, s, p)
|
||||
if rec.Code != 200 {
|
||||
continue // a page this harness cannot render is another test's problem
|
||||
}
|
||||
m := re.FindStringSubmatch(rec.Body.String())
|
||||
if m == nil {
|
||||
t.Errorf("%s: no stylesheet link at all", p)
|
||||
continue
|
||||
}
|
||||
if m[1] == "" {
|
||||
t.Errorf("%s: the stylesheet buster is EMPTY (%q) — an empty buster is a constant and "+
|
||||
"never busts anything", p, m[0])
|
||||
continue
|
||||
}
|
||||
if m[1] == "0.316.0" || strings.Contains(m[1], ".") {
|
||||
t.Errorf("%s: the buster looks like a version (%q); it must be the per-build tag", p, m[1])
|
||||
}
|
||||
if len(m[1]) != 8 {
|
||||
t.Errorf("%s: buster %q is %d chars, want the 8-hex tag", p, m[1], len(m[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestAssetTag_EveryShellUsesIt — the fix is only a fix if the shells ask for it. Before v0.316.0
|
||||
// two stranger-facing pages used the tag and the other seven shells used `?v={{.Version}}`, which
|
||||
// is exactly the address that did not change between the three 0.315.0 builds.
|
||||
|
||||
@@ -1093,6 +1093,12 @@ func (s *Server) executeTemplate(w http.ResponseWriter, r *http.Request, name st
|
||||
// fence for the guest share page, which has no admin session.
|
||||
s.addEscrowBanner(data, r)
|
||||
s.addMissedBackupBanner(data, r) // R-871 (decision 110)
|
||||
// The stylesheet cache-buster, for the DASHBOARD shell. executeTemplateLang has called this for
|
||||
// the stranger-facing pages since v0.255.0; this path did not need it while layout.html asked for
|
||||
// `?v={{.Version}}`, which baseData supplies. v0.316.0 moved it to `{{.AssetTag}}` and the first
|
||||
// live load rendered `?v=` — a constant, which is worse than the version it replaced. Both render
|
||||
// paths now go through the one function, which is what v0.255.0's own comment asked for.
|
||||
s.addShellAssetData(data)
|
||||
lang := s.langFor(r)
|
||||
s.addLanguageData(data, r, lang)
|
||||
var buf bytes.Buffer
|
||||
|
||||
Reference in New Issue
Block a user