# GitHub Actions 实战:从零搭建 CI/CD 流水线的 5 个核心配置

手动部署 → 凌晨 3 点修 bug → 一气之下把整个流程塞进 GitHub Actions,3 分钟搞定。

引言

去年接手一个遗留项目,发布流程是纯手动的:git pull → 本地跑 pytest → 手动打包 → scp 上传服务器 → ssh 重启。三步一检查,一步错了从头来。

有一次依赖没同步,线上挂了 40 分钟。那之后我把整套流程迁移到了 GitHub Actions,现在 push 代码到 main 分支,测试、构建、部署全自动完成。

这篇文章不是 GitHub Actions 的入门教程------官方文档已经够好了。我想分享的是实际项目中踩过坑之后沉淀下来的 5 个配置模式,覆盖了从"能跑"到"生产级"的关键步骤。每个配置都可以直接复制,改个分支名就能用。


1. 基础骨架:push 自动跑测试 + 失败通知

任何 CI 的起点都是自动化测试。下面是一个可以直接用的 Python 项目测试 workflow:

yaml 复制代码
# .github/workflows/test.yml
name: Run Tests

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

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

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest pytest-cov

      - name: Run tests
        run: pytest --cov=src --cov-report=term-missing

几个值得注意的点:

  • 双触发器 push + pull_requestpush 保证你自己的分支变更被验证,pull_request 保证别人提的 PR 自动跑测试。没过审的代码根本合不进 main
  • pytest --cov 生成覆盖率报告,在 PR 页面直接看哪些行没覆盖到。
  • runs-on: ubuntu-latest 是目前性价比最高的 runner,启动快,免费额度够用。如果你的项目依赖 Windows 特定功能,可以换成 windows-latest(但注意 Windows runner 消耗的免费分钟数是 Linux 的 2 倍)。

进阶:加失败通知

测试挂了不能靠人盯着看。用 webhook 推送到企业微信/钉钉/Slack:

yaml 复制代码
      - name: Notify failure
        if: failure()
        run: |
          curl -X POST "${{ secrets.WECOM_WEBHOOK }}" \
            -H "Content-Type: application/json" \
            -d '{"msgtype":"text","text":{"content":"❌ CI 测试失败:${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}}'

把 webhook URL 存在 GitHub Secrets(Settings → Secrets and variables → Actions)里,不要硬编码。failure() 是 GitHub Actions 的内置条件函数,只有前面某一步挂了才会执行。


2. Matrix 策略:一行配置覆盖 N 个环境

在实际项目中,"我本地能跑"不等于"CI 上能跑","Python 3.10 能跑"不等于"3.12 能跑"。提前发现环境兼容性问题,靠 Matrix:

yaml 复制代码
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10", "3.11", "3.12"]
        os: [ubuntu-latest, windows-latest]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - run: pip install -r requirements.txt
      - run: pytest

3 个 Python 版本 × 2 个操作系统 = 6 个 job 并行跑,总耗时约等于最慢那个 job 的时间。

text 复制代码
test (3.10, ubuntu)     ✅  PASSED
test (3.10, windows)    ✅  PASSED
test (3.11, ubuntu)     ✅  PASSED
test (3.11, windows)    ✅  PASSED
test (3.12, ubuntu)     ✅  PASSED
test (3.12, windows)    ❌  FAILED

关键配置:

  • fail-fast: false :一个 job 挂了不取消其他 job。默认是 true,一个失败全部终止------这在 Matrix 场景下很蠢,因为你希望看到所有环境的完整结果。
  • Matrix 变量在 steps 里用 ${{ matrix.xxx }} 引用,setup-python 会根据矩阵变量自动选择版本。
  • 可以 Matrix 更多维度 :比如 db: [postgres, mysql],适合测不同数据库兼容性。但注意 job 数量是指数级增长的------4 个维度 × 3 个值 = 81 个 job,免费额度可能不够。

