前端搭建 CI/CD 工作流指南

1. 选择 CI/CD 工具

常见的前端 CI/CD 工具选择:

  • GitHub Actions (与 GitHub 深度集成)
  • GitLab CI/CD (与 GitLab 深度集成)
  • Jenkins (自托管,高度可定制)
  • CircleCI (云服务)
  • Travis CI (云服务)

2. 基础 CI/CD 流程设计

典型的前端 CI/CD 流程包括以下阶段:

  1. 代码提交 → 2. 自动构建 → 3. 代码检查 → 4. 自动化测试 → 5. 部署

3. 使用 GitHub Actions 示例

一、前期准备

  1. 项目要求

    • 代码托管在 GitHub 仓库
    • 项目根目录有 package.json 文件
    • 有基本的构建脚本 (如 npm run build)
  2. 环境准备

    • 在项目根目录创建 .github/workflows 文件夹
    • 准备部署目标的相关凭据 (如需)

二、基础 CI/CD 配置文件

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

yaml 复制代码
name: Frontend CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]  # 监听 main 和 develop 分支的推送
  pull_request:
    branches: [ main ]          # PR 到 main 分支时触发

env:
  NODE_VERSION: '18.x'          # 统一 Node.js 版本

jobs:
  # 第一个 job:代码检查和测试
  lint-and-test:
    name: Lint & Test
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3   # 检出代码
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'            # 启用 npm 缓存
    
    - name: Install dependencies
      run: npm ci               # 使用 ci 而不是 install 保证依赖一致
    
    - name: Run ESLint
      run: npm run lint
    
    - name: Run unit tests
      run: npm test
    
    - name: Upload test coverage
      uses: codecov/codecov-action@v3
      with:
        token: ${{ secrets.CODECOV_TOKEN }}  # 可选:上传测试覆盖率到 Codecov

  # 第二个 job:构建和部署
  build-and-deploy:
    name: Build & Deploy
    needs: lint-and-test        # 依赖 lint-and-test 成功
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
    
    - name: Install dependencies
      run: npm ci
    
    - name: Build project
      run: npm run build
      
    - name: Archive production artifacts
      uses: actions/upload-artifact@v3
      with:
        name: build-artifacts
        path: dist/             # 假设构建输出在 dist 目录
        
    - name: Deploy to Staging
      if: github.ref == 'refs/heads/develop'
      run: npm run deploy:staging
      env:
        DEPLOY_TOKEN: ${{ secrets.STAGING_DEPLOY_TOKEN }}
    
    - name: Deploy to Production
      if: github.ref == 'refs/heads/main'
      run: npm run deploy:production
      env:
        DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}

三、详细配置说明

1. 触发条件 (on)

yaml 复制代码
on:
  push:
    branches: [ main, develop ]  # 指定触发分支
    tags: [ 'v*' ]              # 可选:标签推送触发
  pull_request:
    branches: [ main ]          # PR 到 main 时触发
  schedule:                     # 可选:定时触发
    - cron: '0 0 * * *'         # 每天 UTC 午夜

2. 环境变量管理

yaml 复制代码
env:
  NODE_VERSION: '18.x'
  BUILD_DIR: 'dist'
  
jobs:
  deploy:
    env:
      API_BASE_URL: ${{ secrets.API_BASE_URL }}

3. 矩阵构建 (多环境测试)

yaml 复制代码
jobs:
  test:
    strategy:
      matrix:
        node-version: ['16.x', '18.x', '20.x']
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

4. 缓存优化

yaml 复制代码
- name: Cache node modules
  uses: actions/cache@v3
  id: cache
  with:
    path: |
      node_modules
      .next/cache
    key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}

5. 人工审核 (生产部署)

yaml 复制代码
- name: Wait for manual approval
  uses: trstringer/manual-approval@v1
  with:
    secret: ${{ github.token }}
    approvers: 'team-lead,product-owner'
    minimum-approvals: 1

四、部署到不同平台的配置示例

1. 部署到 GitHub Pages

yaml 复制代码
- name: Deploy to GitHub Pages
  uses: peaceiris/actions-gh-pages@v3
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./dist
    keep_files: true            # 保留历史文件

2. 部署到 AWS S3 + CloudFront

yaml 复制代码
- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v2
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-east-1

