Skip to content

guard against stale SPA embed dir at verify and build time#6

Merged
cjimti merged 2 commits into
mainfrom
makefile-spa-gate
May 11, 2026
Merged

guard against stale SPA embed dir at verify and build time#6
cjimti merged 2 commits into
mainfrom
makefile-spa-gate

Conversation

@cjimti
Copy link
Copy Markdown
Contributor

@cjimti cjimti commented May 11, 2026

Summary

  • make ui-verify now diffs internal/ui/dist/ against a fresh ui/dist/ build (excluding .gitkeep) and fails if they differ. Same posture as fmt-check / mod-tidy-check.
  • make build gains a check-ui-embed prerequisite that refuses to compile when internal/ui/dist/index.html is missing.
  • make ui now touches internal/ui/dist/.gitkeep after the copy so the gitignored embed dir stays tracked across rebuilds.

Why

internal/ui/dist/ is embedded into the Go binary via //go:embed. make verify previously ran ui-verify, which only ran pnpm build and never compared the fresh ui/dist/ against the embedded copy. Source could be current while the embedded bundle was stale, and the binary would silently serve the old SPA.

With this change:

  • A stale embed fails make verify locally and in CI.
  • A missing embed fails make build before producing a UI-less binary.

Test plan

  • make verify passes on this branch.
  • make verify fails when internal/ui/dist/index.html is removed.
  • make build fails with the check-ui-embed message when internal/ui/dist/ is empty.
  • CI green.

cjimti added 2 commits May 10, 2026 23:50
ui-verify now diffs internal/ui/dist/ against a fresh ui/dist/ build
and fails if they differ (excluding .gitkeep). build gains a
check-ui-embed prerequisite that refuses to compile when the embed
dir is empty.

Closes a class of bug where `make verify` passes on current source
but the binary embeds a stale SPA bundle, silently shipping the
previous UI to operators.
CodeQL's autobuild step runs the default make target on a fresh
checkout. With this PR's new build: check-ui-embed prerequisite,
that fails because internal/ui/dist/ is gitignored except for the
.gitkeep and `make ui` hasn't run — exactly the failure mode the
gate is designed to surface to developers. CodeQL doesn't need a
working portal; it needs Go to compile for type tracing.

Switched to build-mode: manual + `go build -v ./...`, matching the
CI workflow's Build job (.github/workflows/ci.yml:114). CodeQL no
longer touches Make, so future Makefile prerequisite changes
won't silently break the security scan.

Observed failure on PR #6's CodeQL run:

  Trying build command make []
  FAIL: ./internal/ui/dist/index.html missing.
        The Go binary embeds ./internal/ui/dist via //go:embed.
        Without a built SPA there, the portal serves a JSON
        stub instead of the React UI. Run:
            make ui
  /bin/bash: fork: retry: Resource temporarily unavailable

The fork: retry line is the runner exhausting itself retrying past
the 30-minute timeout — not a flake.
@cjimti cjimti merged commit 232edbc into main May 11, 2026
7 checks passed
@cjimti cjimti deleted the makefile-spa-gate branch May 11, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant