切换语言
切换主题

Next.js CI/CD 实战指南:用 GitHub Actions 实现自动测试和部署

周五下午五点半,我盯着终端里滚动的日志,手指在键盘上机械地敲着 git pull && npm install && npm run build && pm2 restart。这已经是今天第三次部署了——上午修了个小 bug,中午优化了个接口,现在又改了点样式。三台服务器,每台都得操作一遍。

等我弄完最后一台,时针已经指向七点。

那天晚上回家的路上我在想,肯定有更好的办法。我不想每次改完代码都得去服务器上重复这些操作,更不想担心某台服务器忘记重启导致线上出问题。说实话,我连测试都经常忘记跑——改完代码就想着赶紧部署上线,结果后面发现 bug 了又得重新来一遍。

后来我接触到了 CI/CD 和 GitHub Actions,整个工作流程彻底变了。现在我只要 push 代码到 GitHub,剩下的测试、构建、部署全都自动完成。喝杯咖啡的功夫,新版本就已经上线了。

如果你也在被手动部署折磨,接下来我分享一下怎么用 GitHub Actions 搭建 Next.js 的自动化部署流程。从最基础的配置到完整的实战案例,包括我踩过的坑和解决方案,全都会讲到。

为什么需要 CI/CD

手动部署的那些痛

回想我刚开始做 Next.js 项目的时候,部署流程是这样的:本地写完代码,测试一下,然后 SSH 登录到服务器,git pull 拉代码,npm install 装依赖,npm run build 构建,最后 pm2 restart 重启服务。一套流程下来,顺利的话也要十几分钟。

但经常不顺利。

有次我在三台服务器上部署,前两台都成功了,第三台因为 SSH 断开了没注意到。第二天用户反馈说网站有时候正常有时候显示旧版本——原来是负载均衡把请求分到了那台没更新的服务器上。还有一次,我改完代码太兴奋,直接部署了,完全忘记跑测试。结果上线后发现一个致命 bug,又得紧急回滚,冷汗都下来了。

更坑的是多服务器构建问题。Next.js 每次 build 都会生成一个新的 build ID,三台服务器各自构建,ID 就不一样了。当负载均衡把用户请求分到不同服务器时,Next.js 检测到 ID 变化,就会触发硬刷新,重新加载所有资源。用户体验?别提了。

CI/CD 到底解决了什么

说白了,CI/CD 就是把这些重复的、容易出错的流程自动化。

**CI(持续集成)**负责测试这块。你每次 push 代码,它就自动跑一遍测试,包括单元测试、类型检查、代码规范检查。测试不过?那这次提交就别想部署了,直接报错让你去修。这样就避免了把有问题的代码部署到线上。

**CD(持续部署)**负责构建和部署。测试通过了?好的,自动开始构建,构建完成后自动部署到服务器。整个过程你不用动一根手指。

实际效果?我现在的工作流程是:本地写代码 → 提交到 GitHub → 自动测试 → 自动构建 → 自动部署。从 push 代码到上线,大概 5 分钟,而且不需要我盯着。我可以去倒杯水,回来新版本就已经在线上了。

还有个好处是可追踪。每次部署都有完整的日志记录,哪个提交触发的、测试结果如何、部署到哪台服务器,全都一清二楚。出了问题也能快速定位,不会像以前那样抓瞎。

GitHub Actions 基础配置

先搞懂它怎么工作的

刚接触 GitHub Actions 的时候,我看到一堆 workflow、job、step 这些概念,脑袋都大了。其实理解起来挺简单的:

**Workflow(工作流)**就是一套完整的自动化流程,比如”测试+构建+部署”就是一个 workflow。它由一个 YAML 文件定义,放在项目的 .github/workflows 目录下。

**Job(作业)**是 workflow 里的一个独立任务。比如你可以有一个”测试”job 和一个”部署”job。Job 之间可以并行执行,也可以设置依赖关系让它们按顺序执行。

