Skip to content

从 Travis CI 迁移到 GitHub Actions:2026 年的前端自动化部署实战

Published: at 21:004 min read
目录

前言

2018 年我写过一篇 Travis CI 配置教程,当时它是开源项目的 CI 标配,免费额度慷慨,与 GitHub 集成流畅。

2021 年,Travis CI 更换了收费策略,免费用户的构建额度从”无限”改为”有限积分”,耗尽即停。大量开源项目在毫无预兆的情况下 CI 停摆,社区因此掀起了集体迁移浪潮。

受益最大的是 GitHub Actions——它由 GitHub 官方维护,与 GitHub 生态深度集成,在前端与开源项目中已经成为最常见的 CI/CD 方案之一。


一、Travis CI 的落幕

1.1 收费事件时间线

1.2 GitHub Actions 为什么赢


二、GitHub Actions 核心概念速览

理解五个概念就够用:

Repository
└── .github/workflows/
    └── deploy.yml          ← Workflow(工作流)

Workflow
├── on: push                ← 触发条件(Event)
└── jobs:
    └── build               ← Job(独立运行环境)
        ├── runs-on: ubuntu-latest
        └── steps:          ← Steps(顺序执行的步骤)
            ├── uses: actions/checkout@v4   ← Action(可复用步骤)
            └── run: pnpm build             ← 直接运行命令

三、等价迁移:.travis.yml → GitHub Actions

3.1 典型的 Travis CI 前端配置

# .travis.yml(2018 年风格)
language: node_js
node_js:
  - "16"
cache:
  yarn: true
  directories:
    - node_modules

install:
  - yarn install

script:
  - yarn lint
  - yarn test
  - yarn build

deploy:
  provider: pages
  skip_cleanup: true
  github_token: $GITHUB_TOKEN
  local_dir: dist
  on:
    branch: main

3.2 等价的 GitHub Actions 配置

# .github/workflows/deploy.yml
name: CI & Deploy

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

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: "pnpm" # 自动缓存 pnpm store

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Lint
        run: pnpm lint

      - name: Test
        run: pnpm test

      - name: Build
        run: pnpm build

      # 只有 push 到 main 才部署(PR 不部署)
      - name: Deploy to GitHub Pages
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

3.3 关键差异对照

