From 83a96ef13db55527213d6254b0ab39a11d53d84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Sat, 16 May 2026 19:11:48 +0800 Subject: [PATCH] Keep pre-push fast by moving coverage out of the hook Daily pushes should catch policy and path-aware local failures without making every contributor wait for full coverage. The hook now runs a new quality:push entrypoint that reuses the PR quality gate while skipping coverage; verify, quality:pr, and CI still retain the full coverage gate for PR readiness. Constraint: Forks and local contributors need a faster default push path Rejected: Remove coverage from quality:pr | PR readiness and CI still need the ratcheted coverage signal Confidence: high Scope-risk: narrow Directive: Keep pre-push on quality:push; use verify or quality:pr when coverage evidence is required Tested: bun test scripts/pr/quality-contract.test.ts scripts/git-hooks/install.test.ts Tested: bun run check:policy Tested: bun run quality:push Not-tested: Live provider smoke; intentionally remains opt-in --- CONTRIBUTING.md | 2 +- docs/en/guide/contributing.md | 4 ++-- docs/guide/contributing.md | 4 ++-- package.json | 1 + scripts/git-hooks/install.ts | 3 ++- scripts/git-hooks/pre-push | 4 ++-- scripts/pr/quality-contract.test.ts | 7 +++++++ 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f32e045..23fb5697 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,7 +54,7 @@ explicitly requested it. bun run hooks:install ``` -安装后,每次 push 都会先运行同一套验证入口(内部是 `bun run quality:pr`,等价于 `bun run verify`),失败则 push 中止。维护者机器可以把真实模型/桌面 smoke 也纳入 pre-push: +安装后,每次 push 都会先运行快速本地门禁(内部是 `bun run quality:push`)。它复用 PR gate 的 impact/policy/路径检查,但默认跳过耗时的 coverage lane;完整覆盖率仍保留在 `bun run verify`、`bun run quality:pr` 和 CI。维护者机器可以把真实模型/桌面 smoke 也纳入 pre-push: ```bash bun run quality:providers diff --git a/docs/en/guide/contributing.md b/docs/en/guide/contributing.md index d8ce3217..b6fd7d5b 100644 --- a/docs/en/guide/contributing.md +++ b/docs/en/guide/contributing.md @@ -97,7 +97,7 @@ Git hooks are local, so each clone needs to install the hook once: bun run hooks:install ``` -After installation, every `git push` runs the same verification entrypoint internally (`bun run quality:pr`, equivalent to `bun run verify`). If unit tests, coverage, docs/native/adapter checks, or any other selected path-aware lane fails, the local hook blocks the push. +After installation, every `git push` runs the fast local gate internally (`bun run quality:push`). It reuses the PR gate impact, policy, and path-aware checks, but skips the expensive coverage lane by default; full coverage remains in `bun run verify`, `bun run quality:pr`, and CI. If unit tests, docs/native/adapter checks, or any other selected fast path-aware lane fails, the local hook blocks the push. Maintainers or contributors with model quota can also add real provider smoke and desktop agent-browser smoke to the pre-push hook: @@ -114,7 +114,7 @@ bun run hooks:install -- --live-provider-model minimax:main:minimax-main --live- These options are stored in local `.git/config` as `quality.prePush*` keys, so provider selectors and secrets are not committed. `smoke` mode covers real provider connectivity plus the desktop UI chat smoke; `baseline` mode also runs every real Coding Agent baseline case. -Maintainer-level overrides must also be explicit local config before the hook passes them to `quality:pr`: +Maintainer-level overrides must also be explicit local config before the hook passes them to `quality:push`: ```bash bun run hooks:install -- --allow-cli-core-change --allow-coverage-baseline-change diff --git a/docs/guide/contributing.md b/docs/guide/contributing.md index 38cb2d7a..68f26811 100644 --- a/docs/guide/contributing.md +++ b/docs/guide/contributing.md @@ -97,7 +97,7 @@ Git hook 不能提交到远端自动生效,所以每个 clone 需要安装一 bun run hooks:install ``` -安装后,每次 `git push` 都会先运行同一套验证入口(内部是 `bun run quality:pr`,等价于 `bun run verify`)。如果单元测试、覆盖率、文档/native/adapter 等按路径选中的门禁失败,push 会被本机 hook 阻断。 +安装后,每次 `git push` 都会先运行快速本地门禁(内部是 `bun run quality:push`)。它复用 PR gate 的 impact/policy/路径检查,但默认跳过耗时的 coverage lane;完整覆盖率仍保留在 `bun run verify`、`bun run quality:pr` 和 CI。如果单元测试、文档/native/adapter 等按路径选中的快速门禁失败,push 会被本机 hook 阻断。 维护者或有模型额度的贡献者可以把真实 provider smoke 和桌面 agent-browser smoke 也纳入 push 前门禁: @@ -114,7 +114,7 @@ bun run hooks:install -- --live-provider-model minimax:main:minimax-main --live- 这些选项写入本机 `.git/config` 的 `quality.prePush*` 配置,不会提交 provider selector 或密钥。`smoke` 模式覆盖真实 provider 连通性和桌面 UI 聊天 smoke;`baseline` 模式会额外跑全部真实 Coding Agent baseline case。 -维护者级 override 也必须显式写入本机配置,hook 才会传给 `quality:pr`: +维护者级 override 也必须显式写入本机配置,hook 才会传给 `quality:push`: ```bash bun run hooks:install -- --allow-cli-core-change --allow-coverage-baseline-change diff --git a/package.json b/package.json index 66ed1fa9..40e583fb 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "quality:verify": "bun run quality:pr", "quality:providers": "bun run scripts/quality-gate/providers.ts", "quality:pr": "bun run quality:gate --mode pr", + "quality:push": "bun run quality:gate --mode pr --skip coverage", "quality:baseline": "bun run quality:gate --mode baseline", "quality:release": "bun run quality:gate --mode release", "quality:smoke": "bun run quality:gate --mode baseline --allow-live --only 'provider-smoke:*' --only 'desktop-smoke:*'", diff --git a/scripts/git-hooks/install.ts b/scripts/git-hooks/install.ts index 50cc2f79..577e2586 100755 --- a/scripts/git-hooks/install.ts +++ b/scripts/git-hooks/install.ts @@ -196,7 +196,8 @@ if (import.meta.main) { }) console.log(`Installed pre-push quality gate: ${result.hookPath}`) - console.log('Every git push now runs: bun run quality:pr') + console.log('Every git push now runs: bun run quality:push') + console.log('Coverage remains in bun run verify, quality:pr, and CI.') if (args.liveProviderModels.length > 0) { console.log(`Live ${args.liveMode ?? 'smoke'} gate is enabled for ${args.liveProviderModels.length} provider selector(s).`) diff --git a/scripts/git-hooks/pre-push b/scripts/git-hooks/pre-push index 0207d5a2..be2ba3f0 100755 --- a/scripts/git-hooks/pre-push +++ b/scripts/git-hooks/pre-push @@ -16,7 +16,7 @@ is_enabled() { esac } -echo "[pre-push] Running PR quality gate: bun run quality:pr" +echo "[pre-push] Running fast pre-push quality gate: bun run quality:push" if is_enabled "$(git_config quality.allowCliCoreChange)"; then export ALLOW_CLI_CORE_CHANGE=1 @@ -30,7 +30,7 @@ if is_enabled "$(git_config quality.allowCoverageBaselineChange)"; then export ALLOW_COVERAGE_BASELINE_CHANGE=1 fi -bun run quality:pr +bun run quality:push live="${QUALITY_PRE_PUSH_LIVE:-$(git_config quality.prePushLive)}" diff --git a/scripts/pr/quality-contract.test.ts b/scripts/pr/quality-contract.test.ts index c7ba5055..56a0b9db 100644 --- a/scripts/pr/quality-contract.test.ts +++ b/scripts/pr/quality-contract.test.ts @@ -36,18 +36,25 @@ describe('feature quality contract', () => { const packageJson = JSON.parse(readFileSync('package.json', 'utf8')) as { scripts?: Record } + const prePushHook = readFileSync('scripts/git-hooks/pre-push', 'utf8') const contributing = readFileSync('docs/guide/contributing.md', 'utf8') const englishContributing = readFileSync('docs/en/guide/contributing.md', 'utf8') const rootContributing = readFileSync('CONTRIBUTING.md', 'utf8') expect(packageJson.scripts?.verify).toBe('bun run quality:pr') expect(packageJson.scripts?.['quality:verify']).toBe('bun run quality:pr') + expect(packageJson.scripts?.['quality:push']).toBe('bun run quality:gate --mode pr --skip coverage') expect(packageJson.scripts?.['check:persistence-upgrade']).toBe('bun run scripts/quality-gate/persistence-upgrade.ts') + expect(prePushHook).toContain('bun run quality:push') + expect(prePushHook).not.toContain('\nbun run quality:pr\n') expect(contributing).toContain('bun run verify') + expect(contributing).toContain('bun run quality:push') expect(contributing).toContain('AI Coding Agent 修复循环') expect(englishContributing).toContain('bun run verify') + expect(englishContributing).toContain('bun run quality:push') expect(englishContributing).toContain('AI Coding Agent Fix Loop') expect(rootContributing).toContain('bun run verify') + expect(rootContributing).toContain('bun run quality:push') }) test('keeps general AI coding tools pointed at the same quality bar', () => {