**Step(步骤)**是 job 里的具体操作,像”拉取代码”、“安装依赖”、“运行测试”这些都是 step。

触发条件也很灵活。你可以设置成每次 push 到 main 分支就触发,或者只在创建 Pull Request 时触发,甚至可以设置定时任务每天凌晨自动执行。

创建第一个 Workflow

先在项目根目录创建 .github/workflows 文件夹,然后新建一个 ci-cd.yml 文件。最基础的配置长这样:

name: CI/CD Pipeline

# 触发条件:push 到 main 分支时执行
on:
  push:
    branches: [main]

jobs:
  build:
    # 在 Ubuntu 最新版本上运行
    runs-on: ubuntu-latest

    steps:
      # 第一步:拉取代码
      - uses: actions/checkout@v4

      # 第二步:设置 Node.js 环境
      - 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

这个配置的意思是:每次有代码 push 到 main 分支,就在 Ubuntu 系统上执行拉代码、装 Node.js、装依赖、构建这几个步骤。

把这个文件提交到 GitHub 后,你去仓库的 “Actions” 标签页就能看到 workflow 的执行情况了。第一次看到那个绿色的对勾,说实话挺有成就感的。

配置 Secrets 保护敏感信息

如果要部署到服务器,肯定会用到一些敏感信息,比如服务器 IP、SSH 密钥、API token 这些。千万别直接写在 YAML 文件里,不然提交到 GitHub 就暴露了。

正确的做法是用 GitHub 的 Secrets 功能。在仓库的 Settings → Secrets and variables → Actions 里,点”New repository secret”添加密钥。比如添加一个叫 SERVER_HOST 的 secret,值是你服务器的 IP 地址。

然后在 workflow 里用 ${{ secrets.SERVER_HOST }} 来引用,GitHub 会自动替换成实际的值,而且在日志里会打码显示,不会泄露。

搭建自动测试流程

测试环境配置

测试这块,我的想法是:能自动化的就别手动。我配置的测试流程包括代码规范检查(ESLint)、类型检查(TypeScript)、单元测试(Jest),基本上能拦住大部分问题。

先看看完整的测试 job 配置:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'  # 缓存 npm 依赖,加速后续构建

      - name: Install dependencies
        run: npm ci

      - name: Lint check
        run: npm run lint

      - name: Type check
        run: npm run type-check

      - name: Run tests
        run: npm run test -- --coverage

这里有个小技巧:cache: 'npm' 会自动缓存 node_modules,第二次运行的时候就不用重新下载所有依赖了,能省好几分钟。

加速测试流程的几个技巧

刚开始的时候,我的测试流程跑一次要 10 多分钟,每次提交都得等半天。后来优化了一下,现在 3 分钟就能跑完。

第一个技巧是缓存。除了上面提到的 npm 缓存,Next.js 的构建缓存也能缓存起来:

- name: Cache Next.js build
  uses: actions/cache@v3
  with:
    path: |
      ~/.npm
      .next/cache
    key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}

这样 Next.js 就不用每次都重新构建所有页面了,能快不少。

第二个技巧是并行执行。如果测试之间没有依赖关系,可以分成多个 job 并行跑:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps: [...]  # 只跑 lint

  test:
    runs-on: ubuntu-latest
    steps: [...]  # 只跑单元测试

  type-check:
    runs-on: ubuntu-latest
    steps: [...]  # 只跑类型检查

这三个 job 会同时开始,总耗时就是最慢那个 job 的时间,而不是三个加起来。

我踩过的坑

有一次我配置测试,本地跑得好好的,GitHub Actions 上就是报错。调试了半天才发现,GitHub Actions 在拉取 Pull Request 的代码时,默认会把 PR 分支合并到目标分支上,产生一个新的临时提交。这个临时提交在本地是不存在的,就可能导致一些奇怪的问题。

解决办法是在 checkout 的时候加个参数:

