CI/CD 实践指南
这页适合作为“代码提交到自动交付”的流程总览。CI/CD 的重点不是把 YAML 写长,而是保证每次改动都能被稳定构建、测试、发布和回滚。
先定流水线目标
一条健康的流水线通常至少回答清楚这些问题:
- 提交后要自动检查什么
- 哪些分支允许部署
- 失败后谁会收到通知
- 生产发布能不能回滚
- 密钥和环境变量如何隔离
核心概念
- CI(持续集成):代码提交后自动构建、测试
- CD(持续部署/交付):测试通过后自动部署到生产环境
GitHub Actions 进阶
矩阵构建
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
缓存依赖
- uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
条件执行
steps:
- name: Deploy
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: npm run deploy
- name: Preview
if: github.event_name == 'pull_request'
run: npm run build
Secrets 使用
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
复用 Workflow
# .github/workflows/reusable-build.yml
on:
workflow_call:
inputs:
environment:
required: true
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build -- --mode ${{ inputs.environment }}
# .github/workflows/deploy.yml
jobs:
deploy:
uses: ./.github/workflows/reusable-build.yml
with:
environment: production
部署策略
Cloudflare Pages
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
command: pages deploy dist --project-name=myproject
Vercel
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: --prod
Docker 镜像发布
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: user/app:latest,user/app:${{ github.sha }}
SSH 部署
- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: deploy
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /opt/app
git pull
docker compose up -d --build
自动化测试
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
env:
DATABASE_URL: postgres://postgres:test@localhost:5432/testdb
Release 自动化
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
推荐落地顺序
建议按这个顺序建设:
- 先加最小构建检查
- 再加测试和缓存
- 再加预览部署
- 再加生产部署和回滚
- 最后再补 Release、通知和审批
常见问题
本地能跑,CI 总失败
高频原因通常包括:
- Node / Python / Bun 版本不一致
- 锁文件没同步
- 环境变量和 Secret 缺失
- CI 环境更严格,暴露了隐藏问题
流水线越来越慢
优先优化:
- 依赖缓存
- Job 拆分
- 只在必要路径触发
- 把重型步骤放到更后面
自动部署让人不安心
这时更适合先做:
- Preview 部署
- 主分支受保护
- 生产环境审批
- 明确回滚脚本
风险提醒
- 密钥不要写死在 workflow
- 发布动作必须和分支策略绑定
- 先有回滚思路,再谈全自动上线
延伸阅读
参考链接
- GitHub Actions 文档 — 官方文档
- Awesome Actions — 精选 Actions
- act — 本地运行 GitHub Actions