cMail docs

Contributing to cmail

Contributions of code, tests, documentation, accessibility work, security hardening, and deployment experience are welcome. By participating, you agree to the Code of Conduct.

Keep deployments, credentials, customer information, and organisation-specific material out of every contribution โ€” issues, pull requests, commits, and screenshots included.

Before opening an issue

Local setup

git clone https://github.com/Rob142857/cmail.git
cd cmail
corepack enable
pnpm install --frozen-lockfile
pnpm run setup
pnpm db:migrate:local
pnpm dev

Node.js 22.17 or later is required (.nvmrc says 24). Use pnpm dev:worker in a second terminal for the email Worker. The Developer guide covers everything else you are likely to do: running one test, adding a migration or endpoint, changing the Worker or shared package, updating dependencies, common errors, and releasing.

Edit the ignored apps/web/.dev.vars created by pnpm run setup and use development-only credentials. Never reuse production secrets locally or commit .dev.vars, Wrangler tenant configuration, database exports, message content, or logs.

Making a change

  1. Keep the change focused; explain the user or operator problem it solves.
  2. Follow existing TypeScript, Svelte, and SQL patterns.
  3. Keep organisation names, domains, addresses, and deployment IDs configurable.
  4. Treat every request value as untrusted, including values from managers.
  5. Preserve role checks, mailbox-assignment checks, audit events, and safe handling of message HTML and attachments.
  6. For schema changes, keep setup idempotent and document how an existing deployment upgrades.
  7. Update user-facing documentation when configuration or deployment behavior changes.

Validation

Run the checks in the repository:

pnpm lint
pnpm check
pnpm test
pnpm build

Before requesting review, run the combined suite:

pnpm validate

Maintainers preparing a public release or mirror must use the stricter gate, which also scans every reachable Git object without printing matched values:

pnpm release:check

Mobile and accessibility suite

UI changes also run the Playwright suite in e2e/mobile/. It builds the app, serves it with wrangler pages dev over local HTTPS, applies every migration to a throwaway local D1 under .tmp/e2e-mobile/, and seeds invented users and messages (e2e/mobile/seed-data.mjs). Outbound delivery is off, so nothing leaves the machine.

pnpm exec playwright install chromium webkit   # once per machine
pnpm test:mobile                         # Pixel 7, Galaxy S24 (360px), iPhone 14, desktop
pnpm test:mobile:update                  # refresh screenshot baselines after an intended UI change
pnpm test:mobile:report                  # open the HTML report

It checks console errors, sideways scroll at 360/375px, 44px touch targets, keyboard focus, axe-core (serious and critical only), dark mode, the on-screen keyboard, offline behaviour and per-device screenshots (e2e/mobile/__screenshots__/<platform>/<device>/). Known bugs are listed in e2e/mobile/known-bugs.ts and run as expected failures; when you fix one, its test reports "Expected to fail, but passed" and you delete the entry.

Two narrower commands are also available: pnpm secrets:scan checks tracked and untracked files for likely credentials, and pnpm secrets:history runs just the Git-history scan that release:check includes.

Automated coverage is not yet complete. Manually exercise the paths your change affects and describe that verification in the pull request. For mail-flow changes, cover as applicable:

Include a focused regression test with bug fixes when practical. Document any new test tooling and make it runnable from the workspace root.

SQL behaviour (triggers, constraints, ORDER BY) belongs in a test against the real migrations, not a hand-written mock. The web app uses apps/web/src/lib/server/mcp/testing/harness.ts; the email worker uses apps/email-worker/src/testing/sqlite-d1.ts. Both run every migration on in-memory node:sqlite. Email-worker tests that need Node modules are named *.node.test.ts, so the Worker code itself is still type-checked with Workers types only. pnpm test from the root runs them all.

CI runs pnpm release:check on Node 22, 24 and 26, and the axe and smoke specs of the mobile suite on Pixel 7 and desktop Chrome (the screenshot specs are left to pnpm test:mobile). Both must pass before merge. See the Developer guide for single-file test commands and what CI runs.

Pull requests

A useful pull request includes:

Maintainers may ask for a smaller scope or more tests before review. Review does not guarantee a change is safe for every deployment โ€” operators still need to assess their own environment.

Commit hygiene

Use clear, imperative commit messages. Before pushing, inspect the full diff and staged file list:

git diff
git diff --staged

If a secret or private record enters Git, stop. Revoke or rotate it first, then follow an appropriate history-removal process โ€” deleting the current copy does not remove it from Git history.

License

By contributing, you agree your contribution is licensed under the repository's MIT License.

For support and question routing, see SUPPORT.md.