- uses: actions/checkout@v4
  with:
    ref: ${{ github.head_ref }}  # 使用 PR 分支的原始代码

还有个坑是测试超时。有些 E2E 测试跑得慢,默认超时时间不够用。可以在 job 里设置更长的超时时间:

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15  # 默认是 6 分钟

配置自动部署流程

部署到 Vercel:最简单的方案

如果你的项目托管在 Vercel 上,那恭喜你,几乎不用配置什么。Vercel 和 GitHub 天然集成,你把仓库连接到 Vercel 项目后,每次 push 代码就自动部署了。

但如果想更精细地控制,比如只在测试通过后才部署,可以用 Vercel 官方的 GitHub Action:

jobs:
  deploy:
    runs-on: ubuntu-latest
    needs: test  # 等测试 job 完成后再执行
    if: github.ref == 'refs/heads/main'  # 只在 main 分支部署

    steps:
      - uses: actions/checkout@v4

      - 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'  # 部署到生产环境

需要在 Vercel 后台生成一个 token,还有在项目设置里找到 org ID 和 project ID,把它们添加到 GitHub Secrets 里。

Vercel 还有个好处是自动为每个 PR 创建预览环境。你提交一个 PR,Vercel 会自动部署一个临时环境,给你一个预览链接,能直接看到改动效果,超方便。

部署到自建服务器:更灵活但稍微复杂

我自己的项目是部署在自己的服务器上的,主要是想要更多控制权。这种情况需要配置 SSH 连接,然后让 GitHub Actions 通过 SSH 去服务器上执行部署命令。

先在本地生成一对 SSH 密钥:

ssh-keygen -t ed25519 -C "github-actions"

把公钥添加到服务器的 ~/.ssh/authorized_keys 里,私钥添加到 GitHub Secrets(比如叫 SSH_PRIVATE_KEY)。

然后配置部署 job:

jobs:
  deploy:
    runs-on: ubuntu-latest
    needs: test
    if: github.ref == 'refs/heads/main'

    steps:
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/my-nextjs-app
            git pull origin main
            npm install
            npm run build
            pm2 restart nextjs-app

这个配置会 SSH 到服务器,拉取最新代码,安装依赖,构建,然后重启应用。整个过程完全自动化,你不用再手动登录服务器了。

解决多服务器 Build ID 不一致的问题

如果你像我一样需要部署到多台服务器做负载均衡,有个很重要的事情:多台服务器的 build ID 必须一致,不然用户访问时会不断刷新页面。

解决方案是在一个地方构建好,然后把构建产物分发到所有服务器。我的做法是这样的:

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

      # 把构建产物打包上传
      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: next-build
          path: |
            .next
            public

  deploy:
    runs-on: ubuntu-latest
    needs: build
    strategy:
      matrix:
        server: [server1, server2, server3]  # 多台服务器

    steps:
      # 下载构建产物
      - name: Download build artifacts
        uses: actions/download-artifact@v3
        with:
          name: next-build

      # 部署到对应服务器
      - name: Deploy to ${{ matrix.server }}
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets[format('{0}_HOST', matrix.server)] }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: ".next,public"
          target: "/var/www/my-nextjs-app"

这样就只构建一次,然后把同样的构建产物分发到三台服务器,build ID 自然就一致了。

优化和最佳实践

构建失败了怎么办

自动化很爽,但有时候也会出问题。构建失败了,你总得知道吧?不然代码提交了,部署失败了,你还不知道,那就尴尬了。

我的做法是配置失败通知。可以发邮件,也可以发到 Slack 或者钉钉。以 Slack 为例:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      [...部署步骤...]

      # 如果部署失败,发送 Slack 通知
      - name: Notify on failure
        if: failure()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          text: '部署失败了!快去看看怎么回事'
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}
          channel: '#deploy-notifications'

这样一旦部署失败,Slack 就会收到通知,能第一时间知道。

