
主干开发:正确实现持续集成
主干开发(Trunk-Based Development, TBD)意味着频繁地将代码集成到主干,以避免合并地狱。
核心原则
- 短生命周期分支:最长1-2天,然后合并
- 小提交:每个提交都是一个完整、可工作的单元
- 始终绿色:主干分支始终可部署
- 特性开关:在生产环境中隐藏未完成的功能
特性开关处理未完成工作
// 特性开关服务
class FeatureFlags {
private flags: Map<string, boolean>;
constructor(private config: FlagConfig) {
this.flags = new Map(Object.entries(config));
}
isEnabled(flag: string, userId?: string): boolean {
return this.flags.get(flag) ?? false;
}
}
// 使用:安全地提交未完成特性
async function processOrder(order: Order, flags: FeatureFlags) {
if (flags.isEnabled('new-payment-flow')) {
return await newPaymentService.process(order);
}
return await legacyPaymentService.process(order);
}
分支策略
# 主干开发(推荐)
main <-- 单一事实来源
|
+-- feature/user-auth(最长1-2天)
+-- fix/login-bug(最长几小时)
# 非主干开发(避免)
main
develop
release/v1.2
feature/big-feature(3周前!)
结对/群体编程替代方案
# 使用短分支(<1天),直接集成
git checkout -b feat/add-search
# 工作几小时
git add .
git commit -m "feat: add search endpoint with basic filtering"
git push origin feat/add-search
# 创建PR,快速审查,当天合并
主干开发的CI流水线
# .github/workflows/ci.yml
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run typecheck
- run: npm run lint
- run: npm test -- --coverage
- run: npm run build
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy to production
run: ./deploy.sh
防止大爆炸式合并
// 不要分支两周,而是在开关后提交
// 第1天:添加开关和桩代码
async function getRecommendations(userId: string) {
if (featureFlags.isEnabled('ml-recommendations')) {
// TODO: 实现ML推荐
return [];
}
return legacyRecommendations(userId);
}
// 第2天:在开关后实现核心逻辑
// 第3天:对10%用户启用开关
// 第4天:对所有用户启用
// 第5天:移除开关和旧代码
分支保护规则
main分支保护:
- 要求状态检查(CI必须通过)
- 要求1+个批准
- 新提交时忽略过时的审查
- 禁止直接推送(需要PR)
- 要求线性历史(rebase/squash)
主干开发配合特性开关实现了真正的持续交付——每天安全地部署多次。