CI/CD 是通过自动化流程完成代码检查、测试、构建和部署的工程实践。
1. CI 与 CD
| 概念 | 全称 | 主要作用 |
|---|---|---|
| CI | Continuous Integration | 持续集成,自动测试和验证代码 |
| CD | Continuous Delivery | 持续交付,保证代码随时可以发布 |
| CD | Continuous Deployment | 持续部署,验证通过后自动发布到生产环境 |
典型流程:
Developer
↓
Git Push / Pull Request
↓
GitHub Actions
│
├── Lint / Type Check
├── Unit / Integration Tests
└── Build
↓
CI Passed
↓
Docker Image
↓
Image Registry
↓
Deployment Server
↓
Running Application
CI 负责保证代码质量,CD 负责交付和部署。
CI 并不要求必须自动部署;可以先实现 CI,再逐步增加 CD。
2. GitHub Actions 核心模型
GitHub Actions 是 GitHub 提供的自动化工作流平台。
GitHub Event
↓
Workflow
↓
Jobs
↓
Runner
↓
Steps
├── uses: Action
└── run: Shell Command
核心概念:
| 概念 | 含义 |
|---|---|
| Workflow | 完整自动化流程,使用 YAML 定义 |
| Event | 触发 Workflow 的事件 |
| Job | 一组在同一 Runner 上执行的任务 |
| Step | Job 内的单个执行步骤 |
| Runner | 执行 Job 的机器 |
| Action | 可复用的自动化步骤 |
| Artifact | Workflow 产生的文件或构建结果 |
| Secret | 加密管理的敏感配置 |
Workflow 文件保存在:
.github/
└── workflows/
├── ci.yml
└── deploy.yml
一个仓库可以定义多个 Workflow。
3. 基本 Workflow
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
run: pytest
执行过程:
Push to main / PR to main
↓
Start Workflow
↓
Create Ubuntu Runner
↓
Checkout Code
↓
Install Python
↓
Install Dependencies
↓
pytest
↓
Pass / Fail
这里假设项目依赖及测试环境已经正确配置。如果 Django 使用 PostgreSQL,还需要提供测试数据库服务。
重要 YAML 字段
| 字段 | 作用 |
|---|---|
name | Workflow 或 Step 名称 |
on | 触发条件 |
jobs | 定义 Job |
runs-on | 选择 Runner |
steps | 定义执行步骤 |
uses | 调用现有 Action |
run | 执行 Shell 命令 |
with | 传递 Action 参数 |
env | 设置环境变量 |
if | 条件执行 |
needs | Job 之间的依赖 |
permissions | GITHUB_TOKEN 权限 |
concurrency | 控制并发执行 |
uses 与 run 的区别:
- uses: actions/checkout@v4
调用已经实现的 Action。
- run: pytest
直接执行命令。
4. Event:Workflow 触发条件
Push
on:
push:
branches: [main]
每次向 main 推送代码时触发。
Pull Request
on:
pull_request:
branches: [main]
创建或更新目标为 main 的 PR 时触发。
手动触发
on:
workflow_dispatch:
可以在 GitHub Actions 页面手动运行。
Tag / Release
on:
push:
tags:
- "v*"
例如推送 v1.2.0 时执行发布。
定时任务
on:
schedule:
- cron: "0 2 * * *"
使用 UTC 时间,每天计划在 02:00 触发。定时 Workflow 可能发生延迟,并不保证严格准时。
5. Job、Step 与 Runner
一个 Workflow 可以包含多个 Job:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "Testing"
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building"
默认情况下,不同 Job 可以并行执行。
同一个 Job 中的 Steps 通常按顺序执行。
needs:Job 依赖
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: pytest
build:
needs: test
runs-on: ubuntu-latest
steps:
- run: docker build -t myapp .
表示必须先完成 test,且通常需要成功,才能执行 build。
Test
↓
Build
↓
Deploy
Job 隔离
每个 GitHub-hosted Runner 上的 Job 通常运行在独立环境中。
因此,不同 Job 不会自动共享本地文件。
如果需要传递构建产物,可以使用 Artifact 或镜像仓库。
6. 实际 CI:Django + React
对于前后端分离项目,可以分别定义 Backend 和 Frontend Job。
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
backend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: backend/requirements.txt
- run: pip install -r requirements.txt
- name: Run tests
run: pytest
- name: Validate OpenAPI
run: >
python manage.py spectacular
--file openapi.yaml
--validate
--fail-on-warn
frontend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "24"
cache: pnpm
cache-dependency-path: frontend/pnpm-lock.yaml
- run: corepack enable
- run: pnpm install --frozen-lockfile
- name: Type Check
run: pnpm exec tsc -b
- name: Build
run: pnpm build
这是一个简化示例。实际使用时需要根据目录结构、数据库和环境变量调整。尤其是 pytest 依赖 PostgreSQL 时,需要添加 services 或其他测试数据库配置。
此外,前端 Orval 生成代码应与最新 OpenAPI Schema 保持一致,可以在 CI 中增加生成结果检查。
常见 CI 检查
| 工具 | 检查内容 |
|---|---|
| Ruff | Python Lint / Format |
| pytest | Django 业务和 API 测试 |
| drf-spectacular | OpenAPI Schema 验证 |
| TypeScript | 静态类型检查 |
| ESLint | JavaScript / React 代码质量 |
| Vite | 前端生产构建 |
| Docker Build | 容器镜像能否成功构建 |
不必一开始就启用全部检查。建议先保证 pytest、TypeScript 和生产构建能稳定通过。
7. Cache 与 Artifact
Cache:加快构建
例如:
- uses: actions/setup-node@v4
with:
node-version: "24"
cache: pnpm
它可以缓存包管理器下载的依赖,加快后续 Workflow。
也可以使用:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-${{ hashFiles('requirements.txt') }}
注意:Cache 用于性能优化,不应依赖缓存的存在保证构建正确。
Artifact:保存构建结果
例如:
- uses: actions/upload-artifact@v4
with:
name: frontend-dist
path: frontend/dist
可以保存:
- 前端构建结果。
- 测试报告。
- Coverage 报告。
- 其他构建产物。
区别:
| 概念 | 主要用途 |
|---|---|
| Cache | 加快后续任务 |
| Artifact | 保存或传递工作流产物 |
| Container Registry | 存储和分发 Docker 镜像 |
8. Secrets、Variables 与 Contexts
Secrets
在 GitHub 仓库中:
Settings
↓
Secrets and variables
↓
Actions
可以配置:
DEPLOY_HOST
DEPLOY_USER
SSH_PRIVATE_KEY
Workflow 读取:
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
Secrets 适合密码、Token、SSH Private Key 等。
Variables
非敏感配置可以使用 Variables:
env:
APP_ENV: ${{ vars.APP_ENV }}
Contexts
GitHub Actions 提供内置上下文:
${{ github.ref }}
${{ github.sha }}
${{ github.actor }}
${{ github.repository }}
${{ github.event_name }}
${{ secrets.MY_SECRET }}
${{ vars.APP_ENV }}
${{ ... }} 是 GitHub Actions 的表达式语法,不是 Bash 变量语法。
而:
$APP_ENV
通常是 Shell 环境变量。
GITHUB_TOKEN
GitHub 为 Workflow 提供临时的 GITHUB_TOKEN,用于访问 GitHub API 和部分仓库资源。
建议遵循最小权限原则:
permissions:
contents: read
如果需要推送 GHCR 镜像:
permissions:
contents: read
packages: write
9. CD:Docker 镜像发布
对于 Docker Compose 部署,常见 CD 流程:
Merge to main
↓
CI Pass
↓
Docker Build
↓
Push Image to GHCR
↓
VPS Pull Image
↓
Docker Compose Up
↓
Health Check
GHCR
GitHub Container Registry:
ghcr.io/username/sorivel-backend:1.2.0
可以使用 GitHub Actions 构建并推送 Docker 镜像。
示例:
name: Publish Backend
on:
push:
tags:
- "v*"
permissions:
contents: read
packages: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: ./backend
push: true
tags: ghcr.io/your-org/sorivel-backend:${{ github.ref_name }}
这里需要替换 your-org,并确保镜像命名和发布权限正确。实际应将发布 Workflow 与 CI 成功条件关联,避免测试失败的代码被发布。
VPS 部署
服务器 Compose 使用镜像:
services:
backend:
image: ghcr.io/your-org/sorivel-backend:v1.2.0
restart: unless-stopped
更新:
docker compose pull backend
docker compose up -d backend
这种方式将镜像构建放在 GitHub Actions,而不是每次在 VPS 上重新构建。
更复杂的自动部署可以通过 SSH、Self-hosted Runner 或其他部署系统实现,但不建议直接在生产服务器上执行不受信任的 PR 代码。
10. Environment 与部署保护
GitHub Actions 支持 Deployment Environment。
例如:
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
可以为 Production 环境配置:
- 环境级 Secrets。
- 环境级 Variables。
- 审批规则。
- 分支或 Tag 限制。
某些保护功能取决于仓库类型和 GitHub Plan。
对于生产部署,建议区分:
Development
Staging(可选)
Production
即使只有一台 VPS,也可以使用 Production Environment 管理部署凭据和发布权限。
11. Concurrency:防止并发部署
concurrency:
group: production-deploy
cancel-in-progress: false
确保同一个 Concurrency Group 中不会有多个部署同时运行。
cancel-in-progress: false 表示不主动取消已经运行的部署,但新触发的 Pending Run 仍可能取代旧的 Pending Run;它并不提供严格 FIFO 部署队列。
对于 CI,可以使用:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
新提交可以取消同一分支上尚未完成的旧 CI,减少资源浪费。
12. CI/CD 安全与回滚
安全原则
- 使用最小权限的
GITHUB_TOKEN。 - Secrets 不写入仓库或 Dockerfile。
- 不让不受信任的 PR 访问生产凭据。
- 第三方 Actions 优先固定到完整 Commit SHA,提高供应链安全性。
- 不随意使用具有高权限 Token 的
pull_request_target执行 PR 中的不可信代码。 - 部署前执行必要的测试和构建检查。
回滚(Rollback)
不要只依赖 latest 标签。
推荐使用明确版本:
sorivel-backend:v1.2.0
sorivel-backend:v1.2.1
如果新版本有问题:
Current: v1.2.1
↓
Rollback
↓
Previous: v1.2.0
修改镜像版本并重新部署:
docker compose pull backend
docker compose up -d backend
还需要注意:应用镜像回滚不等于数据库回滚。 如果部署同时执行了破坏性 Migration,必须单独设计数据库兼容和恢复策略。
13. CI/CD 的推荐实践
对于单台 VPS + Docker Compose 项目,可以采用三个阶段。
第一阶段:CI
PR / Push
↓
pytest
↓
Type Check
↓
Build
目标:自动检查代码是否可靠。
第二阶段:自动发布镜像
Main / Release Tag
↓
CI Passed
↓
Docker Build
↓
Push to GHCR
目标:构建可部署、可追踪版本的镜像。
第三阶段:自动部署
Approved Release
↓
Deploy to VPS
↓
docker compose pull
↓
docker compose up -d
↓
Health Check
目标:让部署可重复、可验证、可回滚。
总结
GitHub Actions 最重要的概念:
| 分类 | 核心内容 |
|---|---|
| 基础结构 | Workflow、Event、Job、Step、Runner |
| YAML 配置 | on、uses、run、needs、if、env |
| CI | Lint、Test、Type Check、Build |
| 性能 | Cache、Artifact |
| 安全 | Secrets、GITHUB_TOKEN、Permissions |
| CD | Registry、Docker Build/Push、Deployment |
| 生产保障 | Environment、Concurrency、Health Check、Rollback |
GitHub Actions 的核心作用是:当特定事件发生时,在 Runner 中自动执行预先定义好的工作流。
对于日常开发,优先掌握:
- 如何根据 Push / PR 触发 Workflow。
- 如何编写包含多个 Job 的 YAML。
- 如何执行 pytest、TypeScript 和 Vite 构建。
- 如何使用 Cache、Secrets 和环境变量。
- 如何构建 Docker 镜像并发布到 GHCR。
- 如何在 VPS 上部署及回滚。