Skip to content

Latest commit

 

History

History
165 lines (119 loc) · 6.11 KB

File metadata and controls

165 lines (119 loc) · 6.11 KB

Contributing

Setup

Node 22 or later.

npm install

The repository uses npm workspaces. Install once at the root; do not install inside a workspace.

Two packages have install scripts that fetch platform binaries, esbuild and workerd. They are approved explicitly in the root package.json under allowScripts, so a new dependency that wants to run install scripts has to be approved deliberately.

Running the API

npm run dev

This starts wrangler dev on http://localhost:8787 with the same bindings as production, including the rate limiter.

curl 'http://localhost:8787/v1/roll?formula=4d6kh3'
curl 'http://localhost:8787/openapi.json'

Running the site

npm run dev --workspace @rollful/site

Astro serves on http://localhost:4321. The documentation is grouped by what each page is, after Diátaxis: a lesson under Start here, a recipe under Guides, a description under Reference, and a discussion under Explanation. A page belongs to exactly one of those, and the sidebar group follows from the directory it sits in.

Two routes are fixed rather than free. /docs/ and /docs/api/ are the two tutorials, because the site header, the marketing page, the 404 page and the Worker's own index all link them. The generated endpoint reference stays under /docs/api/endpoints and is listed under Reference regardless of that route.

Moving a page means adding its old address to redirects in astro.config.mjs. A published link should not break because the shelving changed.

The reference builds from the committed document, so it always describes this checkout. The home page roller calls the real API, and by default that is production. To point it at a local Worker, copy apps/site/.env.example to apps/site/.env and run both:

npm run dev --workspace @rollful/api
npm run dev --workspace @rollful/site

.env is not committed.

Checks

npm run typecheck
npm test
npm run format:check

npm run typecheck regenerates apps/api/worker-configuration.d.ts with wrangler types before compiling, so binding types always match wrangler.jsonc. That file is generated and is not committed.

Tests

Tests run inside workerd through @cloudflare/vitest-pool-workers, not in Node. This is deliberate: the API's whole premise is that OpenDice needs no Node compatibility layer, and a test running in Node would not prove it.

npm test --workspace @rollful/api
cd apps/api && npx vitest    # watch mode

Tests drive the Worker over HTTP through SELF, so middleware, validation, error mapping and CORS are all covered rather than bypassed. Each request sends its own cf-connecting-ip, because the rate limiter is real in local tests too and a shared address would make one test spend another's budget.

Read limits from @rollful/schema in tests rather than repeating the numbers.

The site's test is not one of those. It runs in Node and checks a single thing: that the version beside the wordmark is the OpenDice version the lockfile installs. Nothing in the dependency graph holds those two together — the site does not depend on opendice, the API does — so a release that bumped the package and forgot the site would go out announcing a version nobody is running.

Style

Prettier settings are in .prettierrc.json: no semicolons, single quotes, 100 columns.

npm run format

Prose is neutral and direct, readable at high school level. Comments are kept to a minimum; code should explain itself, and a comment is only worth adding where the code cannot express the point.

Every source file starts with the SPDX header:

// SPDX-License-Identifier: MIT
// Copyright (C) 2026 Nicola Mustone

Deploying

Pushes to main deploy through GitHub Actions: the API when apps/api or packages/schema change, the site when apps/site or packages/schema change. Both need the same two repository secrets:

Secret Value
CLOUDFLARE_API_TOKEN a token created from the Edit Cloudflare Workers template
CLOUDFLARE_ACCOUNT_ID the account owning rollful.dev, from npx wrangler whoami

To deploy by hand:

npm run deploy                            # the API
npm run deploy --workspace @rollful/site  # the site

Both rollful.dev and api.rollful.dev are Worker Custom Domains. The site is a Worker with an assets binding and no main, so it serves static files and runs no code of its own.

Cloudflare creates the DNS record and issues the certificate on the first deploy, so there is no DNS record to add by hand and none to keep in step afterwards. Do not edit those records in the dashboard. The rollful.dev zone must already exist in the account.

Letting CI check its own deploy

Both workflows fetch the deployed URL afterwards to prove it answers. Cloudflare's bot protection replies to GitHub's runners with a managed challenge, so that fetch gets an interstitial rather than the site. The workflows treat a challenge as a warning rather than a failure, because a challenge says nothing about whether the deploy worked — which leaves the deploy unverified.

To get a real check back, add a WAF custom rule on the zone that skips bot protection for requests carrying a header only the workflows send:

Expression http.request.headers["x-rollful-deploy-check"][0] eq "<secret>"
Action Skip → Bot Fight Mode, and any other rule that would challenge

Then store the same value as the DEPLOY_CHECK_TOKEN repository secret. Use a secret rather than matching a user agent: a rule anyone can satisfy by setting a header they can guess is a hole in the bot protection, not an exception for CI.

Changes

Add an entry to CHANGELOG.md under Unreleased for anything that changes the API's behaviour, its limits, or its response shapes.