test(coverage): drive db/cache/nosql local providers to >=95% via sou… #125
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # instant.dev/api — CI | |
| # | |
| # Multi-repo note: go.mod uses `replace instant.dev/proto => ../proto`. The | |
| # "Checkout proto sibling" step clones the proto repo next to this checkout. | |
| # If your GitHub repo is not named `proto`, set the `PROTO_REPO` repository | |
| # variable (e.g. `myorg/instant-proto`) or fork/rename to match | |
| # `${{ github.repository_owner }}/proto`. | |
| name: CI | |
| on: | |
| push: | |
| branches: [master] | |
| # CI-minute savings (2026-05-21): skip CI on docs-only commits. | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - 'CLAUDE.md' | |
| - '.gitignore' | |
| - 'LICENSE' | |
| - 'BUGBASH-*/**' | |
| pull_request: | |
| branches: [master] | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - 'CLAUDE.md' | |
| - '.gitignore' | |
| - 'LICENSE' | |
| - 'BUGBASH-*/**' | |
| schedule: | |
| # Weekly — reserved for optional scheduled jobs (see e2e job). | |
| - cron: '0 6 * * 1' | |
| workflow_dispatch: | |
| concurrency: | |
| # CI-minute savings (2026-05-21): cancel prior in-flight CI run for the | |
| # same branch/PR when a new commit lands. Different PRs/branches still | |
| # run in parallel (group key includes github.ref). | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Stale-green guard. A PR can show a green CI run that was executed BEFORE a | |
| # breaking commit landed on the base branch — merging it would ship a broken | |
| # master. This job FAILS if the PR branch does not contain origin/<base> as | |
| # an ancestor, forcing an "Update branch" before the PR can merge. | |
| up-to-date-with-base: | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fail if PR branch is behind its base branch | |
| run: | | |
| BASE="${{ github.event.pull_request.base.ref }}" | |
| git fetch origin "${BASE}" --depth=1 | |
| if git merge-base --is-ancestor "origin/${BASE}" HEAD; then | |
| echo "PR branch contains origin/${BASE} — up to date." | |
| else | |
| echo "::error::PR branch is behind origin/${BASE}. Update the branch (merge/rebase ${BASE}) and re-run CI so it validates against current base." | |
| exit 1 | |
| fi | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: instant_dev_test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| env: | |
| TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/instant_dev_test?sslmode=disable | |
| TEST_REDIS_URL: redis://localhost:6379/15 | |
| # db-provider admin target. internal/providers/db/local.go CREATEs a | |
| # customer database per /db/new; in tests it connects to | |
| # TEST_POSTGRES_CUSTOMERS_URL. testhelpers defaults this to an | |
| # unreachable localhost:5434, so without this every postgres- | |
| # provisioning test (TestDBNew_*, TestBulkTwin_*) 503'd. Points at an | |
| # instant_customers DB created on the same service container below — | |
| # exactly as deploy.yml's proven-green gate does. | |
| TEST_POSTGRES_CUSTOMERS_URL: postgres://postgres:postgres@localhost:5432/instant_customers?sslmode=disable | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Checkout proto sibling (for go.mod replace ../proto) | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ vars.PROTO_REPO || format('{0}/proto', github.repository_owner) }} | |
| token: ${{ secrets.REPO_ACCESS_TOKEN }} | |
| path: _proto_ci | |
| - name: Place ../proto for Go replace directive | |
| run: mv _proto_ci ../proto | |
| - name: Checkout common sibling (for go.mod replace ../common) | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ vars.COMMON_REPO || format('{0}/common', github.repository_owner) }} | |
| token: ${{ secrets.REPO_ACCESS_TOKEN }} | |
| path: _common_ci | |
| - name: Place ../common for Go replace directive | |
| run: mv _common_ci ../common | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.25' | |
| - name: Apply DB migrations to the test database | |
| # Mirrors deploy.yml's proven-green gate. Before this step CI ran | |
| # tests against a BARE Postgres whose schema came ONLY from | |
| # testhelpers.runMigrations — a hand-maintained mirror. This step | |
| # applies the REAL migration files (exactly like `make test-db-up`), | |
| # then creates instant_customers — the db provider's local backend | |
| # (internal/providers/db/local.go) CREATEs a customer database per | |
| # /db/new and connects to TEST_POSTGRES_CUSTOMERS_URL for it. Without | |
| # this DB every postgres provision (TestDBNew_*, TestBulkTwin_*) 503'd. | |
| env: | |
| PGPASSWORD: postgres | |
| run: | | |
| for f in $(ls internal/db/migrations/*.sql | sort); do | |
| echo "→ applying $(basename "$f")" | |
| psql -h localhost -U postgres -d instant_dev_test -f "$f" >/dev/null | |
| done | |
| echo "all migrations applied to instant_dev_test" | |
| psql -h localhost -U postgres -d postgres -c "CREATE DATABASE instant_customers" >/dev/null | |
| echo "created instant_customers (db-provider admin target)" | |
| - run: go build ./... | |
| - run: go vet ./... | |
| # The gate. This MUST stay equal to deploy.yml's proven-green | |
| # invocation (`go test ./... -short -count=1 -p 1`) PLUS `-race`: | |
| # - `-p 1` is load-bearing: every package shares the single | |
| # instant_dev_test DB + redis/15. Default parallelism runs ~25 | |
| # package binaries at once and they corrupt each other's DB/redis | |
| # state mid-test. `-p 1` serialises package execution. | |
| # - `-short` matches deploy.yml so the two gates run the identical | |
| # hermetic suite (tests that genuinely need a live k8s/provisioner | |
| # stack are tagged `e2e` and excluded from `./...` anyway). | |
| # - `-race` is the extra rigor CI adds over deploy.yml — it caught | |
| # the BillingHandler.ensureRazorpayFns data race. | |
| - run: go test ./... -short -race -count=1 -p 1 | |
| # E2E requires a live Kubernetes stack (see repo CLAUDE.md). This job does not | |
| # run on push/PR — only on schedule or manual dispatch — so default CI stays fast. | |
| e2e: | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Checkout proto sibling | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ vars.PROTO_REPO || format('{0}/proto', github.repository_owner) }} | |
| token: ${{ secrets.REPO_ACCESS_TOKEN }} | |
| path: _proto_ci | |
| - run: mv _proto_ci ../proto | |
| - name: Checkout common sibling | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ vars.COMMON_REPO || format('{0}/common', github.repository_owner) }} | |
| token: ${{ secrets.REPO_ACCESS_TOKEN }} | |
| path: _common_ci | |
| - run: mv _common_ci ../common | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.25' | |
| - name: E2E placeholder (wire to k8s / secrets) | |
| run: | | |
| echo "Configure services, secrets, and port-forwards, then run e.g.:" | |
| echo " go test ./e2e/... -tags e2e -count=1 -timeout 180s" | |
| echo "See CLAUDE.md (Full-stack E2E) for required env vars." |