0%

CI/CD 流水线设计

一、前言

CI/CD(持续集成/持续交付)是现代软件开发的核心理念。根据 2026 年 DevOps 状态报告,采用 CI/CD 的团队:

  • 部署频率提升 46 倍
  • 变更前置时间缩短 440 倍
  • 服务恢复时间缩短 2564 倍
  • 变更失败率降低 7 倍

CI/CD 的核心价值:

  • 自动化构建:代码提交自动触发构建
  • 自动化测试:单元测试、集成测试自动执行
  • 自动化部署:通过流水线自动部署到各环境
  • 快速反馈:问题尽早发现和修复
  • 降低风险:小步快跑,降低单次变更风险

本文将详细介绍 CI/CD 流水线设计,涵盖主流平台配置、最佳实践和实战案例。


二、CI/CD 核心概念

2.1 流水线阶段

1
2
3
4
5
6
7
8
9
10
11
12
graph LR
A[代码提交] --> B[构建 Build]
B --> C[测试 Test]
C --> D[扫描 Scan]
D --> E[部署 Deploy]
E --> F[监控 Monitor]

B --> B1[编译<br/>打包<br/>镜像构建]
C --> C1[单元测试<br/>集成测试<br/>E2E 测试]
D --> D1[代码质量<br/>安全扫描<br/>漏洞检测]
E --> E1[开发环境<br/>测试环境<br/>生产环境]
F --> F1[性能监控<br/>日志收集<br/>告警通知]

2.2 环境策略

1
2
3
4
5
6
7
8
9
graph TB
A[开发环境 Dev] -->|自动部署 | B[测试环境 Test]
B -->|手动确认 | C[预发环境 Staging]
C -->|手动确认 | D[生产环境 Prod]

A --> A1[每次提交]
B --> B1[测试通过]
C --> C1[验收通过]
D --> D1[正式发布]

环境说明

环境 用途 部署方式 数据
Dev 开发测试 自动 模拟数据
Test 集成测试 自动 测试数据
Staging 预发验证 手动 生产脱敏
Prod 生产环境 手动 真实数据

三、GitHub Actions 流水线

3.1 基础配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# .github/workflows/ci.yml
name: CI Pipeline

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
# 1. 代码检查
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run linter
run: npm run lint

- name: Run type check
run: npm run type-check

# 2. 单元测试
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test -- --coverage

- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info

# 3. 构建
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

3.2 Docker 构建与推送

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# .github/workflows/docker.yml
name: Docker Build and Push

on:
push:
branches: [main]
tags: ['v*.*.*']

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run security scan
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'

- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'

3.3 多环境部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# .github/workflows/deploy.yml
name: Deploy to Environments

on:
push:
branches: [main, develop]
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'dev'
type: choice
options:
- dev
- test
- staging
- prod

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.environment || 'dev' }}
url: ${{ vars.DEPLOY_URL }}

steps:
- uses: actions/checkout@v4

- name: Deploy to ${{ github.event.inputs.environment || 'dev' }}
run: |
echo "Deploying to ${{ github.event.inputs.environment || 'dev' }}"
# 添加实际部署命令
# kubectl set image deployment/app app=myapp:${{ github.sha }}

- name: Health check
run: |
curl -f ${{ vars.DEPLOY_URL }}/health || exit 1

