GitHub Actions 完全指南:从零到自动化部署

2023-01-20 Linux 运维

前言

GitHub Actions 是 GitHub 提供的持续集成和持续部署(CI/CD)平台,允许开发者在代码仓库中直接定义自动化工作流。自 2018 年推出以来,GitHub Actions 已经成为最受欢迎的 CI/CD 工具之一。本文将详细介绍 GitHub Actions 的核心概念、workflow 结构、触发事件、矩阵构建、缓存策略以及自动化部署实践。

1. GitHub Actions 基础概念

1.1 核心概念

概念 说明
Workflow 自动化的完整流程,由一个或多个 job 组成
Job 一组 step 的集合,在同一个 runner 上执行
Step 一个 job 中的最小执行单元,可以是 shell 命令或 action
Action 可复用的命令集合,类似函数
Runner 执行 workflow 的服务器(GitHub 托管或自托管)
Event 触发 workflow 的事件(如 push、pull_request)

1.2 为什么选择 GitHub Actions

特性 GitHub Actions Jenkins GitLab CI
集成度 原生 GitHub 集成 需要插件 GitLab 原生
配置方式 YAML in 仓库 Web UI + 插件 YAML in 仓库
学习曲线 低 高 中
价格(公开仓库) 免费 免费 免费
价格(私有仓库) 免费额度 + 按量 自托管免费 按订阅

2. Workflow 文件结构

2.1 基本结构

GitHub Actions workflow 文件存放在仓库的 .github/workflows/ 目录下,使用 YAML 格式。

# .github/workflows/ci.yml

name: CI Pipeline  # workflow 名称

on:  # 触发事件
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:  # 定义任务
  build:
    runs-on: ubuntu-latest  # 运行环境
    steps:  # 步骤
      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

2.2 文件命名规则

  • 文件名:*.yml 或 *.yaml
  • 建议:使用描述性名称,如 ci.yml、deploy.yml、release.yml
  • 一个仓库可以有多个 workflow 文件

3. 触发事件(on)

3.1 常见触发事件

3.2 事件过滤

on:
  push:
    branches:
      - main
    paths:
      - 'src/**'
      - 'package.json'
      - '.github/workflows/**'
    paths-ignore:
      - 'docs/**'
      - '*.md'

3.3 推送到特定标签

on:
  push:
    tags:
      - 'v*'  # 匹配 v1.0、v2.1.3 等

4. Jobs 详解

4.1 单 Job 配置

jobs:
  build:
    name: Build and Test
    runs-on: ubuntu-latest
    timeout-minutes: 30  # 超时时间
    continue-on-error: false  # 出错是否继续

    steps:
      - name: Step 1
        run: echo "Hello"

4.2 多 Job 并行

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test

  build:
    runs-on: ubuntu-latest
    steps:
      - run: npm run build

  lint:
    runs-on: ubuntu-latest
    steps:
      - run: npm run lint

默认情况下,所有 job 并行执行。

4.3 Job 依赖(needs)

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test

  build:
    runs-on: ubuntu-latest
    needs: test  # 等待 test job 完成
    steps:
      - run: npm run build

  deploy:
    runs-on: ubuntu-latest
    needs: [test, build]  # 等待多个 job
    steps:
      - run: npm run deploy

5. Runner 环境

5.1 GitHub 托管 Runner

Runner 说明 适用场景
ubuntu-latest 最新 Ubuntu 通用 Linux 构建
ubuntu-22.04 Ubuntu 22.04 固定版本
windows-latest 最新 Windows .NET Framework 等
windows-2022 Windows Server 2022 固定版本
macos-latest 最新 macOS iOS/macOS 构建
macos-14 macOS 14 固定版本

5.2 自托管 Runner

runs-on: self-hosted  # 使用自托管 runner

# 或指定标签
runs-on: [self-hosted, linux, x64]

设置自托管 Runner:

  1. 进入仓库 → Settings → Actions → Runners
  2. 点击 "New self-hosted runner"
  3. 按照指引下载并配置

6. Steps 详解

6.1 使用 Action

steps:
  # 使用 GitHub 官方 action
  - name: Checkout
    uses: actions/checkout@v4

  # 使用社区 action(指定版本)
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '18'
      cache: 'npm'

  # 使用 Docker 容器 action
  - name: Run in Docker
    uses: docker://alpine:latest

6.2 执行 Shell 命令

steps:
  - name: Run shell command
    run: echo "Hello, World!"

  # 多行命令
  - name: Multi-line command
    run: |
      echo "Line 1"
      echo "Line 2"
      npm install
      npm test

  # 指定 shell
  - name: PowerShell script
    shell: pwsh
    run: Write-Host "Hello from PowerShell"

  # 工作目录
  - name: Build in subdir
    working-directory: ./src
    run: npm run build

6.3 环境变量

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      NODE_ENV: production
      API_KEY: ${{ secrets.API_KEY }}  # 从 secrets 读取

    steps:
      - name: Print env
        run: echo $NODE_ENV
        env:
          LOCAL_VAR: local_value  # step 级别的环境变量

