CI/CD (持续集成/持续交付)
一、基本概念
1.1 CI (Continuous Integration)
- 持续集成
- 频繁地将代码集成到主干
- 自动化构建和测试
1.2 CD (Continuous Delivery/Deployment)
- 持续交付/部署
- 自动化发布流程
- 确保可随时部署
术语:
- action: 动作,指可以复用的代码片段,如安装依赖、打包、部署等。
- cache: 缓存,指将依赖缓存到本地,下次构建时直接使用缓存,从而减少构建时间。
- runner: 运行器,指执行CI/CD任务的机器。
- job: 任务,如构建任务、测试任务、部署任务等。每个 workflow 可以有多个 job,而每个 job 可以有多个 step。
- step: 步骤,如安装依赖、打包、部署等。
- webhook: 钩子,指触发CI/CD任务的事件。
- workflow: 工作流,指整个CI/CD流程。
二、工作流程
2.1 基本流程
代码提交 -> 自动构建 -> 自动测试 -> 自动部署
GitHub Actions Workflow 工作流程图
graph TD A[代码推送到main分支] -->|触发| B[Workflow 开始] B --> C[Job: deploy
运行环境: ubuntu-latest] subgraph "构建部署作业" C -->|Step 1| D[检出代码
checkout@v4] D -->|Step 2| E[检查缓存
cache@v4] E -->|缓存未命中| F[安装依赖
npm install] E -->|缓存命中| G[跳过安装] F --> H[设置 Node.js v16
setup-node@v4] G --> H H --> I[构建项目
npm run docs:build] I --> J[部署到服务器
scp-action] J -->|配置| K[host/username/password
从 secrets 获取] end J -->|成功| L[部署完成] J -->|失败| M[构建失败] L --> N[工作流结束] M --> N style A fill:#fbb,stroke:#333,stroke-width:2px style B fill:#bbf,stroke:#333,stroke-width:2px style L fill:#bfb,stroke:#333,stroke-width:2px style M fill:#fbb,stroke:#333,stroke-width:2px style K fill:#ffd,stroke:#333,stroke-width:2px
2.2 详细步骤
javascript
// 1. 开发者提交代码
git push origin feature/new-feature
// 2. 触发 CI 流程
// .github/workflows/ci.yml
name: 打包与部署
on:
push:
branches:
- main
jobs:
deploy:
name: npm-build 工作
runs-on: ubuntu-latest
steps:
- name: 读取markdown文件
uses: actions/checkout@v4
- name: 安装依赖
run: npm install
- name: 设置Node.js
uses: actions/setup-node@v4
with:
node-version: '16'
- name: 打包
run: npm run docs:build
- name: 部署到服务器
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USERNAME }}
password: ${{ secrets.SERVER_PASSWORD }}
source: "markdown/.vitepress/dist/*"
target: "/blog"
timeout: 60s
port: 22 # 明确指定端口
strip_components: 3
三、常用工具
3.1 CI/CD 平台
- Jenkins 优点:灵活性高,可以自定义很多步骤和逻辑。 缺点:配置复杂,需要手动配置。
- GitHub Actions 优点:简单易用,配置简单。 缺点:灵活性不如Jenkins。
- GitLab CI 优点:与GitLab集成紧密,方便管理。 缺点:但项目放到gitLab上,就谈不上开源了。
- Travis CI
3.2 配置示例
javascript
// Jenkins Pipeline
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm run test'
}
}
stage('Deploy') {
steps {
sh './deploy.sh'
}
}
}
}
Jenkins 配置比较复杂,但也更灵活,可以自定义很多步骤和逻辑。 我这里采用的是GitHub Actions。
四、最佳实践
4.1 构建策略
javascript
// package.json
{
"scripts": {
"build:dev": "webpack --mode development",
"build:prod": "webpack --mode production",
"test": "jest",
"lint": "eslint src"
}
}
4.2 自动化测试
- 单元测试
- 集成测试
- E2E测试
4.3 部署策略
javascript
// deploy.sh
#!/bin/bash
# 生产环境部署脚本
echo "Deploying to production..."
# 1. 构建应用
npm run build:prod
# 2. 上传到服务器
scp -r dist/* user@server:/path/to/deploy
# 3. 重启服务
ssh user@server "pm2 restart app"
五、优势
5.1 开发效率
- 自动化流程
- 快速反馈
- 降低人为错误
5.2 代码质量
- 规范检查
- 自动化测试
- 代码审查
5.3 部署效率
- 一键部署
- 回滚机制
- 环境一致性
六、注意事项
6.1 安全考虑
javascript
// 环境变量配置
// .env.production
API_KEY=xxx
DATABASE_URL=xxx
// 在 CI 中使用
process.env.API_KEY
process.env.DATABASE_URL
注:账号密码等不要直接写在代码中,要通过环境变量来获取。
6.2 性能优化
- 缓存依赖
- 并行构建
- 增量部署
七、常见问题
7.1 构建失败
javascript
// 常见原因
- 依赖问题
- 环境变量缺失
- 测试用例失败
7.2 部署失败
javascript
// 排查步骤
1. 检查日志
2. 验证配置
3. 环境一致性