ci / 质量门禁 (push) Canceled after 0s
背景:本地 PG/Redis 已按要求复用 docker-postgres-1 / docker-redis-1; S3 容器按用户要求删除,后续接入公网自建 RustFS。 改动: - 删除 infra/docker-compose.dev.yaml、infra/compose.dev.yaml - 移除 compose:up / compose:down 脚本,改用 check:dev 预检本机 PG/Redis - 新增 scripts/check-dev-deps.mjs;.env.example 的 S3_* 改为待填 - README / AGENTS / A0 报告同步本地依赖与对象存储说明 影响面:本地开发依赖与 CI 本地脚本、环境变量样例、文档。 回滚方式:恢复被删除的两个 compose 文件与 package.json 脚本即可。 验证:format:check、lint、pnpm ci:local(含 e2e 4/4)全部通过,用时 106.3s。
51 lines
1.9 KiB
JavaScript
51 lines
1.9 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* 本地 CI:在无 Gitea Actions runner 时,按 .gitea/workflows/ci.yml 的门禁顺序执行。
|
||
* 用法:pnpm ci:local(推荐通过 ./.tools/pnpm ci:local 锁定 pnpm 10)
|
||
*/
|
||
import { spawnSync } from 'node:child_process';
|
||
|
||
const pnpm = process.env.npm_execpath ? [process.execPath, process.env.npm_execpath] : ['pnpm'];
|
||
|
||
/** 每一步可包含多条 pnpm 命令,任一失败立即退出。 */
|
||
const steps = [
|
||
{ label: '检查本地依赖(PG / Redis)', commands: [['check:dev']] },
|
||
{ label: '格式化检查', commands: [['format:check']] },
|
||
{ label: 'Lint', commands: [['lint']] },
|
||
{ label: '类型检查', commands: [['typecheck']] },
|
||
{ label: '单元测试', commands: [['test']] },
|
||
{ label: '构建', commands: [['build']] },
|
||
{
|
||
label: '数据库迁移与种子',
|
||
commands: [['exec', 'prisma', 'migrate', 'deploy'], ['db:seed']],
|
||
},
|
||
{ label: '集成测试', commands: [['test:int']] },
|
||
{ label: 'OpenAPI 导出与契约检查', commands: [['openapi:export'], ['openapi:diff']] },
|
||
{ label: '端到端测试', commands: [['test:e2e']] },
|
||
];
|
||
|
||
function runPnpm(args) {
|
||
const result = spawnSync(pnpm[0], [...pnpm.slice(1), ...args], {
|
||
env: process.env,
|
||
stdio: 'inherit',
|
||
});
|
||
if (result.error) {
|
||
console.error(`\n执行 pnpm ${args.join(' ')} 失败:${result.error.message}`);
|
||
process.exit(1);
|
||
}
|
||
if (result.status !== 0) {
|
||
console.error(`\n门禁失败:pnpm ${args.join(' ')}(exit ${result.status ?? 1})`);
|
||
process.exit(result.status ?? 1);
|
||
}
|
||
}
|
||
|
||
const startedAt = Date.now();
|
||
for (const [index, step] of steps.entries()) {
|
||
console.log(`\n[${index + 1}/${steps.length}] ${step.label}`);
|
||
for (const args of step.commands) {
|
||
runPnpm(args);
|
||
}
|
||
}
|
||
const seconds = ((Date.now() - startedAt) / 1000).toFixed(1);
|
||
console.log(`\n本地 CI 全部门禁通过,用时 ${seconds}s。`);
|