7. 矩阵构建(Matrix Builds)

矩阵构建允许在多个配置组合上并行运行 job。

7.1 基础矩阵

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14, 16, 18]
        os: [ubuntu-latest, windows-latest]
        include:
          - os: macos-latest
            node-version: 18
        exclude:
          - os: windows-latest
            node-version: 14

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: Run tests
        run: npm test

上述配置会生成 5 个 job 组合:

  • ubuntu-latest + Node 14
  • ubuntu-latest + Node 16
  • ubuntu-latest + Node 18
  • windows-latest + Node 16
  • windows-latest + Node 18
  • macos-latest + Node 18

7.2 矩阵配置说明

关键字 说明
matrix 定义矩阵变量
include 添加额外的组合
exclude 排除特定组合
fail-fast 一个失败是否取消其他(默认 true)
max-parallel 最大并行数

8. 缓存策略

8.1 缓存依赖

steps:
  - uses: actions/checkout@v4

  - name: Cache node modules
    uses: actions/cache@v3
    with:
      path: ~/.npm
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-node-

  - name: Install dependencies
    run: npm ci

8.2 缓存策略说明

缓存目标 路径 键策略
npm ~/.npm hashFiles('**/package-lock.json')
yarn ~/.cache/yarn hashFiles('**/yarn.lock')
pip ~/.cache/pip hashFiles('**/requirements.txt')
Docker /tmp/.buildx-cache hashFiles('**/Dockerfile')

9. Artifacts(构建产物)

9.1 上传 Artifacts

steps:
  - name: Build
    run: npm run build

  - name: Upload artifacts
    uses: actions/upload-artifact@v3
    with:
      name: build-output
      path: dist/
      retention-days: 7  # 保留天数(默认 90)

9.2 下载 Artifacts

steps:
  - name: Download artifacts
    uses: actions/download-artifact@v3
    with:
      name: build-output
      path: dist/

10. Secrets 管理

10.1 设置 Secrets

  1. 进入仓库 → Settings → Secrets and variables → Actions
  2. 点击 "New repository secret"
  3. 输入名称和值

10.2 使用 Secrets

steps:
  - name: Deploy to server
    run: |
      echo "Deploying with API key: ${{ secrets.API_KEY }}"
      curl -H "Authorization: Bearer ${{ secrets.API_KEY }}" ...

10.3 环境变量与 Secrets 的区别

特性 env secrets
可见性 日志中可见 自动脱敏
适用场景 普通配置 密码、Token
加密存储 否 是

11. 自动化部署实践

11.1 部署到服务器(SSH)

name: Deploy to Server

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Deploy via SSH
        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/app
            git pull origin main
            docker-compose restart

11.2 部署到 Docker Hub

name: Build and Push Docker Image

on:
  push:
    tags: [ 'v*' ]

jobs:
  docker:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: myapp:latest,myapp:${{ github.ref_name }}

11.3 部署到 Kubernetes

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup kubectl
        uses: azure/setup-kubectl@v3
        with:
          version: 'latest'

      - name: Configure kubeconfig
        run: |
          echo "${{ secrets.KUBE_CONFIG }}" > ~/.kube/config
          chmod 600 ~/.kube/config

      - name: Deploy to K8s
        run: |
          kubectl set image deployment/myapp myapp=myapp:${{ github.sha }}
          kubectl rollout status deployment/myapp

12. 实战完整示例

12.1 Node.js 项目 CI/CD

13. 常见问题排查

13.1 Workflow 不触发

# 检查项:
1. workflow 文件是否在 .github/workflows/ 目录下
2. 文件名是否以 .yml 或 .yaml 结尾
3. YAML 语法是否正确(可用 yamllint 检查)
4. on 触发条件是否匹配当前事件

13.2 依赖下载慢

# 使用镜像加速
steps:
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '18'
      registry-url: 'https://registry.npmmirror.com'

13.3 权限错误

# 某些操作需要设置权限
permissions:
  contents: read
  packages: write

14. 最佳实践

  1. 使用具体版本:actions/checkout@v4 而非 actions/checkout@main
  2. 合理使用缓存:加速依赖安装
  3. 分离 job:测试、构建、部署分离,提高并行度
  4. 保护 secrets:不在日志中输出敏感信息
  5. 使用矩阵构建:一次测试多个版本
  6. 设置超时:避免 job 无限运行
  7. 使用 environment:生产部署增加审批流程
environment:
  name: production
  url: https://prod.example.com

15. 总结

GitHub Actions 是一个功能强大且易用的 CI/CD 平台。本文详细介绍了:

  1. 核心概念:workflow、job、step、action
  2. 触发事件:push、pull_request、schedule、workflow_dispatch
  3. 矩阵构建:多版本、多环境并行测试
  4. 缓存策略:加速依赖安装
  5. 自动化部署:SSH、Docker、Kubernetes 部署示例
  6. 最佳实践:安全性、性能优化、可维护性

下一步:

  • 为你的项目创建第一个 workflow
  • 探索 GitHub Marketplace 的 action
  • 结合项目需求定制 CI/CD 流程