GitHub Actions 核心概念

GitHub Actions 是 GitHub 内置的 CI/CD 平台,它直接集成在代码仓库中,无需额外搭建基础设施。理解以下核心概念是编写工作流的基础:

创建一个完整的 CI 流水线

下面是一个面向 Vue/React 项目的前端 CI 工作流,覆盖代码检查、测试和构建三个阶段:

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  lint:
    name: 代码检查
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 安装 Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: 安装依赖
        run: npm ci

      - name: ESLint 检查
        run: npx eslint src/ --ext .js,.jsx,.ts,.tsx --max-warnings 0

      - name: TypeScript 类型检查
        run: npx tsc --noEmit

  test:
    name: 单元测试
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci

      - name: 运行测试并生成覆盖率
        run: npx vitest run --coverage

      - name: 上传覆盖率报告
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
          path: coverage/

  build:
    name: 构建产物
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci

      - name: 构建项目
        run: npm run build

      - name: 上传构建产物
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

CD 流水线:自动部署

构建通过后,下一步是自动部署。以下展示两种常见部署目标:GitHub Pages 和自有服务器。

部署到 GitHub Pages

# .github/workflows/deploy-pages.yml
name: Deploy to Pages

on:
  push:
    branches: [main]

# 设置 GITHUB_TOKEN 的权限
permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run build

      - name: 上传 Pages 产物
        uses: actions/upload-pages-artifact@v3
        with:
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: 部署到 GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

部署到自有服务器(SSH)

# .github/workflows/deploy-server.yml
name: Deploy to Server

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run build

      - name: 通过 Rsync 部署到服务器
        uses: burnett01/rsync-deployments@6.0.0
        with:
          switches: -avzr --delete
          path: dist/
          remote_path: /var/www/myapp/
          remote_host: ${{ secrets.SERVER_HOST }}
          remote_user: ${{ secrets.SERVER_USER }}
          remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

环境变量与 Secrets 管理

敏感信息(如 API 密钥、SSH 私钥、服务器地址)不应硬编码在工作流文件中。GitHub 提供了 Secrets 和 Variables 机制:

# 在工作流中使用 Secrets 和 Variables
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: 构建时注入环境变量
        env:
          VITE_API_BASE: ${{ vars.API_BASE_URL }}
          VITE_API_KEY: ${{ secrets.API_KEY }}
        run: npm run build

      - name: 构建后验证
        run: |
          # Secrets 会被自动掩码,不会泄露到日志中
          echo "API endpoint: ${{ vars.API_BASE_URL }}"
          # 下面的输出会被显示为 ***
          echo "Key: ${{ secrets.API_KEY }}"

配置路径:仓库 Settings → Secrets and variables → Actions。支持四个级别的作用域:仓库级、环境级、组织级和企业级。

缓存策略优化

缓存可以显著缩短工作流执行时间。以下是几种关键缓存策略:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # 策略一:使用 setup-node 内置的 npm 缓存
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'  # 自动缓存 ~/.npm

      - run: npm ci

      # 策略二:手动缓存 node_modules(适用于 pnpm/yarn)
      - name: 缓存 pnpm 存储
        uses: actions/cache@v4
        with:
          path: |
            ~/.local/share/pnpm/store
            node_modules
            */node_modules
          key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
          restore-keys: |
            pnpm-${{ runner.os }}-

      # 策略三:缓存构建产物(适用于 monorepo)
      - name: 缓存 Turborepo 产物
        uses: actions/cache@v4
        with:
          path: |
            .turbo
            **/.eslintcache
          key: turbo-${{ runner.os }}-${{ github.sha }}
          restore-keys: |
            turbo-${{ runner.os }}-

Matrix 矩阵构建

当你需要在不同环境组合下测试时,Matrix 构建可以并行运行多组配置:

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false  # 一个失败不影响其他组合
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18, 20, 22]
        # 排除特定组合
        exclude:
          - os: windows-latest
            node-version: 18

    steps:
      - uses: actions/checkout@v4
      - name: 使用 Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test

实战:Vue 项目完整工作流

以下是一个适合生产环境的 Vue 项目完整 CI/CD 工作流,整合了上述所有关键特性:

# .github/workflows/vue-app.yml
name: Vue App CI/CD

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true  # 同分支新推送取消旧运行

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npx eslint src/ --ext .js,.ts,.vue --max-warnings 0
      - run: npx vitest run --coverage
      - run: npm run build
        env:
          VITE_APP_VERSION: ${{ github.sha }}

      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  deploy-staging:
    needs: ci
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/
      - name: 部署到测试环境
        uses: burnett01/rsync-deployments@6.0.0
        with:
          switches: -avzr --delete
          path: dist/
          remote_path: /var/www/staging/
          remote_host: ${{ secrets.SERVER_HOST }}
          remote_user: deploy
          remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

  deploy-production:
    needs: ci
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/
      - name: 部署到生产环境
        uses: burnett01/rsync-deployments@6.0.0
        with:
          switches: -avzr --delete
          path: dist/
          remote_path: /var/www/production/
          remote_host: ${{ secrets.SERVER_HOST }}
          remote_user: deploy
          remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

小结

GitHub Actions 为前端项目提供了一站式的 CI/CD 解决方案。从代码推送到自动部署,整个过程无需离开 GitHub 生态。关键实践包括:拆分 CI 和 CD 为独立 Job 以明确职责;使用缓存和 npm ci 加速构建;通过 Secrets 管理敏感信息;利用 concurrency 避免重复运行;以及使用 Environment 保护规则为生产部署增加审批关卡。一套良好的自动化流水线不仅能减少人为错误,更能让团队将注意力集中在代码质量本身。