Five parallel jobs run on every PR. Unit tests run in 3 seconds with no setup. The full integration suite spawns wrangler dev and uses a real Google Maps key from CI secrets — or falls back to a deterministic stub for fork PRs that can't access secrets. Results stream into a single sticky PR comment.
wrangler dev on port 8787, seeds R2 via miniflare, hits HTTP endpoints.
Bot search, fulfillment, driver/dispatch endpoints, invoice import (12 tests).
Uses real Google Maps key if available, stub otherwise.
test-results.json artifact, parses pass/fail counts,
and posts (or updates) a sticky comment via marocchino/sticky-pull-request-comment@v2.
GOOGLE_MAPS_API_KEY. Value: your Google Cloud Geocoding API key.
comment-pr finishes.
GOOGLE_MAPS_API_KEY is empty, the workflow flips to GEOCODE_STUB=true
and runs a deterministic hash-based geocoder. Same parsing/routing/branch-grouping logic is
validated either way; only the live Google API call differs.
When checks fail, the same comment is updated in place — never appended — so your PR thread stays clean. Click "Run details" to dive into a specific failure.
| Trigger | Branch | Behavior |
|---|---|---|
pull_request | any → main/develop | All 5 jobs run. Comment posts to PR. |
push | main / develop | 4 test jobs run. No comment (no PR target). |
workflow_dispatch | any | Manual trigger from Actions tab. Same as push. |
This is the bit that wires the secret. The integration job composes a fresh
.dev.vars on every run, choosing geocoding mode based on whether the secret is set:
# From .github/workflows/test.yml · worker-tests job - name: Create test .dev.vars env: GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} run: | { echo "JWT_SECRET=ci-test-secret-not-for-production-use" echo "CRON_TRIGGER_TOKEN=ci-test-cron-token" echo "STRIPE_SECRET=sk_test_ci_placeholder" if [ -n "$GOOGLE_MAPS_API_KEY" ]; then echo "GOOGLE_MAPS_API_KEY=$GOOGLE_MAPS_API_KEY" else echo "GEOCODE_STUB=true" fi } > .dev.vars
.dev.vars is in .gitignore — secrets never land in the repo. The
file is created fresh each CI run and discarded when the runner shuts down.
Each job uses actions/setup-node@v4 with cache: 'npm'. First run on a
branch hits npm registry (~20s); subsequent runs restore from cache (~3s). Worker job
caches worker/package-lock.json; the app jobs cache their own.
✅ All checks passed
abc1234· Run details