Skip to content

Deploy from CI, plus maintainer and handover docs - #3

Merged
monchee merged 4 commits into
mainfrom
ci-deploy-and-handover
Aug 20, 2026
Merged

Deploy from CI, plus maintainer and handover docs#3
monchee merged 4 commits into
mainfrom
ci-deploy-and-handover

Conversation

@monchee

@monchee monchee commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Why

Production deploys only happen by running npm run deploy locally with personal wrangler credentials. If the current maintainer stops working on this, nobody can ship a corrected drug dose — regardless of who can edit one. That is the binding continuity risk, not editing access.

What

ci: deploy job on push to main, after test and e2e pass.

Guarded by a credential-check step rather than a job-level condition: the secrets context is not available in if: expressions, so the job promotes the token to job-level env and gates the build and deploy steps on a step output. With no CLOUDFLARE_API_TOKEN configured the job succeeds and logs that it skipped, so CI stays green until the token exists.

npm run deploy is retained as the break-glass path.

docs: MAINTAINERS.md + HANDOVER.md — neither repo documented how to run, ship, or inherit this app.

  • MAINTAINERS.md — local setup, test commands, both deploy paths.
  • HANDOVER.md — every account, domain, secret and token; who owns each, whether the app needs it, how to rotate it. Covers the personal dream.yuson.au domain and its pages.dev fallback, Sentry and Supabase (both optional at runtime), and the PasswordGate PIN.

Known issue recorded, not fixed here

supabase/migrations/001_research_submissions.sql grants the anon role INSERT, SELECT and DELETE on all rows — anyone holding the anon key can read or delete every research submission. Documented in HANDOVER.md; worth a separate fix.

Before this can actually deploy

Add CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID as repo secrets. Until then the deploy job is inert by design.

🤖 Generated with Claude Code

Monchee and others added 4 commits August 20, 2026 14:46
Production deploys currently only happen by running `npm run deploy`
locally with personal wrangler credentials, so nobody else can ship a
corrected drug dose. This moves publishing to CI on push to main.

Guarded by a credential-check step rather than a job-level condition:
the secrets context is not available in `if:` expressions, so the job
promotes the token to job-level env and gates the build and deploy
steps on a step output. With no CLOUDFLARE_API_TOKEN configured the job
succeeds and logs that it skipped, so CI stays green until the token
exists.

`npm run deploy` is retained as the break-glass path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Neither repo documented how to run, ship, or inherit this app. Written
for a successor who is not the original author.

MAINTAINERS.md covers local setup, the test commands, and both deploy
paths. HANDOVER.md inventories every account, domain, secret and token,
who owns each, whether the app needs it, and how to rotate it — Cloudflare,
the personal dream.yuson.au domain and its pages.dev fallback, Sentry and
Supabase (both optional at runtime), and the PasswordGate PIN.

Also records, as a known issue to fix separately, that the research
submissions migration grants the anon role INSERT, SELECT and DELETE on
all rows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The e2e job installs dependencies and Playwright, then Playwright starts
`npm run preview` (because CI is set), which serves dist/. Nothing in that
job ever built dist/, so the preview server had nothing to serve and all
59 tests timed out waiting for the app to render.

This has been failing on every release since the job was added, giving
the appearance of e2e coverage without any. It also blocks the new deploy
job, which is gated on `needs: [test, e2e]`.

Reproduced locally: the suite passes with dist/ present and fails
identically to CI with dist/ moved aside.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The TTL expiry test seeds the clock at 2026-07-14T10:00:00+10:00 and
asserts the banner reads "expires at 10:29". The app formats that in
browser-local time, so the assertion only held on a machine set to Sydney
and failed on CI runners, which are UTC — 00:29, exactly ten hours off.

Pinning timezoneId makes every test deterministic regardless of runner
locale, and matches where the app is actually used.

Verified: full chromium suite 59/59 passing with TZ=UTC, up from 0/59
before the missing-build fix and 58/59 after it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@monchee
monchee merged commit 13f5f2b into main Aug 20, 2026
3 checks passed
@monchee
monchee deleted the ci-deploy-and-handover branch August 20, 2026 06:41
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