如果你的项目只支持一个 Python 版本,至少加上 os: [ubuntu-latest, windows-latest]。Windows 路径分隔符、换行符、文件权限问题,是跨平台 bug 的第一来源。


3. Cache 策略:把 CI 时间从 5 分钟压到 30 秒

每次 CI 都从零安装依赖是最常见的性能浪费。GitHub Actions 提供了 actions/cache@v4,原理很简单:把指定目录打个快照,下次 key 不变就直接恢复。

yaml 复制代码
      - name: Cache pip packages
        uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-

      - name: Cache virtual environment
        uses: actions/cache@v4
        with:
          path: .venv
          key: ${{ runner.os }}-venv-${{ hashFiles('requirements.txt') }}

      - name: Install dependencies
        run: pip install -r requirements.txt

缓存策略解析:

缓存层 路径 作用
pip cache ~/.cache/pip 缓存下载的 .whl 包,避免重复下载
venv cache .venv 缓存已安装的虚拟环境,跳过安装步骤

两级缓存叠加,requirements.txt 不变时 pip install 直接跳过------CI 时间从 5 分钟压到 30 秒。

Key 设计原则:

  • hashFiles('requirements.txt') 做 key 的一部分:依赖文件变了自动刷新缓存。
  • restore-keys 做降级匹配:精确 key 没命中时(比如新增了一个依赖),用前缀匹配恢复最近一次缓存,只增量安装新包。
  • 跨平台注意 :pip cache 在 Windows 上是 ~\AppData\Local\pip\Cache,在 path 里写成 ~/.cache/pip,actions/cache 会自动处理路径映射。但如果缓存一直 miss,检查一下路径是否正确。

缓存总大小限制 10GB(GitHub 免费计划),超过后旧的缓存会被自动驱逐。如果你用 Mono-repo 多语言项目,注意控制缓存体积------可以给每种语言单独设一个 cache step。


4. Artifacts + Environments:测试→构建→部署的完整链路

测试通过了,下一步是部署。GitHub Actions 的 job 之间是隔离的------每个 job 跑在独立的虚拟机里,文件不共享。传递产物的机制是 Artifacts ;控制部署流程的机制是 Environments

4.1 Artifacts:job 间传文件

yaml 复制代码
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install -r requirements.txt
      - run: pytest --junitxml=report.xml
      - name: Upload test report
        uses: actions/upload-artifact@v4
        with:
          name: test-report
          path: report.xml

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Download test report
        uses: actions/download-artifact@v4
        with:
          name: test-report
      - run: cat report.xml
  • needs: test 是关键:部署 job 必须等测试 job 全部通过才会执行。测试挂了,部署根本不会触发。
  • Artifacts 保留 90 天(默认),可以在 Actions 页面下载。
  • v4 版本相比 v3 性能提升明显,大文件上传不再超时。

4.2 Environments:分级部署 + 审批门禁

复制代码
dev(自动) → staging(自动) → production(需要手动审批)
yaml 复制代码
  deploy-staging:
    needs: test
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - run: echo "Deploying to staging..."

  deploy-prod:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: echo "Deploying to production..."

在仓库 Settings → Environments 中配置:

环境 审批 保护分支 适用场景
staging 不需要 自动部署,快速验证
production 需要手动 Approve main 分支 生产发布有人审核

还可以给 Environment 绑定独立的 Secrets------stagingproduction 用不同的数据库密码、API 密钥,互不污染。


5. Reusable Workflow:一套配置全团队复用

当一个组织有 5 个、10 个、20 个微服务仓库时,每个仓库复制粘贴一份 CI 配置是维护噩梦。GitHub Actions 支持 Reusable Workflow------定义一个公共 workflow,其他仓库直接引用。

定义公共 workflow(.github/workflows/_python-ci.yml):

yaml 复制代码
name: Reusable Python CI

on:
  workflow_call:
    inputs:
      python-version:
        required: false
        type: string
        default: "3.12"
    secrets:
      WECOM_WEBHOOK:
        required: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ inputs.python-version }}
      - uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
      - run: pip install -r requirements.txt
      - run: pytest

各服务引用(service-a/.github/workflows/ci.yml):

yaml 复制代码
name: Service A CI

on: [push]

jobs:
  ci:
    uses: ./.github/workflows/_python-ci.yml
    with:
      python-version: "3.12"
    secrets:
      WECOM_WEBHOOK: ${{ secrets.WECOM_WEBHOOK }}

最佳实践:

  • 文件名以下划线开头(_python-ci.yml),约定俗成表示"内部 workflow,不直接触发"。
  • 通过 inputs 暴露可配置参数(Python 版本、Node 版本等),各服务按需覆盖。
  • Secrets 不会自动传递,需要在调用方显式声明 secrets: XXX: ${{ secrets.XXX }}------这是一个安全设计。
  • Reusable workflow 必须放在 .github/workflows/ 目录下,且调用方仓库需要 actions: read 权限。

完整流水线

上面 5 个模式拼在一起,就是一条可以直接上生产的 CI/CD pipeline:

yaml 复制代码
name: CI/CD Pipeline

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

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10", "3.11", "3.12"]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
      - run: pip install -r requirements.txt
      - run: pytest --junitxml=report.xml
      - uses: actions/upload-artifact@v4
        with:
          name: report-${{ matrix.python-version }}
          path: report.xml

  deploy-staging:
    needs: test
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
      - run: |
          scp -r dist/* user@staging-server:/app/
          ssh user@staging-server 'systemctl restart myapp'

  deploy-prod:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - run: |
          scp -r dist/* user@prod-server:/app/
          ssh user@prod-server 'systemctl restart myapp'

执行流程:push main → 9 个测试 job 并行 → 全部通过 → 自动部署 staging → 手动 Approve → 部署 production。


总结

配置 核心概念 解决的问题
自动测试 + 通知 on: [push, pull_request] + webhook 每次 push 自动验证,失败即时通知
Matrix strategy.matrix 多版本/多系统兼容性,一个配置覆盖
Cache actions/cache@v4 + hashFiles 重复构建加速,依赖变更自动刷新
Artifacts + Environments needs + environment job 间传产物,环境分级 + 审批门禁
Reusable Workflow workflow_call 消除重复配置,团队级 CI 标准化

这套配置在我们团队跑了半年。发布频率从"两周憋一个大版本"变成"一天发三次",回归测试从 40 分钟压到 6 分钟。

如果你在搭建 CI/CD 过程中遇到坑,欢迎在评论区交流。


参考链接:


本文发表于 2026 年 6 月,文中配置基于 GitHub Actions 当前最新版本。如果本文对你有帮助,欢迎点赞、收藏、关注。

相关推荐
霸道流氓气质2 天前
GitLab CI/CD 完全指南
linux·ci/cd·gitlab
sbjdhjd2 天前
从零搭建企业级 CI/CD(下):Jenkins+GitLab+Harbor 全链路实战指南
git·servlet·ci/cd·云原生·云计算·gitlab·jenkins
糖果店的幽灵2 天前
软件测试接口测试从入门到精通:接口测试CI_CD集成
软件测试·ci/cd·接口测试
平头老王3 天前
CI/CD流水线设计 — 第1章:常见误区
ci/cd·自动化·devops·持续部署·持续集成
星落zx4 天前
在CI/CD流水线里接入多模型自动Code Review,踩坑与方案分享
人工智能·ci/cd·代码复审
又是进步的一天4 天前
一台虚拟机学习CI流程
学习·ci/cd·云原生·容器·kubernetes·devops
w3296362715 天前
八、OpenCode 高阶玩法:CLI 自动化、CI/CD 集成与远程协作
运维·ci/cd·自动化·ai编程·开发工具·opencode
brycegao5 天前
如何搭建标准化 Git 工具流,保障 Android 团队代码质量
android·ci/cd
Dontla5 天前
CI/CD前世今生(持续集成、持续交付、持续部署、Jenkins、Github Actions)
ci/cd·github·jenkins