分支策略:开发环境和生产环境分开

实际项目里,我会用不同的分支对应不同的环境。develop 分支部署到测试环境,main 分支部署到生产环境。配置长这样:

on:
  push:
    branches:
      - main      # 生产环境
      - develop   # 测试环境

jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    steps:
      - [...部署到测试环境...]

  deploy-production:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - [...部署到生产环境...]

这样平时开发就往 develop 提交,自动部署到测试环境验证。确认没问题了,再合并到 main,自动部署到生产环境。

有些团队还会要求生产环境部署前要手动审批。GitHub Actions 支持这个功能,在 job 里加一个 environment 配置,然后在仓库设置里配置审批人:

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment:
      name: production  # 需要审批的环境
    steps: [...]

这样每次要部署到生产环境,都会先暂停,等审批人点了”同意”才继续执行。对于重要项目来说,多一层保护还是挺有必要的。

回滚机制

虽然有测试和审批,但有时候还是会出现线上问题。这时候需要快速回滚到上一个版本。

一个简单的回滚方案是给每次部署打上 tag,然后保留最近几个版本的构建产物。需要回滚的时候,手动触发一个 workflow,指定要回滚到的 tag:

on:
  workflow_dispatch:  # 手动触发
    inputs:
      tag:
        description: '要回滚到的 tag'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.tag }}  # 使用指定的 tag

      - name: Deploy
        [...正常的部署流程...]

这样在 GitHub Actions 页面上点”Run workflow”,输入 tag,就能快速回滚了。

环境变量管理

Next.js 项目经常需要配置环境变量,比如 API 地址、数据库连接字符串这些。千万别直接写死在代码里,也别提交到 Git 仓库。

最佳实践是:

  1. 敏感信息放在 GitHub Secrets 里
  2. 在 workflow 里注入到环境变量
  3. Next.js 构建时读取环境变量
- name: Build
  run: npm run build
  env:
    NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }}
    DATABASE_URL: ${{ secrets.DATABASE_URL }}

这样不同环境可以用不同的环境变量,代码完全不用改。

实战案例:完整配置示例

说了这么多,来看一个完整的配置示例。这个配置包含了测试、构建、部署的完整流程,基本上可以直接用到你的项目里:

name: Next.js CI/CD

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

jobs:
  # Job 1: 代码检查和测试
  test:
    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: Lint check
        run: npm run lint

      - name: Type check
        run: npm run type-check

      - name: Run tests
        run: npm run test -- --coverage

  # Job 2: 构建
  build:
    runs-on: ubuntu-latest
    needs: test  # 测试通过后才构建
    if: github.event_name == 'push'  # 只在 push 时构建,PR 时不构建

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'

      - name: Cache dependencies and build
        uses: actions/cache@v3
        with:
          path: |
            ~/.npm
            .next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }}

      # 上传构建产物供部署使用
      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: next-build
          path: |
            .next
            public
            package.json

  # Job 3: 部署到测试环境
  deploy-staging:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/develop'

    steps:
      - name: Download build artifacts
        uses: actions/download-artifact@v3
        with:
          name: next-build

      - name: Deploy to staging server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.STAGING_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/staging
            pm2 stop nextjs-app || true
            rm -rf .next public
            pm2 start npm --name "nextjs-app" -- start
            pm2 save

      - name: Notify Slack
        if: always()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          text: '测试环境部署${{ job.status == "success" && "成功" || "失败" }}'
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}

  # Job 4: 部署到生产环境
  deploy-production:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    environment:
      name: production  # 需要手动审批

    steps:
      - name: Download build artifacts
        uses: actions/download-artifact@v3
        with:
          name: next-build

      - name: Deploy to production server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.PROD_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/production
            pm2 stop nextjs-app || true
            rm -rf .next public
            pm2 start npm --name "nextjs-app" -- start
            pm2 save

      - name: Notify Slack
        if: always()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          text: '生产环境部署${{ job.status == "success" && "成功" || "失败" }}'
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}

这个配置里,PR 只会跑测试,不会构建和部署。提交到 develop 分支会自动部署到测试环境,提交到 main 分支会部署到生产环境(需要手动审批)。每次部署都会发 Slack 通知,失败了也能第一时间知道。

实际使用的时候,你需要在 GitHub 仓库设置里配置这些 Secrets:

  • API_URL: API 地址
  • STAGING_HOST / PROD_HOST: 测试/生产服务器地址
  • SERVER_USER: SSH 用户名
  • SSH_PRIVATE_KEY: SSH 私钥
  • SLACK_WEBHOOK: Slack webhook 地址(可选)

配置完成后,整个流程就跑起来了。你要做的就是写代码、提交,剩下的全自动。

结论

从手动部署到自动化,这个转变真的改变了我的开发体验。不用再每次改完代码就去服务器上敲一遍重复的命令,不用再担心忘记跑测试,也不用再盯着终端等构建完成。

配置 GitHub Actions 的 CI/CD 流程,前期可能需要花点时间摸索,但绝对值得。一旦配置好了,后面就能持续受益。你可以从最简单的配置开始,先跑通测试和构建,再慢慢加上部署、通知、回滚这些功能。

说实话,现在回想起来,我都不知道以前是怎么手动部署过来的。如果你还在手动部署,真的建议你花点时间配置一下自动化流程。代码 push 上去,喝杯咖啡,回来新版本就上线了——这种感觉,试过就回不去了。

赶紧动手试试吧。从你的 Next.js 项目开始,创建第一个 workflow 文件,看着 GitHub Actions 自动跑起来的那一刻,你就会明白我在说什么了。

Next.js CI/CD完整配置流程

从创建GitHub Actions workflow到配置测试、构建、部署的完整步骤

⏱️ 预计耗时: 2 小时

  1. 1

    步骤1: 创建GitHub Actions workflow

    创建.github/workflows/deploy.yml:
    ```yaml
    name: Deploy

    on:
    push:
    branches: [main]

    jobs:
    build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
    with:
    node-version: '18'
    - run: npm install
    - run: npm run build
    - run: npm test
    ```

    关键点:
    • 触发条件:push到main分支
    • 运行环境:ubuntu-latest
    • 步骤:checkout → setup-node → install → build → test
  2. 2

    步骤2: 配置测试步骤

    添加测试:
    ```yaml
    - name: Run tests
    run: npm test

    - name: Type check
    run: npm run type-check

    - name: Lint
    run: npm run lint
    ```

    关键点:
    • 测试失败阻止部署
    • 类型检查确保类型安全
    • 代码规范检查确保代码质量

    优势:
    • 避免把有问题的代码部署到线上
    • 自动检查,不会忘记跑测试
  3. 3

    步骤3: 配置构建步骤

    构建配置:
    ```yaml
    - name: Build
    run: npm run build
    env:
    NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
    ```

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

    关键点:
    • 配置环境变量
    • 使用缓存加速构建
    • 检查构建输出
  4. 4

    步骤4: 配置部署步骤

    SSH部署:
    ```yaml
    - name: Deploy to server
    uses: appleboy/ssh-action@master
    with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_KEY }}
    script: |
    cd /path/to/app
    git pull
    npm install
    npm run build
    pm2 restart app
    ```

    多服务器部署:
    ```yaml
    - name: Deploy to servers
    uses: appleboy/ssh-action@master
    with:
    host: ${{ secrets.HOSTS }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_KEY }}
    script: |
    cd /path/to/app
    git pull
    npm install
    # 使用GitHub Actions构建的产物
    pm2 restart app
    ```

    关键点:
    • 使用SSH密钥认证
    • 统一构建ID(在GitHub Actions中构建)
    • 避免多服务器构建ID不一致

常见问题