- name: Deploy to S3
  run: |
    aws s3 sync ./dist s3://your-bucket-name --delete
    aws cloudfront create-invalidation \
      --distribution-id ${{ secrets.CF_DISTRIBUTION_ID }} \
      --paths "/*"

3. 部署到 Vercel

yaml 复制代码
- name: Install Vercel CLI
  run: npm install -g vercel@latest

- name: Deploy to Vercel
  run: vercel --prod --token ${{ secrets.VERCEL_TOKEN }}
  env:
    VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
    VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

五、完整高级示例

yaml 复制代码
name: Advanced Frontend CI/CD

on:
  push:
    branches: [ main, develop ]
    tags: [ 'v*' ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:    # 允许手动触发
    inputs:
      environment:
        description: 'Deploy environment'
        required: true
        default: 'staging'
        type: choice
        options:
        - staging
        - production

env:
  NODE_VERSION: '18.x'
  BUILD_DIR: 'dist'

jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      should_deploy: ${{ steps.check-ref.outputs.should_deploy }}
    steps:
    - name: Check branch/tag
      id: check-ref
      run: |
        if [[ $GITHUB_REF == refs/heads/main || $GITHUB_REF == refs/heads/develop || $GITHUB_REF == refs/tags/v* ]]; then
          echo "should_deploy=true" >> $GITHUB_OUTPUT
        else
          echo "should_deploy=false" >> $GITHUB_OUTPUT
        fi

  lint-test:
    needs: setup
    if: ${{ needs.setup.outputs.should_deploy == 'true' }}
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
    
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: node_modules
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-node-
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run linter
      run: npm run lint
    
    - name: Run tests
      run: npm test -- --coverage
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3

  build:
    needs: lint-test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
    
    - name: Install dependencies
      run: npm ci
    
    - name: Build project
      run: npm run build
    
    - name: Upload artifacts
      uses: actions/upload-artifact@v3
      with:
        name: build-output
        path: ${{ env.BUILD_DIR }}

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: 
      name: ${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'production') || 'staging' }}
      url: ${{ steps.deploy.outputs.deployment_url }}
    steps:
    - name: Download artifacts
      uses: actions/download-artifact@v3
      with:
        name: build-output
        path: ${{ env.BUILD_DIR }}
    
    - name: Deploy to environment
      id: deploy
      run: |
        if [ "${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'production') || 'staging' }}" == "production" ]; then
          npm run deploy:production
          echo "deployment_url=https://production.example.com" >> $GITHUB_OUTPUT
        else
          npm run deploy:staging
          echo "deployment_url=https://staging.example.com" >> $GITHUB_OUTPUT
        fi

六、最佳实践建议

  1. 分阶段执行:将流程分为 lint/test/build/deploy 等独立阶段

  2. 失败快速:将最容易失败的步骤放在前面

  3. 缓存优化:缓存 node_modules 和构建缓存

  4. 环境隔离:严格区分 staging 和 production 环境

  5. 安全防护

    • 使用 GitHub Secrets 存储敏感信息
    • 生产部署添加人工审批
  6. 监控通知

    • 集成 Slack/Teams 通知
    • 失败时自动通知相关人员
  7. 定期清理:设置 artifacts 和 cache 的保留策略

通过以上配置,你可以建立一个健壮、高效的前端 CI/CD 流程,实现从代码提交到自动化部署的完整链路。

相关推荐
90后的晨仔12 小时前
在macOS上无缝整合:为Claude Code配置魔搭社区免费API完全指南
前端
沿着路走到底13 小时前
JS事件循环
java·前端·javascript
子春一213 小时前
Flutter 2025 可访问性(Accessibility)工程体系:从合规达标到包容设计,打造人人可用的数字产品
前端·javascript·flutter
白兰地空瓶13 小时前
别再只会调 API 了!LangChain.js 才是前端 AI 工程化的真正起点
前端·langchain
jlspcsdn14 小时前
20251222项目练习
前端·javascript·html
行走的陀螺仪15 小时前
Sass 详细指南
前端·css·rust·sass
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ15 小时前
React 怎么区分导入的是组件还是函数,或者是对象
前端·react.js·前端框架
LYFlied15 小时前
【每日算法】LeetCode 136. 只出现一次的数字
前端·算法·leetcode·面试·职场和发展
子春一215 小时前
Flutter 2025 国际化与本地化工程体系:从多语言支持到文化适配,打造真正全球化的应用
前端·flutter
QT 小鲜肉15 小时前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记