Skip to content

DEV: Validate packaged frontend assets before release - #268

Merged
davidtaylorhq merged 1 commit into
mainfrom
asset-packaging
Sep 24, 2026
Merged

davidtaylorhq merged 1 commit into
mainfrom
asset-packaging

Conversation

@davidtaylorhq

@davidtaylorhq davidtaylorhq commented Aug 25, 2026 •

Copy link
Copy Markdown
Member

The Vite migration added assets/manifest.json and assets/logster-config.json, but both are gitignored and were absent from the gemspec's file list. The existing globs included the built JavaScript and CSS, so the next release would have shipped those assets without the JSON files the viewer needs to load them.

The gemspec now explicitly includes both JSON files and limits the remaining contents to runtime code, vendor files, images, built scripts and stylesheets, and the README, license and changelog. Client sources, tests, gemfiles and CI configuration no longer ship. Explicitly naming the JSON files also makes gem build fail when either is missing.

FrontendAssets.verify! checks the built assets before packaging:

  • Both JSON files must parse as objects. The manifest must have exactly one entry, every chunk must name a file, and all imports and dynamicImports references must resolve.
  • Every chunk's script and stylesheet must exist in the flat asset directories. vendor.js is checked separately because the build copies it outside the manifest.
  • Multiple entries are rejected to catch development builds containing the test entry. Manifest references to additional assets, such as fonts or images, are rejected because the current build script does not package them.

rake build now depends on rake build_client_app, which builds and verifies the frontend. LOGSTER_SKIP_ASSET_BUILD=1 reuses existing assets but still verifies them. The publish job sets this flag because it builds the frontend before invoking publish-rubygems-action, whose Ruby container has no Node.js. /pkg/ is ignored so building the gem does not trip the release task's clean-tree check.

The backend CI job builds through the new task. Tests cover invalid or incomplete manifests and verify a staged copy of the gemspec's file list, so accidentally excluding required frontend files fails CI.

Validation: 181 Ruby tests pass with no skips; building with LOGSTER_SKIP_ASSET_BUILD=1 succeeds. The extracted gem passes asset verification and the viewer's rendered asset URLs return HTTP 200. Existing CI is green, including the production frontend build.

Extracted from #264

Co-authored-by: Sam Saffron sam.saffron@gmail.com


Stack created with GitHub Stacks CLI • Give Feedback 💬

@davidtaylorhq
davidtaylorhq force-pushed the asset-packaging branch 2 times, most recently from 3417eb6 to 3400369 Compare August 25, 2026 18:23
Base automatically changed from glimmer-gjs to main September 10, 2026 16:46
@davidtaylorhq
davidtaylorhq force-pushed the asset-packaging branch 3 times, most recently from 2042d35 to 74ccc1c Compare September 11, 2026 09:26
The gemspec shipped whatever `git ls-files` returned minus `website` and `bin`, so the published gem carried the client app sources, the test suite, the CI workflows and the gemfiles. It also missed two files it did need. `assets/manifest.json` and `assets/logster-config.json` arrived with the Vite build and are ignored by git, so `git ls-files` never saw them and the globs that pick up the built scripts and stylesheets did not cover them; the next release would have shipped a viewer that died looking for its manifest. The gemspec now lists the runtime files on purpose — `lib`, `vendor`, the images, the three top-level documents — and names the two JSON files outright, so `gem build` refuses to package a release without them.

That catches a missing file but not a stale one, where the manifest names hashes that no longer exist on disk. `FrontendAssets.verify!` covers that: it checks that every file any chunk names is really in `assets/javascript` or `assets/stylesheets`. Everything the build copies lands in one of those two flat directories, so which chunk imports which does not decide where to look, and there is no graph to walk. It does check that the manifest holds together the way the viewer needs, though, since the viewer reads the same file at runtime and raises if it does not: there has to be exactly one entry chunk, every chunk has to name a file, and every chunk an `imports` or `dynamicImports` list names has to be one the manifest describes. `vendor.js` is checked by name, because the build copies it out of `dist/@embroider/virtual` and no chunk mentions it.

Two entry chunks means a development build, where the test bundle is an entry of its own. The viewer renders whichever it finds first, so the check refuses the whole manifest rather than trusting the order. A chunk naming anything under `assets` is refused too: those are the fonts and images a chunk imports, and `build_client_app.sh` copies only scripts and stylesheets, so the build would have to learn to package them first.

`rake build_client_app` builds the assets, or skips the build when `LOGSTER_SKIP_ASSET_BUILD` is set, and verifies them either way. The publish job sets the variable because `discourse/publish-rubygems-action` runs `rake release` inside a `ruby:3` image that has no node, so building there is not an option; the job builds the assets in an earlier step and the release consumes them.

- `rake build` now depends on `build_client_app`, which puts the check in the path of `rake release`. `/pkg/` is ignored so the gem it writes does not leave the tree dirty and trip `release:guard_clean`.
- The gemspec test stages the files that would ship into a temporary directory and verifies those, so a change that quietly stopped packaging the frontend fails instead of passing a list of things it correctly leaves out.
- The backend CI job builds through `rake build_client_app`, so the check meets a real build on every pull request rather than for the first time during a release.

Extracted from #264

Co-authored-by: Sam Saffron <sam.saffron@gmail.com>
@davidtaylorhq
davidtaylorhq marked this pull request as ready for review September 24, 2026 11:27
@davidtaylorhq
davidtaylorhq merged commit 872ddce into main Sep 24, 2026
18 checks passed
@davidtaylorhq
davidtaylorhq deleted the asset-packaging branch September 24, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants