Add interactive per-commit PR preview deployments - #184
Merged
Conversation
# Conflicts: # tests/e2e/smoke.ui.spec.ts
This was referenced Aug 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reviewer summary
This PR turns every same-repository pull request into a public, interactive, credential-free simulator on GitHub Pages. It adapts the proven
leoncheng57.github.ioPR-preview pattern to this repository's browser -> Express BFF -> OpenCode architecture without publishing either backend process.The core review questions are:
gh-pageswithout deleting each other's content?Architecture at a glance
flowchart LR subgraph Local[Private/local production runtime] Browser[Browser SPA] --> BFF[Express BFF] BFF --> OpenCode[opencode serve] BFF --> Host[Git + host filesystem] BFF --> Secrets[Provider and forge credentials] end subgraph Public[Public PR preview] Pages[GitHub Pages] --> PRBundle[PR client bundle] PRBundle --> Simulator[In-browser BFF simulator] Simulator --> Fixture[Deterministic tab-local fixtures] end Public -. no network path .-> BFF Public -. no access .-> OpenCode Public -. no access .-> Host Public -. no secrets .-> SecretsThe preview uses the real PR client bundle. Only
/apibehavior is replaced, before React mounts, byclient/simulator/publicSimulator.ts. Hash routing keeps nested client routes reload-safe underpr-previews/pr-<number>/. The preview build omits the production service worker and PWA manifest.Per-commit deployment flow
Concurrency behavior
Builds are cancellable per PR. Deploys are not cancelled once they begin, because interrupting a shared-branch writer is riskier than briefly publishing an older commit before the queued newest commit replaces it.
Changed file and folder map
Equivalent filesystem view:
BFF simulator stubs
client/simulator/publicSimulator.tsreplacesglobalThis.fetchbefore React mounts. It intercepts only/api/*; document and asset requests continue through native browser fetch. Unknown API method/path pairs return an explicit JSON404rather than a guessed success.Stubbed endpoint families
srcDocRepresentative fixture coverage
Deliberately not stubbed
tests/e2e/mock-opencode.tsandtests/e2e/mock-preview.ts.Trust boundaries
contents: readonly.github/workflows/pr-preview.yml,buildjobdeploy.ifsame-repository checkscripts/pr-preview.ts.git, duplicates, oversized files, or undeclared bytesclean: true,force: false, shared publication lock.env, token, or live transcriptclient/simulator/publicSimulator.tsvite.config.ts,client/main.tsxpr-previews/pr-N,pr-screenshots/pr-N, marker-owned comments, and marks deployments inactiveSuggested review order
.github/workflows/pr-preview.yml, then.github/workflows/cleanup-pr-screenshots.yml.scripts/pr-preview.tsandtests/pr-preview.test.ts.client/main.tsx,client/lib/runtime.ts, thenclient/simulator/publicSimulator.ts.vite.config.ts,client/index.html, stream guards, workspace fixture frame.playwright.preview.config.tsandtests/preview-e2e/public-simulator.spec.ts.Live end-to-end evidence
This PR is the demonstration deployment:
836bf48: build passed; deploy failed because the Pages action required a Git checkout. The deployment failure status and sticky failure comment both worked.fd4e6e5:synchronizeretriggered the pipeline; build, manifest revalidation, Pages publication, URL wait, transient deployment, and sticky link all succeeded.gh-pagestree retained every existingpr-screenshots/*directory and added onlypr-previews/pr-184/*.Deliberate tradeoffs
BrowserRouterURLs.pr-screenshot-publicationfor compatibility with the existing screenshot and pending public-site publishers.Verification
npm run typechecknpm test— 559 passedCI=1 PORT=3510 MOCK_OPENCODE_PORT=4699 MOCK_PREVIEW_PORT=4700 npm run test:e2e— 303 passed, 1 expected screenshot-runner skipnpm run test:previewCI: screenshots
Closes #112
Closes #153
Related: #110, #119