ci: quality-gate floors — ESLint warning ceilings + coverage thresholds#2654
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
|
🟡 Tier 3 — StandardIntroduces new logic, modifies core functionality, or touches areas with non-trivial risk. Why this tier:
Review process: Full human review — logic, architecture, edge cases. Stats
|
Greptile SummaryThis PR introduces two ratchet-style quality gates across all packages: ESLint warning ceilings (via
Confidence Score: 5/5Config-only change that adds quality gates pinned to current measured state — safe to merge with no risk of breaking the build on merge. All eight changed files are package.json scripts and jest config additions. The gates were verified in both directions (pass at current levels, fail on injected regressions) per the PR description. Tradeoffs like omitting collectCoverageFrom are documented and deferred deliberately. No files require special attention. The app/jest.config.js path-scoped thresholds are the most novel part of the change, but they are well-commented and the scoping rationale is sound. Important Files Changed
Reviews (5): Last reviewed commit: "Merge branch 'main' into jordansimonovsk..." | Re-trigger Greptile |
Deep Review✅ No critical issues found. This is a CI-config-only change; the gates are correctly wired ( 🟡 P2 — recommended
🔵 P3 nitpicks (4)
Reviewers (4): correctness, testing, maintainability, project-standards. Testing gaps:
|
E2E Test Results✅ All tests passed • 241 passed • 1 skipped • 836s
Tests ran across 4 shards in parallel. |
Pin Jest coverageThreshold in the unit configs for app, common-utils and hdx-eval to just below each package's measured coverage (measured minus one, rounded down). Coverage can now only ratchet upwards: any decay below these floors fails the build, so the floors rise only when someone raises them deliberately. Also add --coverage to hdx-eval's ci:unit so its threshold is actually collected and enforced. Integration configs are left untouched. The API unit config is deferred to a follow-up until the API unit/int split (#2653) lands.
|
My 2 cents: I don't love coverage requirements on React components. Unit tests on React components can be helpful, but often are not, with other methods (E2E, storybooks) providing more value. Hooks and utils are decent candidates for coverage requirements. Of course with agents we can always just generate tests to hit coverage requirements, but I suspect they'll often be relatively low value and fragile. If the team thinks this is valuable though, happy to get over my hesitations. I love the lint warning ceilings everywhere and the coverage requirements on common-utils in particular (everything there should be very unit-testable). |
Replace the app package's single global coverageThreshold with path-scoped floors on ./src/hooks/ and ./src/utils/ (plus the shared ./src/utils.ts). React components now carry no coverage requirement -- unit tests on them tend to be low-value and fragile, and E2E/Storybook cover them better -- while the ratchet still holds on the genuinely unit-testable code. Jest subtracts the globbed paths from the overall pool, so components are ungated. Floors are pinned one point below measured (hooks/utils sit at 73-77% versus the old 53% global -- the gap was almost entirely components).
@pulpdrew agreed. I've changed this to not take React components into consideration, but I've left in hooks and utils. |
The per-package eslint warning ceilings added in #2654 make any net-new warning a lint failure. Merging main brought the ceilings onto this branch, and the table color tests added 12 warnings that pushed packages/app over its 740 cap. Clear them at the source without touching any ceiling: - replace empty-arrow mock callbacks with jest.fn() - back the jsdom crypto.randomUUID shim with Object.defineProperty instead of an `as any` cast - mock useSource via jest.mocked() to match the existing pattern in the same file - scope one eslint-disable for the deliberately invalid palette token in the unknown-token fallback test Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two ratchet-style quality gates, combined into one PR (they touch different files and share the "this metric can only improve" philosophy).
What changed
lintscript drops--quiet(which made ESLint 9 skip warn-level rules entirely) and adds a--max-warnings <N>ceiling pinned to that package's current count (app 740 / api 357 / common-utils 92 / cli 9 / hdx-eval 3). Warn rules run again and the count can't grow.common-utilsandhdx-evalgain acoverageThreshold.global;appgains thresholds scoped tosrc/hooks/andsrc/utils/only. Each floor is pinned ~1 point below measured, so coverage can only ratchet up.hdx-eval'sci:unitgains--coverageso its floor is collected.Key decisions
packages/apicoverage floor is deferred until the API unit/integration split (ci: faster test feedback — split API tests, parallelise common-utils, shard integration #2653) merges (no APIci:unitbefore then);packages/cliis skipped (single test file).Impact
lintfails when a package exceeds its warning ceiling; the unit job fails when coverage drops below a floor.collectCoverageFrom, so a brand-new fully-untested file doesn't lower a floor — worth a tracked issue (adding it re-baselines all thresholds).Implementation detail
Ceilings and floors were both verified in both directions: they pass at current levels, and an injected regression (a
@ts-ignorefor lint; a temporary threshold bump above measured for coverage) fails as expected. The app's scoped floors were confirmed to enforce per glob — raising./src/hooks/to 99% fails withcoverage threshold for statements (99%) not met: 73.72%, while components stay ungated.