CI/CD 集成 #

什么是 CI/CD? #

CI/CD 是持续集成和持续部署的缩写:

text
CI (Continuous Integration)  → 持续集成
CD (Continuous Deployment)    → 持续部署

工作流程 #

text
代码提交 → 自动测试 → 自动构建 → 自动部署

Netlify 内置 CI/CD #

自动部署流程 #

text
┌──────────────┐
│  Git Push    │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  触发构建    │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  安装依赖    │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  执行构建    │
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  部署上线    │
└──────────────┘

部署类型 #

类型 说明
Production 主分支部署
Deploy Preview PR 预览部署
Branch Deploy 其他分支部署

GitHub Actions 集成 #

基本 Workflow #

yaml
# .github/workflows/deploy.yml
name: Deploy to Netlify

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Deploy to Netlify
        uses: netlify/actions/cli@master
        with:
          args: deploy --prod
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

配置 Secrets #

在 GitHub 仓库设置中添加:

text
Settings → Secrets and variables → Actions → New repository secret

需要的 Secrets:

  • NETLIFY_AUTH_TOKEN:Netlify 访问令牌
  • NETLIFY_SITE_ID:站点 ID

获取访问令牌 #

  1. 访问 app.netlify.com/user/applications
  2. 点击 “New access token”
  3. 复制生成的令牌

获取站点 ID #

text
Site settings → General → Site details → Site ID

PR 预览部署 #

yaml
name: Deploy Preview

on:
  pull_request:
    branches: [main]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Deploy Preview
        uses: netlify/actions/cli@master
        with:
          args: deploy
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
      
      - name: Comment PR
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '🚀 Preview deployed!'
            })

带测试的部署 #

yaml
name: Test and Deploy

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Run lint
        run: npm run lint

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Deploy
        uses: netlify/actions/cli@master
        with:
          args: deploy --prod
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

GitLab CI 集成 #

基本 Pipeline #

yaml
# .gitlab-ci.yml
stages:
  - build
  - deploy

build:
  stage: build
  image: node:18
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour

deploy:
  stage: deploy
  image: node:18
  script:
    - npm install -g netlify-cli
    - netlify deploy --prod --dir=dist
  only:
    - main
  variables:
    NETLIFY_AUTH_TOKEN: $NETLIFY_AUTH_TOKEN
    NETLIFY_SITE_ID: $NETLIFY_SITE_ID

配置 Variables #

text
Settings → CI/CD → Variables → Add variable

添加:

  • NETLIFY_AUTH_TOKEN
  • NETLIFY_SITE_ID

带 Review App #

yaml
stages:
  - build
  - deploy
  - stop

build:
  stage: build
  image: node:18
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

deploy_review:
  stage: deploy
  image: node:18
  script:
    - npm install -g netlify-cli
    - netlify deploy --dir=dist --alias=review-$CI_MERGE_REQUEST_IID
  environment:
    name: review/$CI_MERGE_REQUEST_IID
    url: https://review-$CI_MERGE_REQUEST_IID--your-site.netlify.app
  only:
    - merge_requests

stop_review:
  stage: stop
  script:
    - echo "Stopping review app"
  when: manual
  environment:
    name: review/$CI_MERGE_REQUEST_IID
    action: stop
  only:
    - merge_requests

deploy_production:
  stage: deploy
  image: node:18
  script:
    - npm install -g netlify-cli
    - netlify deploy --prod --dir=dist
  only:
    - main

CircleCI 集成 #

基本 Config #

yaml
# .circleci/config.yml
version: 2.1

orbs:
  node: circleci/node@5

jobs:
  build-and-deploy:
    executor: node/default
    steps:
      - checkout
      
      - node/install-packages:
          pkg-manager: npm
      
      - run:
          name: Build
          command: npm run build
      
      - run:
          name: Install Netlify CLI
          command: npm install -g netlify-cli
      
      - run:
          name: Deploy to Netlify
          command: netlify deploy --prod --dir=dist
          environment:
            NETLIFY_AUTH_TOKEN: $NETLIFY_AUTH_TOKEN
            NETLIFY_SITE_ID: $NETLIFY_SITE_ID

workflows:
  version: 2
  build-deploy:
    jobs:
      - build-and-deploy:
          filters:
            branches:
              only: main

配置 Environment Variables #

text
Project Settings → Environment Variables → Add Variable

自定义构建脚本 #

使用 Build Hook #

yaml
# GitHub Actions
- name: Trigger Netlify Build
  run: curl -X POST ${{ secrets.NETLIFY_BUILD_HOOK }}

构建钩子配置 #

text
Site settings → Build & deploy → Build hooks → Add build hook

部署通知 #

Slack 通知 #

yaml
- name: Notify Slack
  if: success()
  uses: slackapi/slack-github-action@v1
  with:
    channel-id: 'deployments'
    slack-message: '✅ Deployed to production'
  env:
    SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

部署状态徽章 #

markdown
[![Netlify Status](https://api.netlify.com/api/v1/badges/YOUR_SITE_ID/deploy-status)](https://app.netlify.com/sites/YOUR_SITE_NAME/deploys)

回滚部署 #

使用 Netlify CLI #

bash
# 列出部署
netlify deploy:list

# 回滚到指定部署
netlify deploy:restore --deploy-id=xxx

使用 API #

bash
curl -X POST \
  -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \
  https://api.netlify.com/api/v1/deploys/DEPLOY_ID/restore

部署锁 #

锁定部署 #

防止自动部署:

text
Site settings → Build & deploy → Build settings → Stop builds

使用 API #

bash
# 锁定
curl -X POST \
  -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \
  https://api.netlify.com/api/v1/sites/YOUR_SITE_ID/lock

# 解锁
curl -X POST \
  -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \
  https://api.netlify.com/api/v1/sites/YOUR_SITE_ID/unlock

最佳实践 #

1. 测试优先 #

确保测试通过后再部署:

yaml
jobs:
  test:
    # 测试步骤
  
  deploy:
    needs: test
    # 部署步骤

2. 环境分离 #

yaml
deploy-staging:
  # 部署到预发布环境
  only:
    - develop

deploy-production:
  # 部署到生产环境
  only:
    - main

3. 缓存依赖 #

yaml
- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

4. 使用矩阵构建 #

yaml
strategy:
  matrix:
    node-version: [16, 18, 20]

5. 限制并发 #

yaml
concurrency:
  group: deploy-${{ github.ref }}
  cancel-in-progress: true

下一步 #

掌握了 CI/CD 集成后,继续学习 团队协作 了解团队管理功能!

最后更新:2026-03-28