302 lines
6.5 KiB
Markdown
302 lines
6.5 KiB
Markdown
# CI/CD 流水线配置
|
||
|
||
:::tip 说明
|
||
CI/CD(持续集成/持续部署)是现代开发流程的基础设施。本文介绍如何为本项目配置自动化测试、构建和部署流水线。
|
||
:::
|
||
|
||
## GitHub Actions
|
||
|
||
### 基础配置
|
||
|
||
创建 `.github/workflows/ci.yml`:
|
||
|
||
```yaml
|
||
name: CI
|
||
|
||
on:
|
||
push:
|
||
branches: [main, develop]
|
||
pull_request:
|
||
branches: [main]
|
||
|
||
jobs:
|
||
# 后端测试
|
||
backend-test:
|
||
runs-on: ubuntu-latest
|
||
services:
|
||
mysql:
|
||
image: mysql:8.0
|
||
env:
|
||
MYSQL_ROOT_PASSWORD: root
|
||
MYSQL_DATABASE: test_djangoadmin
|
||
ports:
|
||
- 3306:3306
|
||
redis:
|
||
image: redis:6.0
|
||
ports:
|
||
- 6379:6379
|
||
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Set up Python
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.12'
|
||
|
||
- name: Install dependencies
|
||
run: |
|
||
pip install -r requirements.txt
|
||
pip install coverage
|
||
|
||
- name: Run tests
|
||
env:
|
||
DATABASE_ENGINE: mysql
|
||
DATABASE_NAME: test_djangoadmin
|
||
DATABASE_HOST: 127.0.0.1
|
||
DATABASE_PORT: 3306
|
||
DATABASE_USER: root
|
||
DATABASE_PASSWORD: root
|
||
REDIS_HOST: 127.0.0.1
|
||
REDIS_PORT: 6379
|
||
run: |
|
||
coverage run --source='application' manage.py test
|
||
coverage report
|
||
|
||
# 前端检查
|
||
frontend-check:
|
||
runs-on: ubuntu-latest
|
||
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Set up Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '18'
|
||
|
||
- name: Install pnpm
|
||
run: npm install -g pnpm
|
||
|
||
- name: Install dependencies
|
||
working-directory: ./ui
|
||
run: pnpm install
|
||
|
||
- name: Type check
|
||
working-directory: ./ui
|
||
run: pnpm type:check
|
||
|
||
- name: Lint
|
||
working-directory: ./ui
|
||
run: pnpm lint:eslint
|
||
|
||
- name: Build
|
||
working-directory: ./ui
|
||
run: pnpm build
|
||
```
|
||
|
||
### 自动部署
|
||
|
||
```yaml
|
||
# 自动部署到服务器
|
||
deploy:
|
||
needs: [backend-test, frontend-check]
|
||
runs-on: ubuntu-latest
|
||
if: github.ref == 'refs/heads/main'
|
||
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Deploy to server
|
||
uses: appleboy/ssh-action@v1
|
||
with:
|
||
host: ${{ secrets.SERVER_HOST }}
|
||
username: ${{ secrets.SERVER_USER }}
|
||
key: ${{ secrets.SSH_KEY }}
|
||
script: |
|
||
cd /opt/djangoadmin
|
||
git pull origin main
|
||
source /opt/venv/bin/activate
|
||
pip install -r requirements.txt
|
||
python manage.py migrate
|
||
supervisorctl restart djangoadmin
|
||
```
|
||
|
||
## Gitee Go
|
||
|
||
### 基础配置
|
||
|
||
创建 `.gitee/pipeline.yml`:
|
||
|
||
```yaml
|
||
name: CI Pipeline
|
||
|
||
trigger:
|
||
push:
|
||
branches:
|
||
- main
|
||
- develop
|
||
|
||
stages:
|
||
- stage:
|
||
name: test
|
||
jobs:
|
||
- job:
|
||
name: backend-test
|
||
steps:
|
||
- step: python
|
||
name: Run tests
|
||
script:
|
||
- pip install -r requirements.txt
|
||
- python manage.py test
|
||
|
||
- job:
|
||
name: frontend-check
|
||
steps:
|
||
- step: node
|
||
name: Build frontend
|
||
script:
|
||
- cd ui
|
||
- npm install -g pnpm
|
||
- pnpm install
|
||
- pnpm type:check
|
||
- pnpm build
|
||
```
|
||
|
||
## 自动化测试集成
|
||
|
||
### pytest 配置
|
||
|
||
```ini
|
||
# pytest.ini
|
||
[pytest]
|
||
DJANGO_SETTINGS_MODULE = application.settings
|
||
python_files = tests.py test_*.py
|
||
python_classes = Test*
|
||
python_functions = test_*
|
||
addopts = -v --tb=short
|
||
```
|
||
|
||
### 测试脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# scripts/test.sh
|
||
|
||
set -e
|
||
|
||
echo "=== Running Python tests ==="
|
||
coverage run --source='application' manage.py test -v 2
|
||
coverage report --fail-under=80
|
||
|
||
echo "=== Running frontend type check ==="
|
||
cd ui && pnpm type:check
|
||
|
||
echo "=== Running frontend lint ==="
|
||
pnpm lint:eslint
|
||
|
||
echo "=== All checks passed! ==="
|
||
```
|
||
|
||
## 自动化部署
|
||
|
||
### SSH 部署
|
||
|
||
```yaml
|
||
# GitHub Actions
|
||
- name: Deploy via SSH
|
||
uses: appleboy/ssh-action@v1
|
||
with:
|
||
host: ${{ secrets.SERVER_HOST }}
|
||
username: ${{ secrets.SERVER_USER }}
|
||
key: ${{ secrets.SSH_KEY }}
|
||
script: |
|
||
cd /opt/djangoadmin
|
||
git pull origin main
|
||
source /opt/venv/bin/activate
|
||
pip install -r requirements.txt
|
||
python manage.py migrate
|
||
cd ui && pnpm install && pnpm build
|
||
sudo supervisorctl restart djangoadmin
|
||
sudo nginx -s reload
|
||
```
|
||
|
||
### Docker 部署
|
||
|
||
```yaml
|
||
# GitHub Actions
|
||
- name: Build and push Docker image
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
push: true
|
||
tags: your-registry/djangoadmin:latest
|
||
|
||
- name: Deploy to server
|
||
uses: appleboy/ssh-action@v1
|
||
with:
|
||
script: |
|
||
docker pull your-registry/djangoadmin:latest
|
||
docker-compose up -d
|
||
```
|
||
|
||
### Webhook 部署
|
||
|
||
```python
|
||
# application/webhook/views.py
|
||
import hmac
|
||
from django.http import JsonResponse
|
||
|
||
def webhook_deploy(request):
|
||
"""Webhook 自动部署"""
|
||
# 验证签名
|
||
signature = request.META.get('HTTP_X_HUB_SIGNATURE_256')
|
||
secret = os.getenv('WEBHOOK_SECRET', '').encode()
|
||
expected = 'sha256=' + hmac.new(secret, request.body, 'sha256').hexdigest()
|
||
|
||
if not hmac.compare_digest(signature, expected):
|
||
return JsonResponse({'error': 'Invalid signature'}, status=403)
|
||
|
||
# 执行部署脚本
|
||
subprocess.Popen(['/opt/scripts/deploy.sh'])
|
||
return JsonResponse({'status': 'deploying'})
|
||
```
|
||
|
||
## 环境管理
|
||
|
||
### 多环境配置
|
||
|
||
| 环境 | 分支 | 用途 | 部署方式 |
|
||
|------|------|------|---------|
|
||
| 开发环境 | develop | 日本地开发 | 手动 |
|
||
| 测试环境 | develop | 功能测试 | 自动(push 触发) |
|
||
| 预发环境 | release/* | 上线前验证 | 手动触发 |
|
||
| 生产环境 | main | 正式环境 | 手动触发 |
|
||
|
||
### 环境变量管理
|
||
|
||
```yaml
|
||
# GitHub Secrets
|
||
SERVER_HOST: 192.168.1.100
|
||
SERVER_USER: deploy
|
||
SSH_KEY: -----BEGIN OPENSSH PRIVATE KEY-----...
|
||
DB_PASSWORD: your_secure_password
|
||
JWT_SALT: your_jwt_secret
|
||
```
|
||
|
||
## 部署 Checklist
|
||
|
||
```
|
||
1. ✅ 代码审查通过
|
||
2. ✅ 自动化测试通过
|
||
3. ✅ 前端构建成功
|
||
4. ✅ 数据库迁移执行
|
||
5. ✅ 静态文件收集
|
||
6. ✅ 服务重启
|
||
7. ✅ 健康检查通过
|
||
8. ✅ 回滚方案准备
|
||
```
|
||
|
||
## 总结
|
||
|
||
CI/CD 流水线配置涵盖 GitHub Actions、Gitee Go、自动化测试、自动化部署(SSH/Docker/Webhook)、环境管理等方面。核心原则:自动化测试先行、分环境部署、手动触发生产发布、保留回滚能力。
|