ci: add global-install smoke test for CLI preview#455
Conversation
jrusso1020
left a comment
There was a problem hiding this comment.
Verdict: approve
Exactly what we discussed — reproduces Teodora's user-flow in CI. npm pack → npm i -g --prefix /tmp/hf-smoke → init blank → hyperframes preview → probe /api/runtime.js for non-empty body, then grep stderr for ✘ \[ERROR\]|Failed to load runtime. The grep pattern was validated against the pre-#452 broken state (both substrings present in stderr) and passes on fixed code, so the alarm is load-bearing, not decorative. --prefix /tmp/hf-smoke + PATH=/tmp/hf-smoke/bin:$PATH sidesteps sudo cleanly.
The .github/workflows/** addition to changes.code is a quiet quality-of-life fix — without it, CI wouldn't rerun when the workflow itself changed. Good catch.
Plumbing is sound: needs: [changes, build] for gating, 10-minute timeout, 15-second server-readiness poll, background server kill + wait for clean teardown, grep -qE with raw unicode ✘ (which works because run shell is UTF-8 by default on ubuntu-latest). Smoke job itself clocks ~50s on this run — cheap. Smoke: global install is already green on the head commit.
Two non-blockers:
-
Port 3099 is also used by regression tests. On dedicated ubuntu-latest it doesn't collide, but if someone ever runs this job on a self-hosted runner alongside regression, you'd want an env-var override or a random-port probe. Not worth complicating now.
-
npx hyperframespath isn't covered. The reported bug hit both global and npx — same resolution, different path layout under~/.npm/_npx/<hash>/node_modules/. A follow-up variant job (or a matrix) that doesnpm_config_cache=$(mktemp -d) npx hyperframes@file:./packages/cli/... init ...would close the other half of the repro. Non-blocking since #452 fixes both paths with the same guard, and the grep pattern would trigger equivalently for either.
Two housekeeping asks when you merge: (a) tick the last checkbox in the test plan once this lands (CI green on this branch is the evidence), and (b) flip Smoke: global install to a required status check in branch protection so future regressions actually block merge — the test only protects if it gates.
Ship it.
Review by hyperframes
Reproduces the exact failure from #452 where `hyperframes preview` crashed with esbuild runtime errors after `npm i -g` installation. The job packs the CLI tarball, installs it globally via --prefix, scaffolds a blank project, starts the preview server, probes /api/runtime.js for a non-empty response, and asserts stderr contains no esbuild `[ERROR]` or `Failed to load runtime` messages. Runs after the build job passes and only when packages/ changes are detected.
Without this, CI jobs skip when only .github/workflows/ files change, making it impossible to validate new CI jobs on their own PRs.
498f35b to
1355a0a
Compare
0d16a18
into
fix/harden-core-runtime-resolution
* fix(core): guard buildHyperframesRuntimeScript against missing entry.ts buildHyperframesRuntimeScript() now checks existsSync(entryPath) before calling esbuild.buildSync(). When entry.ts doesn't exist (bundled or published contexts where only dist/ ships), it returns null instead of letting esbuild fail with stderr output. This prevents any future consumer that bundles @hyperframes/core from rediscovering the "esbuild can't find entry.ts" bug. Updated loadHyperframeRuntimeSource() and all call-site test scripts to handle the nullable return type. * feat(core): add getHyperframeRuntimeScript() inlined constant The build script now generates src/generated/runtime-inline.ts during build:hyperframes-runtime, containing the IIFE as a string constant. tsc then compiles it into dist/generated/runtime-inline.js. getHyperframeRuntimeScript() is the production-safe path: no esbuild, no file I/O, no import.meta.url arithmetic. It is exported from the @hyperframes/core package index. Build order changed from "tsc && build:hyperframes-runtime" to "build:hyperframes-runtime && tsc" so the generated file exists before tsc runs. * fix(cli): use inlined runtime constant as production fallback loadRuntimeSource() now has three resolution strategies: 1. esbuild from source (dev only) 2. Inlined constant via getHyperframeRuntimeScript() (production) 3. Pre-built IIFE artifact file (final fallback) The inlined constant path avoids file I/O entirely, making runtime resolution work reliably in bundled/published contexts. * ci: add global-install smoke test for CLI preview (#455) ## Summary Adds a CI smoke test that reproduces the exact failure from #452 — `hyperframes preview` printing `✘ [ERROR] Could not resolve "…/runtime/entry.ts"` when installed globally via npm. The job simulates what a real user does: 1. `npm pack` the CLI → install globally with `--prefix` 2. `hyperframes init test-project --example blank` 3. `hyperframes preview --port 3099` in background 4. `curl http://localhost:3099/api/runtime.js` — assert non-empty JS 5. Assert stderr has no `✘ [ERROR]` or `Failed to load runtime` Also adds `.github/workflows/**` to the change detection filter so CI jobs run when workflow files change. ## Validation: the test catches the broken state Verified locally that the grep pattern fires on the pre-#452 code and passes on the fixed code: **Broken (0.4.15-alpha.1, globally installed via `npm i -g hyperframes@alpha`):** ``` $ hyperframes preview --port 3098 2>/tmp/hf-stderr.log $ grep -E '✘ \[ERROR\]|Failed to load runtime' /tmp/hf-stderr.log ✘ [ERROR] Could not resolve "/opt/homebrew/lib/node_modules/hyperframes/runtime/entry.ts" [studio] Failed to load runtime source fallback: Error: Build failed with 1 error: … → CAUGHT: assertion fires, test fails ✓ ``` **Fixed (built from #452 fix branch):** ``` $ node packages/cli/dist/cli.js preview --port 3098 2>/tmp/hf-stderr.log $ grep -E '✘ \[ERROR\]|Failed to load runtime' /tmp/hf-stderr.log (empty) → PASS: no errors ✓ ``` If this smoke test had existed before #452, it would have caught the bug before it shipped. ## Test plan - [x] Grep pattern catches broken state — verified locally against pre-#452 global install - [x] Fixed state passes — verified locally against #452-fixed build - [x] CI job runs green — https://github.com/heygen-com/hyperframes/actions/runs/24854025990/job/72762086753
Summary
Adds a CI smoke test that reproduces the exact failure from #452 —
hyperframes previewprinting✘ [ERROR] Could not resolve "…/runtime/entry.ts"when installed globally via npm.The job simulates what a real user does:
npm packthe CLI → install globally with--prefixhyperframes init test-project --example blankhyperframes preview --port 3099in backgroundcurl http://localhost:3099/api/runtime.js— assert non-empty JS✘ [ERROR]orFailed to load runtimeAlso adds
.github/workflows/**to the change detection filter so CI jobs run when workflow files change.Validation: the test catches the broken state
Verified locally that the grep pattern fires on the pre-#452 code and passes on the fixed code:
Broken (0.4.15-alpha.1, globally installed via
npm i -g hyperframes@alpha):Fixed (built from #452 fix branch):
If this smoke test had existed before #452, it would have caught the bug before it shipped.
Test plan