mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 06:17:27 +00:00
fix(ci): tighten slow bucket guardrails
This commit is contained in:
1 parent
572b184220
commit
5af639ddf7
4 files changed
+79
-22
No files matched your search
@@ -177,7 +177,7 @@ ccs ollama "summarize these logs"
|
|||||||
## Contribute And Report Safely
|
## Contribute And Report Safely
|
||||||
|
|
||||||
- Contributing guide: [CONTRIBUTING.md](./CONTRIBUTING.md)
|
- Contributing guide: [CONTRIBUTING.md](./CONTRIBUTING.md)
|
||||||
- Daily local gate: `bun run format && bun run lint:fix && bun run validate`
|
- Daily local gate: `bun run format && bun run lint:fix && bun run validate` (`validate` is the fast path only)
|
||||||
- Before review or merge confidence: `bun run validate:ci-parity`
|
- Before review or merge confidence: `bun run validate:ci-parity`
|
||||||
- If PR checks stay queued for more than 10 minutes, assume the self-hosted runner is offline and notify a maintainer instead of retrying blindly
|
- If PR checks stay queued for more than 10 minutes, assume the self-hosted runner is offline and notify a maintainer instead of retrying blindly
|
||||||
- Starter work:
|
- Starter work:
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[i] Running CI-parity local checks..."
|
echo "[i] Running CI-parity local checks..."
|
||||||
|
# `set -euo pipefail` above makes every step fail fast. Keep these commands
|
||||||
|
# explicit so parity drift is visible when CI changes.
|
||||||
bun run typecheck
|
bun run typecheck
|
||||||
bun run lint
|
bun run lint
|
||||||
bun run format:check
|
bun run format:check
|
||||||
|
|||||||
+52
-21
@@ -4,9 +4,11 @@ const fs = require('node:fs');
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { spawnSync } = require('node:child_process');
|
const { spawnSync } = require('node:child_process');
|
||||||
|
|
||||||
const bucket = process.argv[2];
|
|
||||||
const rootDir = path.resolve(__dirname, '..');
|
const rootDir = path.resolve(__dirname, '..');
|
||||||
const candidateRoots = ['tests/unit', 'tests/integration', 'tests/npm'];
|
const candidateRoots = ['tests/unit', 'tests/integration', 'tests/npm'];
|
||||||
|
// Keep this list in sync with any newly added dist-dependent or long-running
|
||||||
|
// tests. `tests/unit/scripts/run-test-bucket.test.js` verifies every path here
|
||||||
|
// exists so bucket drift fails loudly instead of silently slowing `test:fast`.
|
||||||
const slowTests = [
|
const slowTests = [
|
||||||
'tests/integration/cursor-daemon-lifecycle.test.ts',
|
'tests/integration/cursor-daemon-lifecycle.test.ts',
|
||||||
'tests/integration/proxy/daemon-lifecycle.test.ts',
|
'tests/integration/proxy/daemon-lifecycle.test.ts',
|
||||||
@@ -23,11 +25,6 @@ const slowTests = [
|
|||||||
'tests/unit/web-server/websearch-routes.test.ts',
|
'tests/unit/web-server/websearch-routes.test.ts',
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!['fast', 'slow', 'all'].includes(bucket)) {
|
|
||||||
console.error('[X] Usage: node scripts/run-test-bucket.js <fast|slow|all>');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const filePattern = /(\.test\.(c|m)?[jt]s|\.spec\.(c|m)?[jt]s|-test\.(c|m)?[jt]s)$/;
|
const filePattern = /(\.test\.(c|m)?[jt]s|\.spec\.(c|m)?[jt]s|-test\.(c|m)?[jt]s)$/;
|
||||||
|
|
||||||
function collectFiles(dir, files = []) {
|
function collectFiles(dir, files = []) {
|
||||||
@@ -51,19 +48,30 @@ function readsBuiltDist(relativePath) {
|
|||||||
return source.includes('dist/');
|
return source.includes('dist/');
|
||||||
}
|
}
|
||||||
|
|
||||||
const discovered = candidateRoots
|
function getDiscoveredTests() {
|
||||||
.flatMap((relativeDir) => collectFiles(path.join(rootDir, relativeDir)))
|
return candidateRoots
|
||||||
.sort();
|
.flatMap((relativeDir) => collectFiles(path.join(rootDir, relativeDir)))
|
||||||
const forceSlow = discovered.filter((file) => {
|
.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldForceSlow(file) {
|
||||||
if (file.startsWith('tests/npm/')) {
|
if (file.startsWith('tests/npm/')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return readsBuiltDist(file);
|
return readsBuiltDist(file);
|
||||||
});
|
}
|
||||||
const slowSet = new Set([...slowTests, ...forceSlow]);
|
|
||||||
|
function getSlowSet() {
|
||||||
|
const discovered = getDiscoveredTests();
|
||||||
|
const forceSlow = discovered.filter((file) => shouldForceSlow(file));
|
||||||
|
return new Set([...slowTests, ...forceSlow]);
|
||||||
|
}
|
||||||
|
|
||||||
function selectBucket(name) {
|
function selectBucket(name) {
|
||||||
|
const discovered = getDiscoveredTests();
|
||||||
|
const slowSet = getSlowSet();
|
||||||
|
|
||||||
return name === 'slow'
|
return name === 'slow'
|
||||||
? [...slowSet].sort()
|
? [...slowSet].sort()
|
||||||
: discovered.filter((file) => !slowSet.has(file));
|
: discovered.filter((file) => !slowSet.has(file));
|
||||||
@@ -111,17 +119,40 @@ function runBucket(name) {
|
|||||||
return result.status ?? 1;
|
return result.status ?? 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bucket === 'all') {
|
function main(args = process.argv.slice(2)) {
|
||||||
let exitCode = 0;
|
const bucket = args[0];
|
||||||
|
|
||||||
for (const name of ['fast', 'slow']) {
|
if (!['fast', 'slow', 'all'].includes(bucket)) {
|
||||||
const status = runBucket(name);
|
console.error('[X] Usage: node scripts/run-test-bucket.js <fast|slow|all>');
|
||||||
if (status !== 0) {
|
return 1;
|
||||||
exitCode = status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exit(exitCode);
|
if (bucket === 'all') {
|
||||||
|
let exitCode = 0;
|
||||||
|
|
||||||
|
for (const name of ['fast', 'slow']) {
|
||||||
|
const status = runBucket(name);
|
||||||
|
if (status !== 0) {
|
||||||
|
exitCode = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return runBucket(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exit(runBucket(bucket));
|
if (require.main === module) {
|
||||||
|
process.exit(main());
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
slowTests,
|
||||||
|
readsBuiltDist,
|
||||||
|
shouldForceSlow,
|
||||||
|
getDiscoveredTests,
|
||||||
|
getSlowSet,
|
||||||
|
selectBucket,
|
||||||
|
main,
|
||||||
|
};
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const { describe, expect, test } = require('bun:test');
|
||||||
|
const path = require('node:path');
|
||||||
|
const bucket = require('../../../scripts/run-test-bucket.js');
|
||||||
|
|
||||||
|
describe('run-test-bucket', () => {
|
||||||
|
test('all declared slow tests still exist on disk', () => {
|
||||||
|
for (const relativePath of bucket.slowTests) {
|
||||||
|
const absolutePath = path.resolve(__dirname, '../../../', relativePath);
|
||||||
|
expect(Bun.file(absolutePath).exists()).resolves.toBe(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('forces npm tests into the slow bucket', () => {
|
||||||
|
expect(bucket.shouldForceSlow('tests/npm/cli.test.js')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('keeps dist-independent javascript tests in the fast bucket', () => {
|
||||||
|
expect(bucket.shouldForceSlow('tests/unit/flag-parsing-simple.test.js')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('still forces dist-dependent tests into the slow bucket', () => {
|
||||||
|
expect(bucket.shouldForceSlow('tests/unit/config-dir-override.test.js')).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in new issue
Block a user