可复用工作流(Reusable Workflows)
什么是可复用工作流?
可复用工作流(workflow_call)允许你将一个 Workflow 作为另一个 Workflow 的 Job 调用,实现"CI/CD 模板"的概念。团队可以定义标准化的构建、测试、部署流程,所有项目复用同一套模板,修改模板即可统一升级所有项目。
定义可复用工作流
# .github/workflows/reusable-deploy.yml(这是被调用的模板)
name: 可复用部署工作流
on:
workflow_call: # 声明此工作流可被调用
inputs:
environment:
required: true
type: string
description: '部署环境(staging/production)'
image-tag:
required: true
type: string
dry-run:
required: false
type: boolean
default: false
secrets:
AWS_ROLE_ARN:
required: true
outputs:
deploy-url:
description: '部署后的访问 URL'
value: ${{ jobs.deploy.outputs.url }}
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
outputs:
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- id: deploy
name: 执行部署
run: |
if [[ "${{ inputs.dry-run }}" == "true" ]]; then
echo "DRY RUN: 将部署 ${{ inputs.image-tag }} 到 ${{ inputs.environment }}"
else
# 实际部署逻辑
DEPLOY_URL="https://app-${{ inputs.environment }}.example.com"
echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
fi
调用可复用工作流
# 项目 A 的 deploy.yml
name: 项目A部署流水线
on:
push:
branches: [main]
jobs:
# 先运行自己的测试
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
# 调用共享的部署工作流
deploy-staging:
needs: test
uses: my-org/.github/.github/workflows/reusable-deploy.yml@main
with:
environment: staging
image-tag: ${{ github.sha }}
secrets:
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN_STAGING }}
deploy-production:
needs: deploy-staging
uses: my-org/.github/.github/workflows/reusable-deploy.yml@main
with:
environment: production
image-tag: ${{ github.sha }}
secrets:
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN_PROD }}
Monorepo 策略
路径过滤:智能触发
Monorepo 中包含多个服务,如果每次任意变更都触发所有 CI,既浪费资源又降低效率。使用 paths 过滤和动态检测变更实现智能触发:
# 服务A 专属 CI(只有 services/api/ 变更时触发)
name: API Service CI
on:
push:
paths:
- 'services/api/**'
- 'packages/shared/**' # 共享包变更也要触发
- '.github/workflows/ci-api.yml' # CI 配置本身变更
jobs:
test-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd services/api && npm test
动态检测变更文件(高级)
name: Monorepo Smart CI
on: [push, pull_request]
jobs:
# 第一步:检测哪些服务有变更
detect-changes:
runs-on: ubuntu-latest
outputs:
api-changed: ${{ steps.filter.outputs.api }}
web-changed: ${{ steps.filter.outputs.web }}
mobile-changed: ${{ steps.filter.outputs.mobile }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
api:
- 'services/api/**'
- 'packages/shared/**'
web:
- 'apps/web/**'
- 'packages/ui/**'
mobile:
- 'apps/mobile/**'
# 根据检测结果,条件性运行各服务 CI
test-api:
needs: detect-changes
if: needs.detect-changes.outputs.api-changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd services/api && npm test
test-web:
needs: detect-changes
if: needs.detect-changes.outputs.web-changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd apps/web && npm test
部署环境保护规则
为生产部署设置审批流
在 GitHub 仓库设置 → Environments 中配置 production 环境,添加保护规则:指定必须由哪些人员审批后才能部署。
jobs:
deploy-production:
runs-on: ubuntu-latest
environment:
name: production # 引用设置了保护规则的环境
url: https://app.example.com
# 必须通过 production 环境的审批才会执行此 Job
steps:
- name: 执行生产部署
run: ./deploy.sh production
# 部署后烟雾测试
smoke-test:
needs: deploy-production
runs-on: ubuntu-latest
steps:
- name: 健康检查
run: |
for i in {1..5}; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://app.example.com/health)
if [[ "$STATUS" == "200" ]]; then
echo "✅ 服务健康,HTTP $STATUS"
exit 0
fi
echo "等待中... ($i/5)"
sleep 30
done
echo "❌ 健康检查失败"
exit 1
推荐 Monorepo 工具链
- Turborepo:构建缓存 + 任务编排,配合 GitHub Actions 效果极佳
- Nx:强大的 Monorepo 管理工具,自带受影响项目检测
- Changesets:Monorepo 版本管理和 CHANGELOG 自动化
总结:GitHub Actions 最佳实践清单
安全
声明最小权限;使用 OIDC 替代长期密钥;固定 Action 版本到 commit SHA;定期运行 CodeQL 和 Trivy 扫描。
效率
使用 setup-* Action 的内置缓存;合理配置 paths 过滤避免不必要触发;并行运行独立 Job;使用 fail-fast: false 收集全量测试结果。
可维护性
提取共用步骤为 Composite Action;用可复用工作流统一团队标准;Workflow 文件加注释说明;配合 Dependabot 自动更新 Action 版本。
可靠性
为生产部署配置环境保护规则和审批流;部署后运行烟雾测试;失败时自动回滚;配置通知(Slack/钉钉)及时告警。
本章小结
本章核心要点
- Monorepo CI 的关键挑战:路径过滤(paths/paths-ignore)确保只有相关子项目变更时才触发对应的 CI;受影响项目检测(nx affected、turbo prune)进一步缩小构建范围;矩阵策略并行测试多个子项目。
- 蓝绿部署与滚动部署:蓝绿部署维护两套环境,切换时流量直接从蓝切到绿,回滚只需切回蓝(适合需要秒级回滚的场景,但资源成本双倍);滚动部署逐步替换旧 Pod(适合 Kubernetes,节省资源但回滚需要时间)。
- 部署后的健康验证:部署完成 ≠ 部署成功,必须配置部署后健康检查(HTTP 轮询关键端点);检查失败时自动触发回滚;将烟雾测试结果作为 PR 状态检查的一部分,防止问题代码合并。
- 推荐 Monorepo 工具链:Turborepo(构建缓存+任务编排,配合 GitHub Actions 效果极佳)、Nx(强大的受影响项目检测)、Changesets(版本管理和 CHANGELOG 自动化)。
- 四维最佳实践:安全(OIDC、最小权限、固定 SHA)、效率(缓存、paths 过滤、并行)、可维护性(Composite Action、可复用工作流)、可靠性(保护规则、烟雾测试、通知告警)。这四个维度是衡量 CI/CD 成熟度的核心标准。