ReviewOS

stacks/bench-review

ops: benchreview.org is not deployed — APP_URL unset, artifact carries 17,930 loopback URLs

#85
Open glennmichael123 opened this 9 days ago ·
9 days ago

Part of #79, and a web blocker in its own right.

Problem

benchreview.org is not deployed, and the mobile app's server is fixed at build time — there is no runtime setting. config/mobile.ts defaults to:

url: envVars.MOBILE_URL ?? 'https://benchreview.org'

so every non-bundled build today produces an app that cannot reach its server and runs permanently on its offline bundle. Only the MOBILE_E2E=1 fully-bundled build is honest right now.

The web artifact has the matching problem. APP_URL is unset, and the conformance gate reports it on every run:

✓ build host is declared (APP_URL)
    APP_URL unset — artifact carries 17930 loopback URLs and is NOT deployable.
    Local preview only; set APP_URL to build for deploy.

17,930 localhost URLs across 3,593 pages. The gate deliberately passes this as a warning rather than failing, because local builds are legitimate — but it means no build produced so far is deployable.

Blocks

  • Universal links (#80) — the association file has to be served from the real origin over https, with no redirect
  • Device builds (#82) — a phone cannot reach this Mac's localhost, so device testing needs a real origin or a tunnel
  • Any demo build that is not fully bundled

What to do

  • Pick the deploy target (the earlier decision was explicitly "not decided yet")
  • Set APP_URL=https://benchreview.org for release builds and confirm the gate's loopback count drops to 0
  • Serve dist/ plus the API (per the deploy model: prod is the pre-rendered artifact + API; stx is build-time only, so no publish step)
  • TLS and the apex/www decision, since trustedOrigins and associatedDomains in config/mobile.ts name the apex exactly
  • Set MOBILE_URL in CI for mobile builds
  • Re-run bun run gate and bun scripts/smoke-deployment.ts

Related: #55 (ops — backups, photo storage, SMTP, alerting) covers what has to be true of the host once it exists.

8 days ago

Deploy prep — the repo-side work is done. Two bugs found doing it, both of which would have hit a real deploy runner.

Nothing here picks a host; that decision is still yours. What changed is that the things which would have gone wrong after you pick one no longer will.

config/cloud.ts was a loaded gun. It declared stacksjs.org as the root site plus docs., tlsx., dtsx. and spreadsheets. subdomains over an AWS serverless driver, pointing at paths like ../../tlsx/docs/dist that do not exist here. ./buddy deploy reads that file. sites is now empty, so it has nothing to act on rather than aiming at domains bench does not own. Not rewritten, because the host is not chosen and inventing one would be worse (32d07255).

Mail would have gone out from a domain you do not control. config/email.ts fell back to no-reply@stacksjs.org, name "Stacks". A deploy that forgot MAIL_FROM_ADDRESS would have sent every verification and password-reset mail claiming to be from someone else's domain — failing SPF/DKIM, landing in spam. Fallbacks are bench's own now. (Your local .env still reads no-reply@benchreview.com; .env.example is already correct.)

The conformance gate now runs in CI (43dcd02f), against the artifact the Build step produced. It is the only check that reads the output — lint, typecheck and unit tests all read the source. It immediately earned its place by finding two things:

1. The gate crashed on a runner. MySQLError: Failed to connect. A runner has no .env, so DB_CONNECTION is unset and config/database.ts defaults to mysql. Three checks read the database, and the driver's failure surfaced from its own connection teardown — an unhandled rejection that killed the process rather than failing a check. It now decides up front whether a database is reachable and never opens one it cannot serve; unreachable is reported on a preview build and fails a release build (f34787c9).

That also corrected a wrong assumption of mine: "is this a release build" is not "APP_URL is set". The local .env sets it to http://localhost:4000, so a bare truthiness test calls every local run a release. It is now the same non-loopback test check 10 already used.

2. A database-less build shipped a sitemap advertising the admin panel. This is the one that matters. buildSitemapXml queried the database first, so an unreachable one threw before a single static path was written; build.ts caught it, logged "sitemap/robots generation skipped", and the stock page-derived sitemap that buildApp() emits survived — listing /admin/users, /admin/reviews, /admin/comments, /settings, /profile, /my-reviews, /notifications, /reset-password. Every one of those is Disallowed in robots.txt. The build reported success.

That is not a CI artifact: a deploy runner that cannot reach the database produces exactly this. The entity queries fail soft now, so the static-page sitemap is always written and the stock one can never survive (58980566). Verified both ways — 14 URLs with no database and none contradicting the 13 Disallow rules; 2,956 with one.

CI is green with all 22 checks running.

DEPLOY.md records the DB_CONNECTION trap, marks the cloud-config and mail-from items done, and states what running the gate with a production APP_URL changes: four checks move from reporting to failing, which is the line between "fine for preview" and "fit to deploy".

Still yours: pick the host, set APP_URL and DB_CONNECTION/DB_* on the build runner, configure SMTP, and decide apex vs www (config/mobile.ts names the apex exactly).

Sign in to comment on this issue.