一、为什么必须配CI
1.1 只靠AI约束的风险
三件套的边界声明:
| 约束类型 | 保证者 | 谁可能绕过 |
|---|---|---|
| 程序性强制 | CLI/CI | 无人能绕 |
| AI行为约束 | Skill元数据+模型选择 | 模型选择失误 |
| 流程惯例 | 团队共识+人审 | 人的惰性 |
只靠AI约束的风险:
python
class AIConstraintRisks:
def __init__(self):
self.risks = {
'test-coverage': {
'bypass_scenario': 'AI漏选skill,或skill没生效',
'consequence': '写了不达标代码,合入主分支'
},
'security-secrets': {
'bypass_scenario': 'AI没跑扫描,或扫描没生效',
'consequence': '密钥泄露到生产环境'
},
'code-structure': {
'bypass_scenario': 'AI写了长文件,没注意到约束',
'consequence': '代码可维护性下降'
}
}
def get_solution(self, risk_name: str) -> str:
"""解决方案:双保险"""
return f"skill约束 + CI闸门 = {risk_name}双保险"
二、覆盖率闸门配置
2.1 Jest覆盖率配置
javascript
// jest.config.js
module.exports = {
coverageThreshold: {
global: {
branches: 80, // 分支覆盖率 >= 80%
functions: 80,
lines: 80,
statements: 80
}
}
};
2.2 GitHub Actions配置
yaml
# .github/workflows/quality-gate.yml
name: Quality Gate
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Run tests with coverage
run: npm test -- --coverage
- name: Check coverage threshold
run: |
COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.branches.pct')
THRESHOLD=80
if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then
echo "Coverage $COVERAGE% is below threshold $THRESHOLD%"
exit 1
fi
echo "Coverage $COVERAGE% meets threshold"
三、安全扫描闸门配置
3.1 Gitleaks配置
yaml
# .github/workflows/security.yml
name: Security Gates
on: [push, pull_request]
jobs:
gitleaks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
3.2 密钥检测规则
toml
# .gitleaks.toml
[[rules]]
id = "api-key"
description = "Generic API key"
regex = '''(?i)(api[_-]?key|apikey|secret[_-]?key|auth[_-]?token)['\"]?\s*[:=]\s*['\"]?[a-zA-Z0-9]{16,}['\"]?'''
[[rules]]
id = "aws-access-key"
description = "AWS Access Key"
regex = '''AKIA[0-9A-Z]{16}'''
[[rules]]
id = "generic-secret"
description = "Generic Secret"
regex = '''(?i)secret|password|passwd|pwd['\"]?\s*[:=]\s*['\"]?[a-zA-Z0-9!@#$%]{8,}['\"]?'''
四、代码规范闸门配置
4.1 ESLint配置
json
// .eslintrc.json
{
"rules": {
"max-lines-per-function": ["error", 50],
"complexity": ["error", 10],
"no-unused-vars": "error",
"no-console": "warn"
}
}
4.2 Pre-commit Hook配置
yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/eslint/eslint
hooks:
- id: eslint
args: ['--max-warnings=0']
- repo: https://github.com/gitleaks/gitleaks
hooks:
- id: gitleaks
五、文件行数检查
5.1 自定义脚本
python
#!/usr/bin/env python3
# scripts/check_file_length.py
import os
import sys
import re
MAX_LINES = 500
def check_file(filepath):
with open(filepath, 'r') as f:
lines = len(f.readlines())
if lines > MAX_LINES:
print(f"ERROR: {filepath} has {lines} lines (max {MAX_LINES})")
return False
print(f"OK: {filepath} ({lines} lines)")
return True
def main():
src_dir = sys.argv[1] if len(sys.argv) > 1 else 'src'
errors = []
for root, dirs, files in os.walk(src_dir):
for file in files:
if file.endswith(('.ts', '.tsx', '.js', '.jsx')):
filepath = os.path.join(root, file)
if not check_file(filepath):
errors.append(filepath)
if errors:
print(f"\n{len(errors)} files exceed {MAX_LINES} lines")
sys.exit(1)
print(f"\nAll files within {MAX_LINES} lines")
if __name__ == '__main__':
main()
5.2 CI配置
yaml
# .github/workflows/file-length.yml
name: File Length Check
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check file lengths
run: python scripts/check_file_length.py src
六、完整CI配置示例
6.1 完整质量门禁
yaml
# .github/workflows/quality-gate.yml
name: Quality Gate
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# 1. 测试与覆盖率
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- uses: actions/upload-artifact@v3
with:
name: coverage
path: coverage/
# 2. 安全扫描
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
with:
args: --verbose
env:
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
# 3. 依赖审查
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/dependency-review-action@v3
# 4. 文件长度检查
file-length:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pip install -r requirements.txt
- run: python scripts/check_file_length.py src
# 5. 构建验证
build:
runs-on: ubuntu-latest
needs: [test, security]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm run build
七、三件套+CI双保险实现
7.1 企业级配置
python
class ThreePiecesWithCI:
def __init__(self):
self.quality_gates = {
'test-coverage': {
'skill': 'test-coverage skill约束AI',
'ci': 'coverage >= 80% in CI',
'double_insurance': True
},
'security-secrets': {
'skill': 'security-secrets skill扫描',
'ci': 'gitleaks + trivy in CI',
'double_insurance': True
},
'code-structure': {
'skill': 'code-structure skill约束',
'ci': 'eslint + file-length in CI',
'double_insurance': True
},
'code-review': {
'skill': 'AI自审+分级报告',
'ci': 'CRITICAL阻断',
'double_insurance': True
}
}
def get_recommendation(self) -> str:
"""推荐配置"""
return """
三件套配置:
- OpenSpec: 严格审阅MUST条款
- Superpowers: TDD循环
- Agent Skills: 适量启用(<=8个)
CI配置:
- 覆盖率闸门: >= 80%
- 安全扫描: gitleaks + trivy
- 规范检查: eslint + file-length
- CRITICAL阻断: 是
双保险 = skill约束AI行为 + CI阻断不达标
"""
八、总结
| 质量维度 | AI约束 | CI闸门 | 双保险 |
|---|---|---|---|
| 测试覆盖率 | test-coverage skill | coverage >= 80% | ✅ |
| 密钥安全 | security-secrets | gitleaks | ✅ |
| 代码规范 | code-structure | eslint | ✅ |
| 审查质量 | AI自审 | CRITICAL阻断 | ✅ |
关键结论:skill约束AI行为,CI阻断不达标合入,人审关键节点。三层叠加 = 可预测的工程化交付。
#AI编程 #三件套 #CI集成 #质量门禁
📖 推荐阅读
如果这篇对你有帮助,以下文章你也会喜欢: