🏠 首页 › 攻略 › GitHub Actions 实战:从入门到 CI/CD 流水线配置全攻略

GitHub Actions 实战:从入门到 CI/CD 流水线配置全攻略

GitHub Actions 是 GitHub 官方 CI/CD 工具。本文从 Workflow 基础语法讲起,涵盖自动化测试、构建部署、条件触发、缓存优化,帮你搭建完整的自动化流水线。

你还在手动部署代码?

每次代码上线,步骤是不是这样:

  1. 本地写代码
  2. 推送到 Git
  3. SSH 到服务器
  4. git pull
  5. 重启服务
  6. 检查日志

如果团队有3个人,还得先合并代码、解决冲突、逐个测试。繁琐还容易出错。

GitHub Actions 可以帮你自动化这一切。

它不需要买额外的 CI/CD 服务,也不需要维护 Jenkins 服务器。代码推到 GitHub,流水线自动跑。

下面从基础到实战,一步步教你配置。


一、Workflow 是什么?

Workflow(工作流)是 GitHub Actions 的基本单位。一个 Workflow 就是一个 YAML 文件,定义"什么时候做什么"。

文件放在仓库的 .github/workflows/ 目录里。

my-project/
├── .github/
│   └── workflows/
│       └── ci.yml          # CI 工作流
│       └── deploy.yml      # 部署工作流
├── src/
└── README.md

二、最简 CI 流水线

先写一个最简单的:代码推送时自动跑测试。

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

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

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - name: 检出代码
        uses: actions/checkout@v4
      
      - name: 设置 Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: 安装依赖
        run: pip install -r requirements.txt
      
      - name: 运行测试
        run: pytest tests/

解读:

  • name: 工作流名称,显示在 GitHub Actions 页面
  • on: 触发条件。这里配置了 push 和 pull_request 到 main 分支时触发
  • jobs: 定义任务。这里只有一个 test 任务
  • runs-on: 运行环境。ubuntu-latest 是 GitHub 提供的云服务器
  • steps: 任务步骤。每步可以是 GitHub 官方 Action 或自定义命令

三、多阶段流水线:测试 → 构建 → 部署

实际项目通常需要多阶段。下面是一个完整例子:

name: Build and Deploy

on:
  push:
    branches: [main]

jobs:
  # 阶段1:测试
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install -r requirements.txt
      - run: pytest tests/
      - name: 上传测试报告
        uses: actions/upload-artifact@v4
        with:
          name: test-report
          path: coverage/report.html

  # 阶段2:构建(依赖测试通过)
  build:
    needs: test  # 等 test  job 完成
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: 构建 Docker 镜像
        run: docker build -t myapp:${{ github.sha }} .
      - name: 推送镜像到 GitHub Container Registry
        run: |
          echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          docker push ghcr.io/${{ github.repository }}:latest

  # 阶段3:部署(依赖构建成功)
  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'  # 只在 main 分支部署
    steps:
      - uses: actions/checkout@v4
      - name: 部署到服务器
        run: |
          ssh deploy@myserver.com "docker pull ghcr.io/${{ github.repository }}:latest"
          ssh deploy@myserver.com "docker compose up -d"

关键点:

  • needs: 定义 job 依赖关系。build 等 test 完成,deploy 等 build 完成
  • if: 条件判断。只有 main 分支才部署
  • ${{ github.sha }}: GitHub 内置变量,表示当前 commit hash
  • secrets: 敏感信息(如 SSH 密钥、密码)存在 GitHub Secrets 里,用 ${{ secrets.NAME }} 引用

四、常用触发条件

on:
  # 代码推送时
  push:
    branches: [main, develop]
    tags: ['v*']
  
  # PR 时
  pull_request:
    branches: [main]
  
  # 定时触发(每天凌晨2点)
  schedule:
    - cron: '0 2 * * *'
  
  # 手动触发(GitHub UI 点击)
  workflow_dispatch:
    inputs:
      environment:
        description: '部署环境'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production
  
  # 监听其他仓库事件
  repository_dispatch:
    types: [deploy-hook]
  
  # 监听 issue 事件
  issues:
    types: [opened, labeled]

cron 格式:分 时 日 月 周(5位)。0 2 * * * 表示每天凌晨2点。


五、缓存加速:别让每次构建都从头来

Python 项目安装依赖是最耗时的步骤。用 actions/cache 缓存依赖:

- name: 缓存 pip 依赖
  uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

- name: 安装依赖
  run: pip install -r requirements.txt

原理:第一次构建时下载依赖并缓存。后续构建如果发现 requirements.txt 没变,直接读缓存,跳过下载。

构建时间可以从5分钟缩短到30秒。


六、环境变量和 secrets

环境变量

env:
  NODE_ENV: production
  DATABASE_URL: ${{ secrets.DB_URL }}

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      API_KEY: ${{ secrets.API_KEY }}
    steps:
      - run: echo "Deploying to $NODE_ENV"

Secrets 管理

在 GitHub 仓库页面:Settings → Secrets and variables → Actions → New repository secret

API_KEY=sk-xxxxxxxx
DB_PASSWORD=xxxxxxxx
GHCR_TOKEN=ghp_xxxxxxxxx

代码里用 ${{ secrets.NAME }} 引用。永远不要把密码写在 YAML 文件里。


七、矩阵构建:一个 job 跑多个环境

测试需要在多个 Python 版本上运行?用矩阵:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11', '3.12']
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - run: pip install -r requirements.txt
      - run: pytest tests/

GitHub 会自动创建4个并行的 job,每个用不同 Python 版本运行测试。

还可以加更多维度:

matrix:
  python-version: ['3.9', '3.11']
  os: [ubuntu-latest, windows-latest]

这会生成 2×2=4 个 job:(3.9+ubuntu, 3.9+windows, 3.11+ubuntu, 3.11+windows)


八、实战:Hugo 站点自动部署

回到 navbox.com.cn 的场景。项目用 Hugo 静态生成,每次更新内容需要重新构建和部署。

# .github/workflows/deploy.yml
name: Deploy Hugo Site

on:
  push:
    branches: [main]
    paths:
      - 'content/**'
      - 'themes/**'
      - 'hugo.toml'
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: 检出代码
        uses: actions/checkout@v4
        with:
          submodules: true
      
      - name: 安装 Hugo
        uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: '0.124.0'
      
      - name: 构建站点
        run: hugo --gc --minify
      
      - name: 部署到服务器
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: "public/"
          target: "/var/www/navbox"
      
      - name: 重启服务
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/navbox
            nginx -t && nginx -s reload

这个 Workflow 的作用:

  1. 监控 content/、themes/、hugo.toml 的变更
  2. 用 Hugo 构建静态站点
  3. 通过 SSH 把 public/ 同步到服务器
  4. 重启 Nginx 使新内容生效

九、常见问题排查

问题1:Workflow 挂了但不知道哪里出错

点击 GitHub Actions 页面的具体 job → 展开 step → 看红色错误日志。大部分错误都在日志里。

问题2:runner 资源不足

GitHub 免费账户的 runner 资源有限。大构建任务容易 OOM。

解决:用 runs-on: ubuntu-latest-8cores 或升级到 GitHub Pro。

问题3:敏感信息泄露

永远不要把密码、密钥写在 Workflow YAML 里。用 Secrets。

检查方法:在 GitHub Actions 页面,点击具体 run → 查看 step 日志,看是否打印了敏感内容。


十、总结

GitHub Actions 的精髓就三句话:

  1. YAML 配置触发条件 — 什么时候跑
  2. 定义 Job 和步骤 — 跑什么
  3. 利用缓存和矩阵 — 跑得快

从今天的例子出发,你的项目最适合加哪条自动化流水线?是从 PR 自动跑测试,还是提交代码自动部署?先从小处开始,逐步完善。