ci-cd-pipeline-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCI/CD Pipeline Patterns
CI/CD流水线模式
A comprehensive skill for designing, implementing, and optimizing CI/CD pipelines using GitHub Actions and modern DevOps practices. Master workflow automation, testing strategies, deployment patterns, and release management for continuous software delivery.
这是一项利用GitHub Actions和现代DevOps实践来设计、实现和优化CI/CD流水线的全面技能。掌握工作流自动化、测试策略、部署模式以及持续软件交付的发布管理。
When to Use This Skill
何时使用此技能
Use this skill when:
- Setting up continuous integration and deployment pipelines for projects
- Automating build, test, and deployment workflows
- Implementing multi-environment deployment strategies (staging, production)
- Managing release automation and versioning
- Configuring matrix builds for multi-platform testing
- Securing CI/CD pipelines with secrets and OIDC
- Optimizing pipeline performance with caching and parallelization
- Building containerized applications with Docker in CI
- Deploying to cloud platforms (AWS, Azure, GCP, Vercel, Netlify)
- Implementing infrastructure as code with Terraform/CloudFormation
- Setting up monorepo CI/CD patterns
- Creating reusable workflow templates and custom actions
- Implementing deployment strategies (blue-green, canary, rolling)
- Automating changelog generation and semantic versioning
- Integrating quality gates and code coverage checks
在以下场景使用此技能:
- 为项目搭建持续集成与部署流水线
- 自动化构建、测试和部署工作流
- 实现多环境部署策略(预发布、生产)
- 管理发布自动化与版本控制
- 配置矩阵构建以实现多平台测试
- 使用密钥和OIDC保障CI/CD流水线安全
- 通过缓存和并行化优化流水线性能
- 在CI中使用Docker构建容器化应用
- 部署至云平台(AWS、Azure、GCP、Vercel、Netlify)
- 使用Terraform/CloudFormation实现基础设施即代码
- 搭建单体仓库(Monorepo)CI/CD模式
- 创建可复用工作流模板和自定义Actions
- 实现部署策略(蓝绿部署、金丝雀部署、滚动部署)
- 自动化生成变更日志与语义化版本控制
- 集成质量门禁与代码覆盖率检查
Core Concepts
核心概念
CI/CD Fundamentals
CI/CD基础
Continuous Integration (CI): Automatically building and testing code changes as developers commit to the repository.
Continuous Deployment (CD): Automatically deploying code changes to production after passing tests.
Continuous Delivery: Keeping code in a deployable state, with manual approval for production deployment.
持续集成(CI):开发者提交代码变更时,自动构建并测试代码。
持续部署(CD):代码通过测试后,自动部署至生产环境。
持续交付:保持代码处于可部署状态,生产环境部署需手动批准。
GitHub Actions Architecture
GitHub Actions架构
GitHub Actions provides event-driven automation directly integrated with your repository.
GitHub Actions提供与仓库直接集成的事件驱动自动化能力。
Workflows
工作流
YAML files in that define automated processes:
.github/workflows/yaml
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build project
run: npm run buildKey Components:
- name: Human-readable workflow name
- on: Events that trigger the workflow (push, pull_request, schedule, workflow_dispatch)
- jobs: Collection of steps that run in sequence or parallel
- runs-on: The runner environment (ubuntu-latest, windows-latest, macos-latest)
位于目录下的YAML文件,用于定义自动化流程:
.github/workflows/yaml
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build project
run: npm run build核心组件:
- name:易读的工作流名称
- on:触发工作流的事件(push、pull_request、schedule、workflow_dispatch)
- jobs:按顺序或并行运行的步骤集合
- runs-on:运行环境(ubuntu-latest、windows-latest、macos-latest)
Jobs
任务(Jobs)
Groups of steps executed on the same runner:
yaml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
deploy:
needs: test # Runs after 'test' job completes
runs-on: ubuntu-latest
steps:
- run: npm run deployJob Features:
- needs: Define job dependencies (sequential execution)
- if: Conditional execution based on expressions
- strategy: Matrix builds for multiple configurations
- outputs: Share data between jobs
- environment: Deployment environments with protection rules
在同一运行器上执行的步骤组:
yaml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
deploy:
needs: test # 在'test'任务完成后运行
runs-on: ubuntu-latest
steps:
- run: npm run deploy任务特性:
- needs:定义任务依赖(顺序执行)
- if:基于表达式的条件执行
- strategy:用于多配置的矩阵构建
- outputs:在任务间共享数据
- environment:带有保护规则的部署环境
Steps
步骤(Steps)
Individual tasks within a job:
yaml
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm testStep Types:
- uses: Run a pre-built action from marketplace or repository
- run: Execute shell commands
- with: Provide inputs to actions
- env: Set environment variables for the step
任务中的单个操作:
yaml
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test步骤类型:
- uses:运行来自市场或仓库的预构建Action
- run:执行Shell命令
- with:为Action提供输入参数
- env:为步骤设置环境变量
Actions
Actions
Reusable units of code that perform specific tasks:
Official Actions:
- : Check out repository code
actions/checkout@v4 - : Setup Node.js environment
actions/setup-node@v4 - : Cache dependencies
actions/cache@v4 - : Upload build artifacts
actions/upload-artifact@v4 - : Download artifacts from previous jobs
actions/download-artifact@v4
Marketplace Actions:
- : Build and push Docker images
docker/build-push-action@v5 - : Configure AWS credentials
aws-actions/configure-aws-credentials@v4 - : Upload code coverage
codecov/codecov-action@v4 - : Authenticate with Google Cloud
google-github-actions/auth@v2
执行特定任务的可复用代码单元:
官方Actions:
- :拉取仓库代码
actions/checkout@v4 - :配置Node.js环境
actions/setup-node@v4 - :缓存依赖
actions/cache@v4 - :上传构建产物
actions/upload-artifact@v4 - :下载来自之前任务的产物
actions/download-artifact@v4
市场Actions:
- :构建并推送Docker镜像
docker/build-push-action@v5 - :配置AWS凭证
aws-actions/configure-aws-credentials@v4 - :上传代码覆盖率
codecov/codecov-action@v4 - :认证Google Cloud
google-github-actions/auth@v2
Secrets and Variables
密钥与变量
Secrets: Encrypted sensitive data (API keys, credentials, tokens)
yaml
steps:
- name: Deploy to production
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: npm run deployVariables: Non-sensitive configuration data
yaml
env:
NODE_ENV: ${{ vars.NODE_ENV }}
API_ENDPOINT: ${{ vars.API_ENDPOINT }}Secret Types:
- Repository secrets: Available to all workflows in a repository
- Environment secrets: Scoped to specific environments (production, staging)
- Organization secrets: Shared across repositories in an organization
密钥(Secrets):加密的敏感数据(API密钥、凭证、令牌)
yaml
steps:
- name: Deploy to production
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: npm run deploy变量(Variables):非敏感配置数据
yaml
env:
NODE_ENV: ${{ vars.NODE_ENV }}
API_ENDPOINT: ${{ vars.API_ENDPOINT }}密钥类型:
- 仓库密钥:对仓库中所有工作流可用
- 环境密钥:限定于特定环境(生产、预发布)
- 组织密钥:在组织内的仓库间共享
Artifacts
构建产物(Artifacts)
Files produced by workflows that can be downloaded or used by other jobs:
yaml
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist-files
path: dist/
retention-days: 7
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist-files
path: ./dist工作流生成的可下载或供其他任务使用的文件:
yaml
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist-files
path: dist/
retention-days: 7
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist-files
path: ./distWorkflow Triggers
工作流触发器
Event Triggers
事件触发器
Push Events:
yaml
on:
push:
branches:
- main
- develop
- 'release/**'
paths:
- 'src/**'
- 'package.json'
tags:
- 'v*'Pull Request Events:
yaml
on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
paths-ignore:
- 'docs/**'
- '**.md'Schedule (Cron):
yaml
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight UTC
- cron: '0 */6 * * *' # Every 6 hoursManual Triggers (workflow_dispatch):
yaml
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy to'
required: true
type: choice
options:
- staging
- production
version:
description: 'Version to deploy'
required: true
type: stringRelease Events:
yaml
on:
release:
types: [published, created, released]Workflow Call (Reusable Workflows):
yaml
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
api-key:
required: true推送事件:
yaml
on:
push:
branches:
- main
- develop
- 'release/**'
paths:
- 'src/**'
- 'package.json'
tags:
- 'v*'拉取请求事件:
yaml
on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
paths-ignore:
- 'docs/**'
- '**.md'定时触发器(Cron):
yaml
on:
schedule:
- cron: '0 0 * * *' # 每天UTC时间午夜执行
- cron: '0 */6 * * *' # 每6小时执行一次手动触发器(workflow_dispatch):
yaml
on:
workflow_dispatch:
inputs:
environment:
description: '要部署的环境'
required: true
type: choice
options:
- staging
- production
version:
description: '要部署的版本'
required: true
type: string发布事件:
yaml
on:
release:
types: [published, created, released]工作流调用(可复用工作流):
yaml
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
api-key:
required: trueMatrix Builds
矩阵构建
Run jobs across multiple configurations in parallel:
yaml
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
include:
- os: ubuntu-latest
node-version: 20
coverage: true
exclude:
- os: macos-latest
node-version: 18
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm test
- if: matrix.coverage
run: npm run coverageMatrix Features:
- Parallel execution: All combinations run simultaneously
- include: Add specific configurations
- exclude: Remove specific combinations
- fail-fast: Stop all jobs if one fails (default: true)
- max-parallel: Limit concurrent jobs
并行运行多配置任务:
yaml
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
include:
- os: ubuntu-latest
node-version: 20
coverage: true
exclude:
- os: macos-latest
node-version: 18
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm test
- if: matrix.coverage
run: npm run coverage矩阵特性:
- 并行执行:所有组合同时运行
- include:添加特定配置
- exclude:移除特定组合
- fail-fast:若一个任务失败则停止所有任务(默认:开启)
- max-parallel:限制并发任务数
Caching Strategies
缓存策略
Speed up workflows by caching dependencies:
Node.js Caching:
yaml
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # Automatically caches npm dependenciesCustom Caching:
yaml
- uses: actions/cache@v4
with:
path: |
~/.npm
~/.cache
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-Docker Layer Caching:
yaml
- uses: docker/build-push-action@v5
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=max通过缓存依赖加速工作流:
Node.js缓存:
yaml
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 自动缓存npm依赖自定义缓存:
yaml
- uses: actions/cache@v4
with:
path: |
~/.npm
~/.cache
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-Docker层缓存:
yaml
- uses: docker/build-push-action@v5
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=maxTesting Strategies in CI
CI中的测试策略
Unit Testing
单元测试
Fast, isolated tests for individual components:
yaml
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/coverage-final.json
flags: unit-tests
token: ${{ secrets.CODECOV_TOKEN }}针对单个组件的快速、隔离测试:
yaml
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/coverage-final.json
flags: unit-tests
token: ${{ secrets.CODECOV_TOKEN }}Integration Testing
集成测试
Test interactions between components and services:
yaml
jobs:
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run database migrations
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
run: npm run migrate
- name: Run integration tests
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
run: npm run test:integration测试组件与服务间的交互:
yaml
jobs:
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run database migrations
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
run: npm run migrate
- name: Run integration tests
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
run: npm run test:integrationEnd-to-End Testing
端到端测试
Test complete user workflows:
yaml
jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run E2E tests
run: npm run test:e2e
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30测试完整用户工作流:
yaml
jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run E2E tests
run: npm run test:e2e
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30Performance Testing
性能测试
Benchmark and performance regression testing:
yaml
jobs:
performance-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build for production
run: npm run build
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v11
with:
urls: |
http://localhost:3000
http://localhost:3000/dashboard
uploadArtifacts: true
temporaryPublicStorage: true
- name: Run load tests
run: npm run test:load基准测试与性能回归测试:
yaml
jobs:
performance-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build for production
run: npm run build
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v11
with:
urls: |
http://localhost:3000
http://localhost:3000/dashboard
uploadArtifacts: true
temporaryPublicStorage: true
- name: Run load tests
run: npm run test:loadCode Quality and Linting
代码质量与代码检查
Enforce code standards and quality gates:
yaml
jobs:
code-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Run Prettier check
run: npm run format:check
- name: Run TypeScript check
run: npm run type-check
- name: Run security audit
run: npm audit --audit-level=moderate
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}强制执行代码标准与质量门禁:
yaml
jobs:
code-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Run Prettier check
run: npm run format:check
- name: Run TypeScript check
run: npm run type-check
- name: Run security audit
run: npm audit --audit-level=moderate
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}Deployment Patterns
部署模式
Blue-Green Deployment
蓝绿部署
Zero-downtime deployment by maintaining two identical environments:
yaml
jobs:
deploy-blue-green:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Green environment
run: |
# Deploy new version to green environment
./deploy.sh green
- name: Run smoke tests on Green
run: |
# Verify green environment is healthy
curl -f https://green.example.com/health
- name: Switch traffic to Green
run: |
# Update load balancer to point to green
aws elbv2 modify-rule --rule-arn $RULE_ARN \
--actions Type=forward,TargetGroupArn=$GREEN_TG
- name: Monitor Green environment
run: |
# Monitor for 5 minutes
./monitor.sh green 300
- name: Rollback if needed
if: failure()
run: |
# Switch back to blue
aws elbv2 modify-rule --rule-arn $RULE_ARN \
--actions Type=forward,TargetGroupArn=$BLUE_TG通过维护两个相同环境实现零停机部署:
yaml
jobs:
deploy-blue-green:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Green environment
run: |
# Deploy new version to green environment
./deploy.sh green
- name: Run smoke tests on Green
run: |
# Verify green environment is healthy
curl -f https://green.example.com/health
- name: Switch traffic to Green
run: |
# Update load balancer to point to green
aws elbv2 modify-rule --rule-arn $RULE_ARN \
--actions Type=forward,TargetGroupArn=$GREEN_TG
- name: Monitor Green environment
run: |
# Monitor for 5 minutes
./monitor.sh green 300
- name: Rollback if needed
if: failure()
run: |
# Switch back to blue
aws elbv2 modify-rule --rule-arn $RULE_ARN \
--actions Type=forward,TargetGroupArn=$BLUE_TGCanary Deployment
金丝雀部署
Gradual rollout to a subset of users:
yaml
jobs:
canary-deployment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy canary (10% traffic)
run: |
kubectl set image deployment/app app=myapp:${{ github.sha }}
kubectl scale deployment/app-canary --replicas=1
kubectl annotate service app-service \
traffic-split='{"canary": 10, "stable": 90}'
- name: Monitor canary metrics
run: |
# Monitor error rates, latency for 15 minutes
./monitor-canary.sh 900
- name: Increase canary traffic (50%)
run: |
kubectl annotate service app-service \
traffic-split='{"canary": 50, "stable": 50}' --overwrite
- name: Monitor again
run: ./monitor-canary.sh 600
- name: Full rollout (100%)
run: |
kubectl set image deployment/app-stable app=myapp:${{ github.sha }}
kubectl scale deployment/app-canary --replicas=0
- name: Rollback canary
if: failure()
run: |
kubectl scale deployment/app-canary --replicas=0向部分用户逐步推出新版本:
yaml
jobs:
canary-deployment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy canary (10% traffic)
run: |
kubectl set image deployment/app app=myapp:${{ github.sha }}
kubectl scale deployment/app-canary --replicas=1
kubectl annotate service app-service \
traffic-split='{"canary": 10, "stable": 90}'
- name: Monitor canary metrics
run: |
# Monitor error rates, latency for 15 minutes
./monitor-canary.sh 900
- name: Increase canary traffic (50%)
run: |
kubectl annotate service app-service \
traffic-split='{"canary": 50, "stable": 50}' --overwrite
- name: Monitor again
run: ./monitor-canary.sh 600
- name: Full rollout (100%)
run: |
kubectl set image deployment/app-stable app=myapp:${{ github.sha }}
kubectl scale deployment/app-canary --replicas=0
- name: Rollback canary
if: failure()
run: |
kubectl scale deployment/app-canary --replicas=0Rolling Deployment
滚动部署
Sequential update of instances:
yaml
jobs:
rolling-deployment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy with rolling update
run: |
kubectl set image deployment/app \
app=myapp:${{ github.sha }} \
--record
- name: Wait for rollout to complete
run: |
kubectl rollout status deployment/app --timeout=10m
- name: Verify deployment
run: |
kubectl get pods -l app=myapp
curl -f https://api.example.com/health
- name: Rollback on failure
if: failure()
run: |
kubectl rollout undo deployment/app按顺序更新实例:
yaml
jobs:
rolling-deployment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy with rolling update
run: |
kubectl set image deployment/app \
app=myapp:${{ github.sha }} \
--record
- name: Wait for rollout to complete
run: |
kubectl rollout status deployment/app --timeout=10m
- name: Verify deployment
run: |
kubectl get pods -l app=myapp
curl -f https://api.example.com/health
- name: Rollback on failure
if: failure()
run: |
kubectl rollout undo deployment/appMulti-Environment Deployment
多环境部署
Deploy to staging, then production with approvals:
yaml
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: ./deploy.sh staging
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.sh production先部署至预发布环境,再手动批准后部署至生产环境:
yaml
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: ./deploy.sh staging
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.sh productionSecurity Best Practices
安全最佳实践
Secret Management
密钥管理
Using GitHub Secrets:
yaml
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1Environment-Scoped Secrets:
yaml
jobs:
deploy:
environment: production # Uses production-scoped secrets
steps:
- name: Deploy
env:
API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
run: ./deploy.sh使用GitHub Secrets:
yaml
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1环境限定密钥:
yaml
jobs:
deploy:
environment: production # 使用生产环境限定的密钥
steps:
- name: Deploy
env:
API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
run: ./deploy.shOIDC (OpenID Connect)
OIDC(开放ID连接)
Authenticate without long-lived credentials:
yaml
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: us-east-1
- name: Deploy to AWS
run: aws s3 sync ./dist s3://my-bucketGoogle Cloud OIDC:
yaml
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: 'projects/123/locations/global/workloadIdentityPools/pool/providers/provider'
service_account: 'github-actions@project.iam.gserviceaccount.com'无需长期凭证即可完成认证:
yaml
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: us-east-1
- name: Deploy to AWS
run: aws s3 sync ./dist s3://my-bucketGoogle Cloud OIDC:
yaml
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: 'projects/123/locations/global/workloadIdentityPools/pool/providers/provider'
service_account: 'github-actions@project.iam.gserviceaccount.com'Secure Workflows
安全工作流
Restrict permissions:
yaml
permissions:
contents: read # Read repository contents
pull-requests: write # Comment on PRs
id-token: write # OIDC token generation
actions: read # Read workflow runsPin action versions to SHA:
yaml
undefined限制权限:
yaml
permissions:
contents: read # 读取仓库内容
pull-requests: write # 对PR添加评论
id-token: write # 生成OIDC令牌
actions: read # 读取工作流运行状态将Action版本固定为SHA:
yaml
undefinedLess secure (tag can be moved)
安全性较低(标签可被移动)
- uses: actions/checkout@v4
- uses: actions/checkout@v4
More secure (immutable SHA)
安全性更高(不可变SHA)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
**Prevent script injection:**
```yaml- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
**防止脚本注入:**
```yamlVulnerable to injection
易受注入攻击
- run: echo "Hello ${{ github.event.issue.title }}"
- run: echo "Hello ${{ github.event.issue.title }}"
Safe approach
安全做法
- run: echo "Hello $TITLE" env: TITLE: ${{ github.event.issue.title }}
undefined- run: echo "Hello $TITLE" env: TITLE: ${{ github.event.issue.title }}
undefinedDocker in CI/CD
CI/CD中的Docker
Building Docker Images
构建Docker镜像
yaml
jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: myorg/myapp
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=maxyaml
jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: myorg/myapp
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=maxMulti-Stage Docker Builds
多阶段Docker构建
dockerfile
undefineddockerfile
undefinedBuild stage
Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
Production stage
Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["npm", "start"]
undefinedFROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["npm", "start"]
undefinedContainer Scanning
容器扫描
yaml
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myorg/myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'yaml
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myorg/myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'Release Automation
发布自动化
Semantic Versioning
语义化版本控制
Automatically version releases based on commit messages:
yaml
jobs:
release:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-releaseConfiguration (.releaserc.json):
json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
["@semantic-release/git", {
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
]
}基于提交消息自动版本化发布:
yaml
jobs:
release:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release配置文件(.releaserc.json):
json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
["@semantic-release/git", {
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
]
}Changelog Generation
变更日志生成
yaml
- name: Generate changelog
uses: mikepenz/release-changelog-builder-action@v4
with:
configuration: '.github/changelog-config.json'
outputFile: 'CHANGELOG.md'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.tag }}
bodyFile: 'CHANGELOG.md'
artifacts: 'dist/*'yaml
- name: Generate changelog
uses: mikepenz/release-changelog-builder-action@v4
with:
configuration: '.github/changelog-config.json'
outputFile: 'CHANGELOG.md'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.tag }}
bodyFile: 'CHANGELOG.md'
artifacts: 'dist/*'Release Notes Automation
发布说明自动化
yaml
- name: Build Release Notes
id: release_notes
uses: mikepenz/release-changelog-builder-action@v4
with:
configurationJson: |
{
"categories": [
{
"title": "## 🚀 Features",
"labels": ["feature", "enhancement"]
},
{
"title": "## 🐛 Fixes",
"labels": ["bug", "fix"]
},
{
"title": "## 📝 Documentation",
"labels": ["documentation"]
}
]
}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}yaml
- name: Build Release Notes
id: release_notes
uses: mikepenz/release-changelog-builder-action@v4
with:
configurationJson: |
{
"categories": [
{
"title": "## 🚀 Features",
"labels": ["feature", "enhancement"]
},
{
"title": "## 🐛 Fixes",
"labels": ["bug", "fix"]
},
{
"title": "## 📝 Documentation",
"labels": ["documentation"]
}
]
}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Monorepo CI/CD Patterns
单体仓库(Monorepo)CI/CD模式
Path-Based Triggers
基于路径的触发器
Run workflows only when specific packages change:
yaml
name: Frontend CI
on:
push:
paths:
- 'packages/frontend/**'
- 'package.json'
- 'pnpm-lock.yaml'
jobs:
test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test frontend
run: pnpm --filter frontend test仅当特定包发生变更时运行工作流:
yaml
name: Frontend CI
on:
push:
paths:
- 'packages/frontend/**'
- 'package.json'
- 'pnpm-lock.yaml'
jobs:
test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test frontend
run: pnpm --filter frontend testAffected Package Detection
变更包检测
yaml
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
affected: ${{ steps.affected.outputs.packages }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect affected packages
id: affected
run: |
# Use tools like Nx or Turborepo to detect changes
AFFECTED=$(npx nx affected:apps --base=origin/main --plain)
echo "packages=$AFFECTED" >> $GITHUB_OUTPUT
test-affected:
needs: detect-changes
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJson(needs.detect-changes.outputs.affected) }}
steps:
- uses: actions/checkout@v4
- name: Test ${{ matrix.package }}
run: npm run test --workspace=${{ matrix.package }}yaml
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
affected: ${{ steps.affected.outputs.packages }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect affected packages
id: affected
run: |
# 使用Nx或Turborepo等工具检测变更
AFFECTED=$(npx nx affected:apps --base=origin/main --plain)
echo "packages=$AFFECTED" >> $GITHUB_OUTPUT
test-affected:
needs: detect-changes
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJson(needs.detect-changes.outputs.affected) }}
steps:
- uses: actions/checkout@v4
- name: Test ${{ matrix.package }}
run: npm run test --workspace=${{ matrix.package }}Turborepo CI
Turborepo CI
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build with Turborepo
run: npx turbo build --cache-dir=.turbo
- name: Cache Turbo
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build with Turborepo
run: npx turbo build --cache-dir=.turbo
- name: Cache Turbo
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-Performance Optimization
性能优化
Parallel Job Execution
任务并行执行
yaml
jobs:
# These jobs run in parallel
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run test:unit
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
# This job waits for all above to complete
deploy:
needs: [lint, unit-test, build]
runs-on: ubuntu-latest
steps:
- run: npm run deployyaml
jobs:
# 这些任务并行运行
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run test:unit
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
# 此任务等待上述所有任务完成后运行
deploy:
needs: [lint, unit-test, build]
runs-on: ubuntu-latest
steps:
- run: npm run deployConditional Job Execution
条件任务执行
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh staging
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh productionyaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh staging
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh productionDependency Caching
依赖缓存
yaml
steps:
# Node.js with npm
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Python with pip
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
# Ruby with bundler
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
# Go modules
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: trueyaml
steps:
# Node.js + npm
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Python + pip
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
# Ruby + bundler
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
# Go模块
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: trueReusable Workflows
可复用工作流
Creating Reusable Workflows
创建可复用工作流
yaml
undefinedyaml
undefined.github/workflows/reusable-deploy.yml
.github/workflows/reusable-deploy.yml
name: Reusable Deploy Workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
version:
required: false
type: string
default: 'latest'
secrets:
deploy-key:
required: true
outputs:
deployment-url:
description: "URL of the deployment"
value: ${{ jobs.deploy.outputs.url }}
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
outputs:
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: actions/checkout@v4
- name: Deploy
id: deploy
env:
DEPLOY_KEY: ${{ secrets.deploy-key }}
run: |
./deploy.sh ${{ inputs.environment }} ${{ inputs.version }}
echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUTundefinedname: Reusable Deploy Workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
version:
required: false
type: string
default: 'latest'
secrets:
deploy-key:
required: true
outputs:
deployment-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: actions/checkout@v4
- name: Deploy
id: deploy
env:
DEPLOY_KEY: ${{ secrets.deploy-key }}
run: |
./deploy.sh ${{ inputs.environment }} ${{ inputs.version }}
echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUTundefinedCalling Reusable Workflows
调用可复用工作流
yaml
undefinedyaml
undefined.github/workflows/main.yml
.github/workflows/main.yml
name: Main Pipeline
on: [push]
jobs:
deploy-staging:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
version: ${{ github.sha }}
secrets:
deploy-key: ${{ secrets.STAGING_DEPLOY_KEY }}
deploy-production:
needs: deploy-staging
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
version: ${{ github.sha }}
secrets:
deploy-key: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
undefinedname: Main Pipeline
on: [push]
jobs:
deploy-staging:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
version: ${{ github.sha }}
secrets:
deploy-key: ${{ secrets.STAGING_DEPLOY_KEY }}
deploy-production:
needs: deploy-staging
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
version: ${{ github.sha }}
secrets:
deploy-key: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
undefinedInfrastructure as Code
基础设施即代码
Terraform Deployment
Terraform部署
yaml
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.0
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Init
run: terraform init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -out=tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}yaml
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.0
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Init
run: terraform init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -out=tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}AWS CloudFormation
AWS CloudFormation
yaml
jobs:
deploy-cloudformation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Deploy CloudFormation stack
run: |
aws cloudformation deploy \
--template-file infrastructure/template.yml \
--stack-name my-app-stack \
--parameter-overrides \
Environment=production \
Version=${{ github.sha }} \
--capabilities CAPABILITY_IAMyaml
jobs:
deploy-cloudformation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Deploy CloudFormation stack
run: |
aws cloudformation deploy \
--template-file infrastructure/template.yml \
--stack-name my-app-stack \
--parameter-overrides \
Environment=production \
Version=${{ github.sha }} \
--capabilities CAPABILITY_IAMBest Practices
最佳实践
Workflow Organization
工作流组织
- Separate concerns: Different workflows for CI, CD, and scheduled tasks
- Use descriptive names: Clear workflow and job names
- Organize with directories: Group related workflows
- Version control: Track workflow changes like code
- 关注点分离:为CI、CD和定时任务使用不同工作流
- 使用描述性名称:清晰的工作流和任务名称
- 按目录组织:将相关工作流分组
- 版本控制:像代码一样跟踪工作流变更
Efficiency
效率
- Cache dependencies: Reduce build times significantly
- Parallel execution: Run independent jobs simultaneously
- Conditional runs: Skip unnecessary jobs
- Matrix strategies: Test multiple configurations efficiently
- Artifact reuse: Share build outputs between jobs
- 缓存依赖:显著缩短构建时间
- 并行执行:同时运行独立任务
- 条件执行:跳过不必要的任务
- 矩阵策略:高效测试多配置
- 产物复用:在任务间共享构建输出
Security
安全性
- Minimize permissions: Use least-privilege principle
- Use OIDC: Avoid long-lived credentials
- Secret rotation: Regularly update secrets
- Pin dependencies: Use specific versions or SHAs
- Scan for vulnerabilities: Automated security checks
- 最小化权限:遵循最小权限原则
- 使用OIDC:避免长期凭证
- 密钥轮换:定期更新密钥
- 固定依赖版本:使用特定版本或SHA
- 漏洞扫描:自动化安全检查
Reliability
可靠性
- Timeout settings: Prevent hanging jobs
- Retry logic: Handle transient failures
- Failure notifications: Alert on critical failures
- Rollback mechanisms: Quick recovery from failed deployments
- Health checks: Verify deployments before marking complete
- 超时设置:防止任务挂起
- 重试逻辑:处理临时故障
- 故障通知:关键故障时发出警报
- 回滚机制:从失败部署中快速恢复
- 健康检查:在标记完成前验证部署状态
Observability
可观测性
- Detailed logging: Clear, actionable logs
- Status checks: Prevent merging failing builds
- Deployment tracking: Know what's deployed where
- Metrics collection: Track pipeline performance
- Audit trails: Track who deployed what and when
- 详细日志:清晰、可操作的日志
- 状态检查:防止合并失败的构建
- 部署跟踪:了解各环境部署内容
- 指标收集:跟踪流水线性能
- 审计追踪:记录谁在何时部署了什么
Failure Handling
故障处理
Retry Failed Steps
重试失败步骤
yaml
steps:
- name: Deploy with retry
uses: nick-fields/retry-action@v2
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 30
command: npm run deployyaml
steps:
- name: Deploy with retry
uses: nick-fields/retry-action@v2
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 30
command: npm run deployContinue on Error
错误后继续执行
yaml
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run optional check
continue-on-error: true
run: npm run optional-check
- name: Run required tests
run: npm testyaml
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run optional check
continue-on-error: true
run: npm run optional-check
- name: Run required tests
run: npm testConditional Cleanup
条件清理
yaml
steps:
- name: Deploy
id: deploy
run: ./deploy.sh
- name: Rollback on failure
if: failure() && steps.deploy.conclusion == 'failure'
run: ./rollback.sh
- name: Cleanup
if: always()
run: ./cleanup.shyaml
steps:
- name: Deploy
id: deploy
run: ./deploy.sh
- name: Rollback on failure
if: failure() && steps.deploy.conclusion == 'failure'
run: ./rollback.sh
- name: Cleanup
if: always()
run: ./cleanup.shAdvanced Patterns
高级模式
Dynamic Matrix Generation
动态矩阵生成
yaml
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- id: set-matrix
run: |
# Generate matrix based on project structure
MATRIX=$(find packages -maxdepth 1 -type d -not -name packages | \
jq -R -s -c 'split("\n")[:-1]')
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
test:
needs: generate-matrix
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- run: npm test --workspace=${{ matrix.package }}yaml
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- id: set-matrix
run: |
# 基于项目结构生成矩阵
MATRIX=$(find packages -maxdepth 1 -type d -not -name packages | \
jq -R -s -c 'split("\n")[:-1]')
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
test:
needs: generate-matrix
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- run: npm test --workspace=${{ matrix.package }}Composite Actions
复合Actions
Create reusable action combinations:
yaml
undefined创建可复用的Action组合:
yaml
undefined.github/actions/setup-project/action.yml
.github/actions/setup-project/action.yml
name: 'Setup Project'
description: 'Setup Node.js and install dependencies'
inputs:
node-version:
description: 'Node.js version'
required: false
default: '20'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
shell: bash
- run: npm run build
shell: bash
**Usage:**
```yaml
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
node-version: '20'name: '项目初始化'
description: '配置Node.js并安装依赖'
inputs:
node-version:
description: 'Node.js版本'
required: false
default: '20'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
shell: bash
- run: npm run build
shell: bash
**使用方式:**
```yaml
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
node-version: '20'Self-Hosted Runners
自托管运行器
yaml
jobs:
deploy:
runs-on: [self-hosted, linux, production]
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.shBenefits:
- Custom hardware/software requirements
- Faster builds (pre-cached dependencies)
- Access to internal networks
- Cost savings for high-volume CI/CD
yaml
jobs:
deploy:
runs-on: [self-hosted, linux, production]
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.sh优势:
- 自定义硬件/软件需求
- 构建更快(预缓存依赖)
- 可访问内部网络
- 高流量CI/CD场景下节省成本
Platform-Specific Deployments
特定平台部署
Vercel Deployment
Vercel部署
yaml
jobs:
deploy-vercel:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'yaml
jobs:
deploy-vercel:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'Netlify Deployment
Netlify部署
yaml
jobs:
deploy-netlify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v3
with:
publish-dir: './dist'
production-branch: main
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: 'Deploy from GitHub Actions'
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}yaml
jobs:
deploy-netlify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v3
with:
publish-dir: './dist'
production-branch: main
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: 'Deploy from GitHub Actions'
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}AWS ECS Deployment
AWS ECS部署
yaml
jobs:
deploy-ecs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: my-app
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Update ECS service
run: |
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--force-new-deploymentyaml
jobs:
deploy-ecs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: my-app
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Update ECS service
run: |
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--force-new-deploymentKubernetes Deployment
Kubernetes部署
yaml
jobs:
deploy-k8s:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubeconfig
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig.yml
echo "KUBECONFIG=$(pwd)/kubeconfig.yml" >> $GITHUB_ENV
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/myapp \
myapp=myregistry/myapp:${{ github.sha }}
kubectl rollout status deployment/myappSkill Version: 1.0.0
Last Updated: October 2025
Skill Category: DevOps, CI/CD, Automation, Deployment
Compatible With: GitHub Actions, Docker, Kubernetes, AWS, Azure, GCP, Vercel, Netlify
yaml
jobs:
deploy-k8s:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubeconfig
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig.yml
echo "KUBECONFIG=$(pwd)/kubeconfig.yml" >> $GITHUB_ENV
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/myapp \
myapp=myregistry/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp技能版本:1.0.0
最后更新:2025年10月
技能分类:DevOps、CI/CD、自动化、部署
兼容平台:GitHub Actions、Docker、Kubernetes、AWS、Azure、GCP、Vercel、Netlify