Documentation Index
Fetch the complete documentation index at: https://docs.odds-api.io/llms.txt
Use this file to discover all available pages before exploring further.
PR Test Workflow — Design
Status: Approved Date: 2026-05-06 Owner: MarkusGoal
Run the full test suite for every PR targetingmain and block merging until all checks pass.
Scope
In scope:- Unit tests, typecheck, and lint for all three subprojects (
v3/,account-service/,web/) - A single GitHub Actions workflow gated as a required check on
main - Per-subproject path filters with an aggregator job so branch protection works correctly
- Documentation for the manual branch-protection setup step
- E2E / browser tests (no Playwright/Cypress today)
- Coverage reporting
- Deployment workflows
- Matrix testing across multiple language versions
- Load/stress tests (kept in the codebase but excluded from CI)
Architecture
One workflow file:.github/workflows/pr-tests.yml.
Triggers on pull_request against main. Three independent jobs run in parallel, plus an aggregator.
all-checks) depends on all three with if: always() and a step that fails if any dependency failed. Branch protection requires only all-checks. This solves the GitHub quirk where path-filtered jobs that don’t run register as “skipped” rather than “passed”, which would otherwise block PRs that touched only one subproject.
Job: v3-go
- Path filter:
v3/**,.github/workflows/pr-tests.yml - Setup:
actions/setup-go@v5pinned to1.24(matchesv3/go.mod) - Cache: built into setup-go
- Steps:
gofmt -l .— fail if output is non-emptygo vet ./...go build ./...go test -short -race ./...
Job: account-service
- Path filter:
account-service/**,.github/workflows/pr-tests.yml - Setup:
actions/setup-node@v4(Node 22) +pnpm/action-setup@v4with pnpm cache - Steps:
pnpm install --frozen-lockfilepnpm typecheckpnpm exec biome check .pnpm test
Job: web
- Path filter:
web/**,.github/workflows/pr-tests.yml - Setup: same as account-service
- Steps:
pnpm install --frozen-lockfilepnpm typecheck(new script — see “Required code changes”)pnpm lint(already wired to biome)pnpm testpnpm build(catches Next.js build-time errors not caught bytsc)
Job: all-checks
needs: [v3-go, account-service, web]if: always()- One step that exits non-zero if any of the three results is
failureorcancelled.skippedis treated as success (path filter didn’t match).
Required code changes outside the workflow file
-
Exclude load/stress Go tests from CI. Add
if testing.Short() { t.Skip(...) }guards (or build tags) at the top of:v3/websocket/load_test.gov3/websocket/load_stress_test.gov3/websocket/hub_performance_test.gov3/websocket/replay_benchmark_test.gov3/websocket/throughput_benchmark_test.gov3/websocket/replay_deferred_bench_test.go- Any other file under
v3/that drives heavy concurrency or long timeouts.
Benchmark*funcs) are not run bygo testby default and don’t need guards. -
Add
typecheckscript toweb/package.json: -
Verify vitest tests don’t need live services. Check whether
account-service/routes/webhooks.test.ts,trial.test.ts, andweb/src/app/api/**/*.test.tsconnect to real Mongo, Redis, or Stripe. If any do, the design choice is to mock them rather than spin up service containers in CI (simpler, faster, more reliable). Implementation step will fix any test that fails because it expects a live service.
Branch protection setup (manual step)
GitHub Actions can’t enable required checks itself — it has to be toggled in repo settings. Document in.github/workflows/README.md:
- Repo Settings → Branches → Add rule for
main - Require status checks: select
all-checks - Require branches to be up to date before merging
- Apply rules to administrators (recommended)
Failure modes & handling
| Scenario | Behavior |
|---|---|
| Web-only PR | Only web job runs; v3-go and account-service skip; all-checks passes |
| Test fails | That job fails; all-checks fails; PR blocked |
| Workflow file edited | All three jobs run (workflow path is in every filter) |
| Lockfile out of sync | pnpm install --frozen-lockfile fails fast in install step |
| Cache miss | First run is slow but correct; subsequent runs hit cache |
Testing the workflow
After merge, validate by:- Opening a trivial PR touching only
web/— verifyv3-goandaccount-serviceskip andall-checksstill passes - Opening a PR with a deliberately failing test — verify
all-checksfails and the PR shows as blocked - Opening a PR touching all three subprojects — verify all jobs run