mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
chore(ci): split dev quality checks from release automation
This commit is contained in:
1 parent
fd0e9b7c3a
commit
051f78aee7
6 files changed
+247
-12
No files matched your search
@@ -50,8 +50,6 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
${{ env.BUN_INSTALL_CACHE_DIR }}
|
${{ env.BUN_INSTALL_CACHE_DIR }}
|
||||||
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-bun-cache-v2-
|
|
||||||
|
|
||||||
- name: Ensure dependencies
|
- name: Ensure dependencies
|
||||||
run: bash scripts/ensure-deps.sh
|
run: bash scripts/ensure-deps.sh
|
||||||
@@ -84,8 +82,6 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
${{ env.BUN_INSTALL_CACHE_DIR }}
|
${{ env.BUN_INSTALL_CACHE_DIR }}
|
||||||
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-bun-cache-v2-
|
|
||||||
|
|
||||||
- name: Ensure dependencies
|
- name: Ensure dependencies
|
||||||
run: bash scripts/ensure-deps.sh
|
run: bash scripts/ensure-deps.sh
|
||||||
@@ -127,8 +123,6 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
${{ env.BUN_INSTALL_CACHE_DIR }}
|
${{ env.BUN_INSTALL_CACHE_DIR }}
|
||||||
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-bun-cache-v2-
|
|
||||||
|
|
||||||
- name: Ensure dependencies
|
- name: Ensure dependencies
|
||||||
run: bash scripts/ensure-deps.sh
|
run: bash scripts/ensure-deps.sh
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
name: Push CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: push-ci-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: [self-hosted, linux, x64]
|
||||||
|
env:
|
||||||
|
BUN_INSTALL_CACHE_DIR: ${{ github.workspace }}/.bun/install/cache
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
check:
|
||||||
|
- { name: typecheck, cmd: 'bun run typecheck' }
|
||||||
|
- { name: lint, cmd: 'bun run lint' }
|
||||||
|
- { name: format, cmd: 'bun run format:check' }
|
||||||
|
name: ${{ matrix.check.name }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: '1.3.9'
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Restore bun package cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ env.BUN_INSTALL_CACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
||||||
|
|
||||||
|
- name: Ensure dependencies
|
||||||
|
run: bash scripts/ensure-deps.sh
|
||||||
|
|
||||||
|
- name: Run ${{ matrix.check.name }}
|
||||||
|
run: ${{ matrix.check.cmd }}
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: [self-hosted, linux, x64]
|
||||||
|
name: build
|
||||||
|
env:
|
||||||
|
BUN_INSTALL_CACHE_DIR: ${{ github.workspace }}/.bun/install/cache
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: '1.3.9'
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Restore bun package cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ env.BUN_INSTALL_CACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
||||||
|
|
||||||
|
- name: Ensure dependencies
|
||||||
|
run: bash scripts/ensure-deps.sh
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: bun run build:all
|
||||||
|
|
||||||
|
- name: Upload dist artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist/
|
||||||
|
retention-days: 1
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: [self-hosted, linux, x64]
|
||||||
|
name: test
|
||||||
|
needs: [build]
|
||||||
|
env:
|
||||||
|
BUN_INSTALL_CACHE_DIR: ${{ github.workspace }}/.bun/install/cache
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: '1.3.9'
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Restore bun package cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ env.BUN_INSTALL_CACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-bun-cache-v2-${{ hashFiles('bun.lock', 'ui/bun.lock') }}
|
||||||
|
|
||||||
|
- name: Ensure dependencies
|
||||||
|
run: bash scripts/ensure-deps.sh
|
||||||
|
|
||||||
|
- name: Download dist artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: bun run test:all
|
||||||
|
|
||||||
|
- name: Test CLI e2e
|
||||||
|
env:
|
||||||
|
CCS_E2E_SKIP_BUILD: '1'
|
||||||
|
run: bun run test:e2e
|
||||||
+2
-2
@@ -45,9 +45,9 @@ echo " branch: $CURRENT_BRANCH"
|
|||||||
echo " base: $BASE_BRANCH"
|
echo " base: $BASE_BRANCH"
|
||||||
|
|
||||||
bun run typecheck
|
bun run typecheck
|
||||||
bun run lint:fix
|
bun run lint
|
||||||
bun run format:check
|
bun run format:check
|
||||||
bun run build:all
|
bun run test:fast
|
||||||
|
|
||||||
git fetch origin "$BASE_BRANCH" --quiet || true
|
git fetch origin "$BASE_BRANCH" --quiet || true
|
||||||
DIFF_RANGE="HEAD"
|
DIFF_RANGE="HEAD"
|
||||||
|
|||||||
+4
-2
@@ -70,12 +70,14 @@
|
|||||||
"lint:fix": "eslint src/ --fix",
|
"lint:fix": "eslint src/ --fix",
|
||||||
"format": "prettier --write src/",
|
"format": "prettier --write src/",
|
||||||
"format:check": "prettier --check src/",
|
"format:check": "prettier --check src/",
|
||||||
"validate": "bun run typecheck && bun run lint:fix && bun run format:check && bun run test:all",
|
"validate": "bun run typecheck && bun run lint && bun run format:check && bun run test:fast",
|
||||||
"validate:ci-parity": "bash scripts/ci-parity-gate.sh",
|
"validate:ci-parity": "bash scripts/ci-parity-gate.sh",
|
||||||
"verify:bundle": "node scripts/verify-bundle.js",
|
"verify:bundle": "node scripts/verify-bundle.js",
|
||||||
"test": "bun run build && bun run test:all",
|
"test": "bun run build && bun run test:all",
|
||||||
"test:ci": "bun run test:all",
|
"test:ci": "bun run test:all",
|
||||||
"test:all": "bun test --max-concurrency=1 tests/unit tests/integration tests/npm",
|
"test:fast": "node scripts/run-test-bucket.js fast",
|
||||||
|
"test:slow": "node scripts/run-test-bucket.js slow",
|
||||||
|
"test:all": "bun run test:fast && bun run test:slow",
|
||||||
"test:unit": "bun test tests/unit",
|
"test:unit": "bun test tests/unit",
|
||||||
"test:npm": "bun test tests/npm/",
|
"test:npm": "bun test tests/npm/",
|
||||||
"test:native": "bash tests/native/unix/edge-cases.sh",
|
"test:native": "bash tests/native/unix/edge-cases.sh",
|
||||||
|
|||||||
@@ -55,8 +55,12 @@ if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[i] Running CI-equivalent local checks..."
|
echo "[i] Running CI-parity local checks..."
|
||||||
|
bun run typecheck
|
||||||
|
bun run lint
|
||||||
|
bun run format:check
|
||||||
bun run build:all
|
bun run build:all
|
||||||
bun run validate
|
bun run test:all
|
||||||
|
CCS_E2E_SKIP_BUILD=1 bun run test:e2e
|
||||||
|
|
||||||
echo "[OK] CI parity gate passed."
|
echo "[OK] CI parity gate passed."
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const { spawnSync } = require('node:child_process');
|
||||||
|
|
||||||
|
const bucket = process.argv[2];
|
||||||
|
const rootDir = path.resolve(__dirname, '..');
|
||||||
|
const candidateRoots = ['tests/unit', 'tests/integration', 'tests/npm'];
|
||||||
|
const slowTests = [
|
||||||
|
'tests/integration/cursor-daemon-lifecycle.test.ts',
|
||||||
|
'tests/integration/proxy/daemon-lifecycle.test.ts',
|
||||||
|
'tests/unit/commands/persist-command-handler.test.ts',
|
||||||
|
'tests/unit/hooks/ccs-browser-mcp-server.test.ts',
|
||||||
|
'tests/unit/targets/codex-runtime-integration.test.ts',
|
||||||
|
'tests/unit/targets/codex-settings-bridge-launch.test.ts',
|
||||||
|
'tests/unit/targets/droid-command-routing-integration.test.ts',
|
||||||
|
'tests/unit/targets/droid-config-manager.test.ts',
|
||||||
|
'tests/unit/targets/settings-profile-browser-launch.test.ts',
|
||||||
|
'tests/unit/targets/settings-profile-image-analysis-launch.test.ts',
|
||||||
|
'tests/unit/targets/settings-profile-websearch-launch.test.ts',
|
||||||
|
'tests/unit/web-server/cursor-routes.test.ts',
|
||||||
|
'tests/unit/web-server/websearch-routes.test.ts',
|
||||||
|
];
|
||||||
|
|
||||||
|
if (bucket !== 'fast' && bucket !== 'slow') {
|
||||||
|
console.error('[X] Usage: node scripts/run-test-bucket.js <fast|slow>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePattern = /(\.test\.(c|m)?[jt]s|\.spec\.(c|m)?[jt]s|-test\.(c|m)?[jt]s)$/;
|
||||||
|
|
||||||
|
function collectFiles(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const fullPath = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
collectFiles(fullPath, files);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePattern.test(entry.name)) {
|
||||||
|
files.push(path.relative(rootDir, fullPath).split(path.sep).join('/'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readsBuiltDist(relativePath) {
|
||||||
|
const source = fs.readFileSync(path.join(rootDir, relativePath), 'utf8');
|
||||||
|
return source.includes('dist/');
|
||||||
|
}
|
||||||
|
|
||||||
|
const discovered = candidateRoots
|
||||||
|
.flatMap((relativeDir) => collectFiles(path.join(rootDir, relativeDir)))
|
||||||
|
.sort();
|
||||||
|
const forceSlow = discovered.filter((file) => {
|
||||||
|
if (file.startsWith('tests/npm/')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/\.(c|m)?js$/.test(file)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return readsBuiltDist(file);
|
||||||
|
});
|
||||||
|
const slowSet = new Set([...slowTests, ...forceSlow]);
|
||||||
|
const selected =
|
||||||
|
bucket === 'slow'
|
||||||
|
? [...slowSet].sort()
|
||||||
|
: discovered.filter((file) => !slowSet.has(file));
|
||||||
|
|
||||||
|
if (selected.length === 0) {
|
||||||
|
console.error(`[X] No tests matched the '${bucket}' bucket.`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bucket === 'slow' && !fs.existsSync(path.join(rootDir, 'dist', 'ccs.js'))) {
|
||||||
|
const build = spawnSync('bun', ['run', 'build'], {
|
||||||
|
cwd: rootDir,
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: process.platform === 'win32',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (build.status !== 0) {
|
||||||
|
process.exit(build.status ?? 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = spawnSync(
|
||||||
|
'bun',
|
||||||
|
['test', '--max-concurrency=1', ...selected],
|
||||||
|
{
|
||||||
|
cwd: rootDir,
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: process.platform === 'win32',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
process.exit(result.status ?? 1);
|
||||||
Reference in new issue
Block a user