refactor(api): unify test coverage under one Vitest projects config#515
Open
mrivas00 wants to merge 3 commits into
Open
refactor(api): unify test coverage under one Vitest projects config#515mrivas00 wants to merge 3 commits into
mrivas00 wants to merge 3 commits into
Conversation
3f64ee6 to
ee51f76
Compare
nivek0o0
reviewed
Jul 15, 2026
ce69459 to
55b3a15
Compare
Replace the three separate configs (vitest.base.config.ts, vitest.storage.config.ts, and the per-leg STORAGE_PROVIDER shell env) with a single vitest.config.ts declaring three test.projects: base, storage-azure, storage-minio. Coverage moves to the root config so Vitest merges it across projects natively. globalSetup selects the storage provider from the project NAME (not process.env, which would be last-writer-wins across projects in a single run); the base project boots no storage container. Each project declares its provider in test.env so buildStorageConfig() passes in the worker, and the dynamic testcontainer endpoint (known only at runtime) is applied from the injected descriptor in createTestApp before app.ready(), so the storage + relay plugins read the real endpoint. Net effect: `vitest run --coverage` exercises the whole suite in one command while keeping azure/minio isolated.
Each CI leg runs `vitest run --project=<leg> --reporter=blob`, and the coverage job merges the blobs with `vitest run --merge-reports --coverage`, applying the gate (90% lines/statements/functions/branches) by flag. Removes scripts/check-coverage.mjs (and its istanbul-lib-coverage dependency) and the COVERAGE_DIR indirection, so local (`pnpm test:api`) and CI share one config and one gate. The blob reports live in the dotfile dir `.vitest-reports`, so the upload step sets `include-hidden-files: true` — otherwise upload-artifact silently skips the hidden dir and the coverage job's download finds nothing. `coverage-artifacts` stays in .gitignore alongside `.vitest-reports`. Branch-protection check names are unchanged (Test (base), Test (storage-azure), Test (storage-minio), Coverage); only the artifact names change (coverage-report-* -> blob-report-*), which are not protected checks.
Update the CI/CD, testing, file-storage, and OpenSSF badge docs for the single projects config and native coverage merge (per-leg blob reports merged by `vitest --merge-reports`, no external script), and correct the stale notes that claimed the API coverage gate was disabled — the merged gate (90% for all four metrics) is enforced locally and in CI.
55b3a15 to
5a70011
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
apps/apicoverage was produced by running three separate Vitest configs (base + one per storage provider) and merging their reports with an external script (scripts/check-coverage.mjs). This folds all three into a singlevitest.config.tswithtest.projects, so Vitest merges coverage natively and the external script goes away.pnpm test:api→vitest run --coverageruns all three projects, merges coverage, and applies the gate. One command, no script.--reporter=blob; thecoveragejob merges the blobs withvitest run --merge-reports --coverageand applies the gate.Removed:
scripts/check-coverage.mjs, theistanbul-lib-coveragedev-dep, theCOVERAGE_DIRindirection, andvitest.base.config.ts/vitest.storage.config.ts.Key change (the one bit of real logic)
globalSetupnow selects the storage provider from the project name rather thanprocess.env— a sharedprocess.env.STORAGE_PROVIDERis last-writer-wins once the three projects run in one command. Thebaseproject boots no storage container. Each project declares its provider intest.envfor boot validation, and the dynamic MinIO testcontainer endpoint (only known at runtime) is applied from the injectedstorageDescriptorincreateTestAppbeforeapp.ready(), so the storage + storage-relay plugins reach the real endpoint.Gate
Unchanged in intent — 90% lines/statements/functions, 85% branches — now passed by flag (identical local and CI) instead of hardcoded in the script. Rebased onto
mainso it carries the current gate and its supporting tests.Compatibility
Branch-protection check names are unchanged:
Test (base),Test (storage-azure),Test (storage-minio),Coverage. Only the artifact names change (coverage-report-*→blob-report-*), which are not protected checks.Verification (run locally with Docker)
pnpm test:api(all three projects, one run, merged): 208 files / 2073 tests pass, coverage 92.1% stmts · 86.59% branch · 93.39% funcs · 92.42% lines → clears the 90/85 gate. Exit 0.baseboots no storage container; the storage-relay tests pass against the real MinIO endpoint.pnpm format:check,pnpm lint,pnpm type-check, andpnpm install --frozen-lockfileall green.🤖 Generated with Claude Code