- name: Notify Slack
if: always()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Deployed to ${{ github.event.inputs.environment || 'dev' }}: ${{ job.status }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

四、GitLab CI 流水线

4.1 完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# .gitlab-ci.yml
stages:
- validate
- test
- build
- scan
- deploy
- monitor

variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
DOCKER_TLS_CERTDIR: "/certs"

# 1. 代码验证
validate:
stage: validate
image: node:18-alpine
script:
- npm ci
- npm run lint
- npm run type-check
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH

# 2. 单元测试
unit-test:
stage: test
image: node:18-alpine
script:
- npm ci
- npm test -- --coverage
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
paths:
- coverage/
expire_in: 1 week
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
rules:
- if: $CI_COMMIT_BRANCH

# 3. 集成测试
integration-test:
stage: test
image: docker:24
services:
- docker:24-dind
- postgres:15-alpine
- redis:7-alpine
script:
- docker build -t $DOCKER_IMAGE .
- docker run --rm \
-e DATABASE_URL=postgresql://postgres:postgres@postgres/postgres \
-e REDIS_URL=redis://redis:6379 \
$DOCKER_IMAGE npm run test:integration
rules:
- if: $CI_COMMIT_BRANCH == "develop"
- if: $CI_COMMIT_BRANCH == "main"

# 4. 构建镜像
build:
stage: build
image: docker:24
services:
- docker:24-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
artifacts:
reports:
dotenv: build.env
rules:
- if: $CI_COMMIT_BRANCH == "develop"
- if: $CI_COMMIT_BRANCH == "main"

# 5. 安全扫描
security-scan:
stage: scan
image: aquasec/trivy:latest
script:
- trivy image --exit-code 0 --format sarif --output trivy-results.sarif $DOCKER_IMAGE
artifacts:
reports:
container_scanning: trivy-results.sarif
paths:
- trivy-results.sarif
rules:
- if: $CI_COMMIT_BRANCH == "main"
allow_failure: true

# 6. 部署到开发环境
deploy-dev:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE
environment:
name: development
url: https://dev.example.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"

# 7. 部署到测试环境
deploy-test:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE
environment:
name: test
url: https://test.example.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"
when: delayed
start_in: 5 minutes

# 8. 部署到预发环境(手动)
deploy-staging:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
needs:
- build
- security-scan

# 9. 部署到生产环境(手动)
deploy-prod:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE
environment:
name: production
url: https://www.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
needs:
- deploy-staging
when: manual

# 10. 部署后验证
post-deploy-check:
stage: monitor
image: curlimages/curl:latest
script:
- curl -f $DEPLOY_URL/health
- curl -f $DEPLOY_URL/api/status
environment:
name: production
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: on_success

4.2 模板复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# .gitlab/ci/templates.yml
# 定义可复用模板
.node_template: &node_template
image: node:18-alpine
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
before_script:
- npm ci

.deploy_template: &deploy_template
image: bitnami/kubectl:latest
before_script:
- kubectl config use-context $KUBE_CONTEXT
after_script:
- kubectl rollout status deployment/app

# 使用模板
test:
<<: *node_template
script:
- npm test

deploy:
<<: *deploy_template
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE

五、Jenkins Pipeline

5.1 声明式 Pipeline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Jenkinsfile
pipeline {
agent any

options {
buildDiscarder(logRotator(numToKeepStr: '10'))
timeout(time: 1, unit: 'HOURS')
timestamps()
}

environment {
DOCKER_IMAGE = "myapp:${env.BUILD_NUMBER}"
REGISTRY = "harbor.example.com"
}

stages {
stage('Checkout') {
steps {
checkout scm
}
}

stage('Lint') {
steps {
sh 'npm ci'
sh 'npm run lint'
sh 'npm run type-check'
}
}

stage('Test') {
steps {
sh 'npm test -- --coverage'
}
post {
always {
junit 'reports/*.xml'
publishCoverage adapters: [coberturaAdapter('coverage/cobertura-coverage.xml')]
}
}
}

stage('Build Docker Image') {
steps {
script {
docker.build("${env.DOCKER_IMAGE}")
}
}
}

stage('Security Scan') {
steps {
sh '''
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image ${DOCKER_IMAGE}
'''
}
}

stage('Push Image') {
steps {
script {
docker.withRegistry("https://${env.REGISTRY}", 'harbor-credentials') {
docker.image("${env.DOCKER_IMAGE}").push()
}
}
}
}

stage('Deploy to Dev') {
when {
branch 'develop'
}
steps {
sh '''
kubectl set image deployment/app \
app=${REGISTRY}/${DOCKER_IMAGE}
'''
}
}

stage('Deploy to Prod') {
when {
branch 'main'
}
input {
message "Deploy to production?"
ok "Deploy"
}
steps {
sh '''
kubectl set image deployment/app \
app=${REGISTRY}/${DOCKER_IMAGE}
kubectl rollout status deployment/app
'''
}
}
}

post {
always {
cleanWs()
}
success {
slackSend(color: 'good', message: "Build ${env.BUILD_NUMBER} succeeded")
}
failure {
slackSend(color: 'danger', message: "Build ${env.BUILD_NUMBER} failed")
}
}
}

5.2 脚本式 Pipeline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Jenkinsfile.scripted
node('docker') {
stage('Checkout') {
checkout scm
}

stage('Build') {
docker.image('node:18-alpine').inside {
sh 'npm ci'
sh 'npm run build'
}
}

stage('Test') {
docker.image('node:18-alpine').inside {
sh 'npm test'
}
}

stage('Deploy') {
if (env.BRANCH_NAME == 'main') {
input message: 'Deploy to production?'
}

sh "kubectl set image deployment/app app=myapp:${env.BUILD_NUMBER}"
}
}

六、实战案例

案例 1:Node.js 微服务 CI/CD

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
myapp/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ ├── docker.yml
│ └── deploy.yml
├── src/
├── tests/
├── Dockerfile
├── docker-compose.yml
├── package.json
└── README.md

完整流水线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# .github/workflows/pipeline.yml
name: Full Pipeline

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
# 第一阶段:验证
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Type check
run: npm run type-check

- name: Security audit
run: npm audit --audit-level=moderate

# 第二阶段:测试
test:
runs-on: ubuntu-latest
needs: validate
services:
postgres:
image: postgres:15
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-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Unit tests
run: npm test -- --coverage

- name: Integration tests
run: npm run test:integration
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
REDIS_URL: redis://localhost:6379

- name: Upload coverage
uses: codecov/codecov-action@v3

# 第三阶段:构建
build:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push'

steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Registry
uses: docker/login-action@v3
with:
registry: harbor.example.com
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
harbor.example.com/myapp:${{ github.sha }}
harbor.example.com/myapp:${{ github.ref_name }}
cache-from: type=gha
cache-to: type=gha,mode=max

# 第四阶段:部署
deploy-dev:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
environment: development

steps:
- uses: actions/checkout@v4

- name: Setup kubectl
uses: azure/setup-kubectl@v3

- name: Configure kubectl
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig

- name: Deploy
run: |
kubectl set image deployment/myapp \
myapp=harbor.example.com/myapp:${{ github.sha }}

- name: Health check
run: |
kubectl rollout status deployment/myapp
curl -f https://dev.example.com/health

deploy-prod:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment: production

steps:
- uses: actions/checkout@v4

- name: Setup kubectl
uses: azure/setup-kubectl@v3

- name: Configure kubectl
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig

- name: Deploy
run: |
kubectl set image deployment/myapp \
myapp=harbor.example.com/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp

- name: Smoke tests
run: |
curl -f https://www.example.com/health
curl -f https://www.example.com/api/status

案例 2:Python 数据平台 CI/CD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# .gitlab-ci.yml
stages:
- test
- build
- deploy

variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

cache:
paths:
- .cache/pip/
- venv/

# 测试
test:
stage: test
image: python:3.11-slim
before_script:
- pip install --upgrade pip
- pip install -r requirements-dev.txt
script:
- pytest --cov=src --cov-report=xml
- flake8 src/
- mypy src/
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
rules:
- if: $CI_COMMIT_BRANCH

# 构建
build:
stage: build
image: docker:24
services:
- docker:24-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
rules:
- if: $CI_COMMIT_BRANCH == "main"

# 部署
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/data-platform api=$DOCKER_IMAGE
- kubectl rollout status deployment/data-platform
environment:
name: production
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual

七、最佳实践

7.1 流水线设计原则

1
2
3
4
5
6
7
8
9
10
11
12
graph TB
A[流水线设计原则] --> B[快速反馈]
A --> C[失败优先]
A --> D[幂等性]
A --> E[可追溯]
A --> F[安全性]

B --> B1[快速失败<br/>并行执行<br/>缓存优化]
C --> C1[先 lint 后测试<br/>先单元后集成]
D --> D1[可重复执行<br/>状态无关]
E --> E1[完整日志<br/>版本标记]
F --> F1[密钥管理<br/>权限控制]

7.2 优化技巧

1. 并行执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# GitHub Actions
jobs:
test:
strategy:
matrix:
node-version: [16, 18, 20]
os: [ubuntu-latest, macos-latest]

runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm test

2. 缓存优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 缓存 node_modules
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-

# 缓存 Docker 层
- name: Build and push
uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max

3. 条件执行

1
2
3
4
5
6
7
8
9
10
11
12
# 仅在生产分支部署
deploy-prod:
if: github.ref == 'refs/heads/main'
steps: ...

# 跳过 CI(在提交信息中添加 [skip ci])
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'

7.3 安全实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 使用 OIDC 代替长期凭证
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::123456789:role/github-role
aws-region: us-east-1

# 2. 限制权限
permissions:
contents: read
packages: write

# 3. 密钥扫描
- name: Secret scanning
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}

八、总结

CI/CD 检查清单

  • 代码提交自动触发构建
  • 自动化测试覆盖核心功能
  • 代码质量检查(lint、type check)
  • 安全扫描(依赖漏洞、镜像漏洞)
  • 多环境部署策略
  • 手动审批流程(生产环境)
  • 部署后健康检查
  • 失败通知机制
  • 构建缓存优化
  • 密钥安全管理

关键指标

指标 目标 测量方式
构建时间 < 10 分钟 流水线耗时
测试覆盖率 > 80% 代码覆盖率报告
部署频率 每天多次 部署次数统计
部署成功率 > 95% 成功/总部署
恢复时间 < 1 小时 故障恢复耗时

最后更新: 2026-03-12

标签: #CI/CD #流水线 #DevOps #自动化 #持续交付

分类: DevOps/CI/CD

参考资料: