GitHub Actions CI/CD 配置教程:自动化构建、测试与部署

GitHub Actions 是 GitHub 自带的 CI/CD 平台。它真正的价值不是“自动跑一次测试”,而是把构建、验证、发布和回滚变成仓库的一部分,让团队不再依赖人工记忆来完成重复动作。

一、先理解 CI/CD

CI:代码一变更就自动构建和测试
CD:测试通过后自动部署

对中小团队来说,CI/CD 的意义通常是三件事:更早发现问题、更稳定地发版、把部署步骤写成可审计的配置。

1.1 先决定你的流水线目标

不同仓库的目标并不一样。

场景 主要目标
Web 前端 快速验证、自动发布
Node.js API 测试、构建、镜像发布
文档仓库 质量检查、预览生成
基础设施代码 计划、审批、部署

二、核心概念

术语 含义
Workflow 自动化流程定义
Job 工作流中的执行单元
Step Job 内部的单个动作
Action 可复用组件
Runner 运行任务的机器

2.1 何时拆 Job

如果某一步失败后不需要重跑整个流程,就应该拆成独立 Job。这样日志更清晰,也更容易并行。

三、推荐的 Node.js 工作流

name: Node.js CI/CD

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

jobs:
  build-test:
    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 lint
      - run: npm test
      - run: npm run build

3.1 带部署的版本

name: Node.js CI/CD

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

permissions:
  contents: read

jobs:
  lint:
    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 lint

  test:
    needs: lint
    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 test

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - name: Deploy to VPS
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: 'dist/'
          target: '/var/www/app/'

四、Secrets 和服务器准备

在仓库 Settings → Secrets and variables → Actions 中配置:

SERVER_HOST
SERVER_USER
SSH_PRIVATE_KEY

服务器侧通常至少要准备一个稳定的发布目录,以及可重复执行的容器或进程管理方式。

version: '3.8'
services:
  app:
    build: .
    ports:
      - '3000:3000'
    restart: always

4.1 权限建议

尽量只给 Actions 必要的权限。

项目 建议
contents read
packages 仅在需要时开启
actions 保持最小化

五、最佳实践

  1. 把 lint、test 和 deploy 拆成独立 Job。
  2. 缓存依赖,减少重复安装时间。
  3. 只让 main 分支触发部署,PR 只做验证。
  4. 对敏感权限使用最小授权原则。
  5. 文档变更较多的仓库可以对特定路径做条件跳过。

5.1 常见增强项

增强项 价值
依赖缓存 减少构建时间
路径过滤 只在需要时跑重任务
环境保护 部署前加审批
并行 Job 提高吞吐量

六、排障建议

git status

先检查本地工作区,再看 Actions 日志,通常能快速判断失败来自代码、依赖还是 Secrets 配置。

6.1 调试顺序

  1. 看触发条件是否匹配。
  2. 看 checkout 是否成功。
  3. 看依赖安装是否失败。
  4. 看测试是否失败。
  5. 看部署密钥和目标路径是否正确。

参考:GitHub Actions 官方文档、actions/checkout、actions/setup-node 的说明页。

七、总结

GitHub Actions 让 CI/CD 变得前所未有的简单。与 GitHub 仓库的深度整合意味着无需额外的 CI 服务器,配置都在代码仓库中。从简单的 Lint + Test 开始,逐步增加部署步骤,最终实现完整的自动化 DevOps 流水线。记住:自动化不是目的,目的是让开发流程更可靠、更高效

7.1 环境和回滚

如果项目已经有 staging 和 production,建议把环境保护也接进来。这样一来,PR 只验证,合并后先经过 staging,再进入 production,回滚也更容易追踪。

环境 用途
Preview 预览和评审
Staging 集成测试和验收
Production 正式发布

回滚最好不是临时手工操作,而是通过固定脚本或容器版本回退来完成。这样你在事故里能先恢复服务,再慢慢查原因。

7.2 矩阵构建和版本发布

如果项目要同时支持多个 Node.js 版本或不同操作系统,可以用 matrix 让测试一次跑多组环境。这样可以提前发现兼容性问题,而不是等用户反馈。

strategy:
  matrix:
    node: [18, 20]
    os: [ubuntu-latest, windows-latest]

发布时还可以把 tag 和 release 挂钩,确保“代码版本”和“上线版本”是一一对应的。对团队来说,这比口头说“这次发的是哪个版本”要可靠得多。

如果团队需要更强的可见性,还可以在部署结束后发通知到 Slack、邮件或群机器人。只要把结果留在仓库里,后续追查发布历史会轻松很多。

另外建议给构建产物设置保留期限,比如保留最近几次成功发布的包。这样一旦回滚或审计,你能直接拿到可验证的二进制,而不是临时再去重新构建一次。

这一步看似细,但在事故恢复时很省时间。

尤其适合高频发版团队。

7.3 维护和排查习惯

建议每隔一段时间检查一次 Secrets、缓存和第三方 Action 版本。CI 不是写完就结束,长期维护同样重要。

项目 处理建议
Secrets 定期轮换
缓存 必要时清理
Action 锁定版本

7.4 一个最小可用的发布模板

如果你的团队刚开始做自动化,建议先从“验证 + 部署”两步跑通,而不是一开始就把通知、矩阵和多环境都塞进去。最小可用的目标,是让每次代码合并后都能自动验证,并且在主分支上自动发布一次。

name: Minimal Deploy

on:
  push:
    branches: [main]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test

  deploy:
    needs: verify
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build

7.5 上线时的最小检查

项目 检查点 说明
触发条件 只在 main 上发布 避免草稿分支误发
依赖安装 npm ci 是否稳定 锁定依赖版本
构建产物 是否真的生成成功 先验证再部署
发布路径 目标目录是否正确 避免覆盖错误目录
回滚方式 是否能快速回退 故障时先恢复服务

7.6 一个常见故障场景

有些仓库的流程在本地能跑,到了 Actions 上就失败,通常不是“GitHub Actions 不稳定”,而是环境不一致。最常见的差异包括 Node 版本、缺失环境变量、权限不够和脚本依赖本地文件。遇到这种情况,先把日志里的第一条失败命令单独拿出来复现,再逐项缩小范围。

  1. 先确认运行环境版本。
  2. 再确认依赖安装是否锁定。
  3. 然后确认 Secrets 是否齐全。
  4. 最后确认发布路径和权限。

把这四步固定成团队习惯后,CI/CD 才会从“偶尔能用”变成“可以依赖”。