Skip to main content

CI/CD (持续集成与持续交付)

CI/CD 旨在通过自动化手段,减少软件开发过程中的手动操作,降低人为错误的风险,从而加快交付速度并提高代码质量。

1. 核心概念

  • CI (Continuous Integration - 持续集成)
    • 开发者频繁地将代码合并到主分支。
    • 每次合并后,自动触发构建、代码检查(Lint)和自动化测试(单元测试、集成测试)。
    • 目标:尽早发现集成错误,保证主干代码的质量。
  • CD (Continuous Delivery / Continuous Deployment - 持续交付/持续部署)
    • 持续交付:在 CI 通过后,自动将代码构建成可部署的产物(如 Docker 镜像),准备好部署,但可能需要人工点击确认才发布到生产环境。
    • 持续部署:在 CI 通过后,自动将最新版本部署到生产环境,全程无需人工干预。

2. 典型的全栈 CI/CD 流水线

一个标准的 Node.js + 前端全栈项目的自动化流水线通常包含以下阶段:

  1. Lint & Test:检查代码格式,运行 Jest 单元测试。
  2. Build:前端执行打包 (npm run build),后端编译 TypeScript。
  3. Dockerize:将构建产物打包成 Docker 镜像。
  4. Push:将镜像推送到镜像仓库(Docker Hub / 阿里云 ACR)。
  5. Deploy:通知生产服务器拉取最新镜像并重启容器。

3. GitHub Actions 实战

GitHub Actions 是目前非常流行的 CI/CD 工具,它直接集成在 GitHub 中,通过项目根目录下的 .github/workflows/ 中的 YAML 文件进行配置。

示例:Node.js 项目的 CI/CD 配置

创建文件:.github/workflows/deploy.yml

name: Node.js CI/CD Pipeline

# 触发条件:当主分支有推送时触发
on:
push:
branches: [ "main" ]

jobs:
# ==========================================
# 阶段 1:构建与测试 (CI)
# ==========================================
build-and-test:
runs-on: ubuntu-latest

steps:
# 1. 检出代码
- name: Checkout code
uses: actions/checkout@v3

# 2. 设置 Node.js 环境
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: '20.x'
cache: 'npm' # 自动缓存依赖,加速构建

# 3. 安装依赖并运行测试
- name: Install dependencies
run: npm ci

- name: Run Linter
run: npm run lint

- name: Run Tests
run: npm test

# ==========================================
# 阶段 2:构建 Docker 镜像并推送 (CD - 准备)
# ==========================================
docker-build-push:
needs: build-and-test # 必须等上面的 CI job 成功后才执行
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

# 登录 Docker Hub (需要提前在 GitHub Secrets 中配置账号密码)
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

# 构建并推送镜像
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: your-username/my-api:latest

# ==========================================
# 阶段 3:部署到服务器 (CD - 部署)
# ==========================================
deploy:
needs: docker-build-push
runs-on: ubuntu-latest

steps:
# 通过 SSH 登录到服务器并执行部署命令
- name: Deploy to Server via SSH
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
# 登录到服务器后执行的脚本
cd /opt/my-app
docker pull your-username/my-api:latest
docker-compose down
docker-compose up -d

4. 最佳实践与注意事项

  1. 敏感信息管理:绝对不能将密码、SSH 私钥、数据库账号硬编码在代码或 YAML 文件中。必须使用平台提供的 Secrets 功能(如 GitHub Secrets)。
  2. 缓存依赖:在 CI 流程中缓存 node_modules~/.npm,可以显著减少流水线的运行时间。
  3. 环境分离:通常配置多个 Workflow,例如 dev 分支触发部署到测试环境,main 分支触发部署到生产环境。
  4. 不可变产物:构建一次,到处运行。应该将 Docker 镜像推送到仓库,然后在各个环境拉取同一个镜像运行,而不是在服务器上拉取源码重新 npm install 和构建。