Travis CIGitHub Actions
.travis.yml.github/workflows/*.yml
language: node_jsactions/setup-node@v4
cache: yarn: truecache: 'pnpm'(setup-node 内置)
$GITHUB_TOKEN 环境变量${{ secrets.GITHUB_TOKEN }}(自动提供)
on: branch: mainif: github.ref == 'refs/heads/main'
before_installsteps 中加一个 run 步骤

四、pnpm 在 GitHub Actions 中的最佳实践

4.1 正确的缓存配置

- uses: pnpm/action-setup@v4
  with:
    version: 10 # 指定 pnpm 版本,避免意外升级

- uses: actions/setup-node@v4
  with:
    node-version: 22
    cache: "pnpm" # 缓存 pnpm 的全局 store(~/.pnpm-store)

cache: 'pnpm' 会缓存 ~/.pnpm-store(pnpm 的全局内容寻址存储),而不是 node_modules。这意味着即使 node_modules 不存在,pnpm install 也几乎是瞬间完成(直接从缓存 hardlink)。

4.2 使用 —frozen-lockfile

- run: pnpm install --frozen-lockfile

--frozen-lockfile 等同于 npm 的 --ci

4.3 读取 package.json 中的 packageManager 字段

如果 package.json 里有:

{
  "packageManager": "pnpm@10.28.0"
}

pnpm/action-setup 可以自动读取:

- uses: pnpm/action-setup@v4
  # 不需要指定 version,自动从 packageManager 字段读取

五、Secrets 与环境变量管理

5.1 内置 Secrets

GITHUB_TOKEN 是 GitHub Actions 自动提供的,无需手动配置,拥有仓库的读写权限。

5.2 自定义 Secrets

在仓库的 Settings → Secrets and variables → Actions 中添加:

- name: Build
  run: pnpm build
  env:
    PUBLIC_GA_MEASUREMENT_ID: ${{ secrets.GA_MEASUREMENT_ID }}
    PUBLIC_API_URL: ${{ vars.API_URL }} # vars 是明文变量,secrets 是加密的

原则

5.3 环境(Environments)

对于需要审批的部署(如生产环境),使用 Environments:

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment:
      name: production # 在 Settings 中配置了需要审批
      url: https://myapp.com
    steps:
      - run: pnpm deploy:prod
        env:
          DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}

六、矩阵构建:多版本并行测试

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [20, 22] # 并行测试两个 Node 版本
        os: [ubuntu-latest, windows-latest] # 也可以测试多个 OS
      fail-fast: false # 一个版本失败不中断其他版本

    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: "pnpm"
      - run: pnpm install --frozen-lockfile
      - run: pnpm test

矩阵构建会并行跑 2×2=4 个 Job,大幅缩短总等待时间。


七、常用部署方案对比

7.1 GitHub Pages(静态站)

- name: Deploy
  uses: peaceiris/actions-gh-pages@v3
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./dist
    cname: myapp.com # 自定义域名

7.2 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"

7.3 Cloudflare Pages

- name: Deploy to Cloudflare Pages
  uses: cloudflare/pages-action@v1
  with:
    apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
    accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
    projectName: my-project
    directory: dist
    gitHubToken: ${{ secrets.GITHUB_TOKEN }}

7.4 三者对比

GitHub PagesVercelCloudflare Pages
免费额度无限(公开仓库)慷慨最慷慨
CDNGitHub CDNVercel EdgeCloudflare 全球 CDN
Preview 部署需自己配置自动(PR 自动部署)自动
函数/APIServerless FunctionsWorkers
自定义域名支持支持支持

八、进阶:Reusable Workflows 与 Composite Actions

8.1 Reusable Workflow(跨仓库复用工作流)

# .github/workflows/reusable-build.yml
on:
  workflow_call: # 声明为可复用
    inputs:
      node-version:
        required: false
        type: string
        default: "22"
    secrets:
      NPM_TOKEN:
        required: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          cache: "pnpm"
      - run: pnpm install --frozen-lockfile
      - run: pnpm build
# 在其他仓库中调用
jobs:
  build:
    uses: myorg/.github/.github/workflows/reusable-build.yml@main
    with:
      node-version: "22"
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

8.2 Composite Action(本地可复用步骤)

# .github/actions/setup-pnpm/action.yml
name: Setup pnpm environment
description: Setup Node.js + pnpm with caching

inputs:
  node-version:
    description: Node.js version
    default: "22"

runs:
  using: composite
  steps:
    - uses: pnpm/action-setup@v4
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: "pnpm"
    - run: pnpm install --frozen-lockfile
      shell: bash
# 在工作流中使用
- uses: ./.github/actions/setup-pnpm
  with:
    node-version: "22"

九、本站(llccing.github.io)的实际 workflow

本站已完成从 Travis CI 到 GitHub Actions 的迁移,实际使用的配置:

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

on:
  push:
    branches: [main]

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

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: "pnpm"

      - run: pnpm install --frozen-lockfile

      - run: pnpm build
        env:
          PUBLIC_GA_MEASUREMENT_ID: ${{ secrets.GA_MEASUREMENT_ID }}

      - uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist
          cname: rowanliu.com

配置简洁,整个构建+部署大约 2-3 分钟完成。


总结

GitHub Actions 取代 Travis CI 不只是工具的替换,更是思维模式的升级——从”在 CI 服务器上运行脚本”到”在 GitHub 生态内编排工作流”。

迁移工作本身并不复杂,大多数项目 1 小时内可以完成。迁移后你会发现:


参考资料