为什么需要CI/CD?
手动部署的痛点:
• 每次改完代码都要去服务器上重复操作
• 容易忘记重启服务器
• 容易忘记跑测试
• 多服务器部署容易出错
• 构建ID不一致导致硬刷新

CI/CD优势:
• 自动化测试、构建、部署
• push代码就自动上线
• 避免手动部署错误
• 统一构建ID
• 提高开发效率

真实案例:
• 三台服务器部署,前两台成功,第三台SSH断开没注意到
• 负载均衡把请求分到没更新的服务器,用户看到旧版本
• 改完代码太兴奋直接部署,忘记跑测试,上线后发现致命bug

解决方案:用GitHub Actions自动化整个流程。
如何配置GitHub Actions?
创建.github/workflows/deploy.yml:
```yaml
name: Deploy

on:
push:
branches: [main]

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- run: npm run build
- run: npm test
```

关键点:
• 触发条件:push到main分支
• 运行环境:ubuntu-latest
• 步骤:checkout → setup-node → install → build → test

配置Secrets:
• 在GitHub仓库Settings → Secrets中配置
• HOST、USERNAME、SSH_KEY等
• 用于SSH部署

建议:从最简单的配置开始,先跑通测试和构建,再慢慢加上部署。
多服务器部署怎么避免构建ID不一致?
问题:多服务器各自构建,ID不一样,负载均衡时触发硬刷新。

解决方案:统一构建ID

在GitHub Actions中构建:
```yaml
- name: Build
run: npm run build

- name: Deploy to servers
uses: appleboy/ssh-action@master
with:
script: |
cd /path/to/app
git pull
# 使用GitHub Actions构建的产物
pm2 restart app
```

或者使用构建产物:
```yaml
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build
path: .next

- name: Deploy to servers
uses: appleboy/ssh-action@master
with:
script: |
# 下载构建产物
# 部署到服务器
```

关键点:
• 在GitHub Actions中统一构建
• 构建产物分发到多台服务器
• 避免每台服务器各自构建

优势:
• 构建ID一致
• 避免硬刷新
• 用户体验更好
如何配置测试步骤?
添加测试:
```yaml
- name: Run tests
run: npm test

- name: Type check
run: npm run type-check

- name: Lint
run: npm run lint
```

关键点:
• 测试失败阻止部署
• 类型检查确保类型安全
• 代码规范检查确保代码质量

优势:
• 避免把有问题的代码部署到线上
• 自动检查,不会忘记跑测试
• 提高代码质量

建议:
• 从最简单的测试开始
• 逐步增加测试覆盖率
• 持续改进测试质量
如何配置部署通知?
Slack通知:
```yaml
- name: Notify Slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'Deployment completed'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
```

邮件通知:
```yaml
- name: Send email
uses: dawidd6/action-send-mail@v3
with:
to: team@example.com
subject: 'Deployment completed'
body: 'Deployment to production completed successfully'
```

关键点:
• 部署成功/失败都通知
• 包含部署信息(版本、时间等)
• 及时通知团队

建议:
• 配置Slack通知(实时)
• 配置邮件通知(备份)
• 包含部署详情
CI/CD的最佳实践是什么?
渐进式实施:
1. 先跑通测试和构建
2. 再慢慢加上部署
3. 最后加上通知、回滚功能

不要追求一步到位,先把最基础的流程跑起来,再逐步完善。

持续改进:
• 每次部署后检查日志
• 根据实际情况调整配置
• 优化构建时间
• 提高测试覆盖率

关键指标:
• 构建时间
• 测试通过率
• 部署成功率
• 回滚次数

建议:
• 从最简单的配置开始
• 持续改进
• 团队协作

记住:CI/CD不是一次性任务,而是持续的过程。

15 分钟阅读 · 发布于: 2025年12月20日 · 修改于: 2026年1月22日

评论

使用 GitHub 账号登录后即可评论

相关文章