625 GitHub Actions CI/CD
一句话概述:GitHub Actions 是 GitHub 内置的 CI/CD 平台,用 YAML 定义自动化工作流(测试、构建、部署),推送代码自动触发,免费额度充足,是开源项目和中小团队的首选。
核心知识点速查表
| 知识点 | 说明 |
|---|
| 最新动态 | Runner Scale Set Client(2026年2月)、自定义 Runner 镜像 GA |
| 免费额度 | 公开仓库无限、私有仓库 2000 分钟/月 |
| 运行环境 | Ubuntu、macOS、Windows Runner |
| 核心概念 | Workflow → Job → Step → Action |
| 配置文件 | .github/workflows/xxx.yml |
| 适用场景 | CI/CD、自动测试、自动部署、定时任务 |
一、核心概念
白话解释:
- Workflow(工作流) = 一套自动化流程(一个 YAML 文件)
- Event(事件) = 触发工作流的动作(push、PR、定时等)
- Job(作业) = 工作流中的一个大步骤(可以并行)
- Step(步骤) = 作业中的一个小步骤(顺序执行)
- Action(动作) = 可复用的自动化单元(别人写好的,直接用)
- Runner(运行器) = 执行作业的机器(GitHub 提供或自托管)
二、基本使用
2.1 第一个工作流
# .github/workflows/ci.yml
name: CI 测试 # 工作流名称(显示在 Actions 页面)
on: # 触发条件
push:
branches: [main, dev] # main 和 dev 分支 push 时触发
pull_request:
branches: [main] # 对 main 的 PR 时触发
jobs:
test: # 作业名(自定义)
runs-on: ubuntu-latest # 运行环境(GitHub 提供的 Ubuntu 虚拟机)
steps: # 步骤列表(按顺序执行)
- name: 检出代码 # 步骤名
uses: actions/checkout@v4 # 使用官方 Action:检出仓库代码
- name: 安装 Node.js
uses: actions/setup-node@v4 # 官方 Action:安装 Node.js
with:
node-version: 22 # 指定 Node.js 版本
cache: 'npm' # 缓存 npm 依赖(加速构建)
- name: 安装依赖
run: npm ci # run:执行 shell 命令
- name: 运行测试
run: npm test
- name: 构建
run: npm run build
2.2 Python 项目 CI
# .github/workflows/python-ci.yml
name: Python CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix: # 矩阵策略:多版本并行测试
python-version: ['3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- name: 安装 Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }} # 使用矩阵变量
cache: 'pip' # 缓存 pip 依赖
- name: 安装依赖
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov # 安装测试工具
- name: 代码检查
run: |
pip install ruff # 安装 Ruff(代码检查+格式化)
ruff check . # 检查代码问题
ruff format --check . # 检查代码格式
- name: 运行测试
run: pytest --cov=src --cov-report=xml # 运行测试并生成覆盖率报告
- name: 上传覆盖率报告
uses: codecov/codecov-action@v4 # 上传到 Codecov
with:
file: coverage.xml
三、触发条件详解
on:
# 推送触发
push:
branches: [main, 'release/**'] # 指定分支(支持通配符)
paths: # 只有特定文件变化才触发
- 'src/**'
- '!src/**/*.md' # 排除 md 文件
tags:
- 'v*' # 标签推送触发(如 v1.0.0)
# Pull Request 触发
pull_request:
types: [opened, synchronize, reopened] # PR 事件类型
# 定时触发(Cron 语法)
schedule:
- cron: '0 2 * * 1' # 每周一凌晨2点(UTC)
# 手动触发
workflow_dispatch:
inputs: # 手动触发时的输入参数
environment:
description: '部署环境'
required: true
type: choice
options:
- staging
- production
四、高级用法
4.1 Secrets 和环境变量
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # 使用 production 环境(可配置审批)
steps:
- uses: actions/checkout@v4
- name: 部署到服务器
env:
SERVER_HOST: ${{ secrets.SERVER_HOST }} # 从仓库 Secrets 读取
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
echo "部署到 $SERVER_HOST"
# 使用 SSH 部署...
白话:Secrets 在 GitHub 仓库 Settings → Secrets and variables → Actions 中设置
敏感信息(密码、API Key)放在 Secrets 里,不要写在 YAML 中
4.2 缓存依赖
- name: 缓存 pip 依赖
uses: actions/cache@v4
with:
path: ~/.cache/pip # 缓存路径
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} # 缓存键
restore-keys: | # 备用键(精确匹配失败时用前缀匹配)
${{ runner.os }}-pip-
# 白话:requirements.txt 没变时,直接用缓存,不用重新下载
4.3 Job 依赖与条件
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
build:
needs: test # 依赖 test 作业(test 通过才执行 build)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
deploy:
needs: [test, build] # 依赖多个作业
if: github.ref == 'refs/heads/main' # 条件:只在 main 分支执行
runs-on: ubuntu-latest
steps:
- run: echo "部署到生产环境"
4.4 Docker 镜像构建与推送
jobs:
docker:
runs-on: ubuntu-latest
permissions:
packages: write # 授权推送到 GitHub Packages
steps:
- uses: actions/checkout@v4
- name: 登录 Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: 构建并推送镜像
uses: docker/build-push-action@v6
with:
context: . # 构建上下文
push: true # 推送到仓库
tags: |
myuser/myapp:latest
myuser/myapp:${{ github.sha }} # 用 commit SHA 做标签
cache-from: type=gha # 使用 GitHub Actions 缓存
cache-to: type=gha,mode=max
4.5 OIDC 认证(无密钥部署)
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # 启用 OIDC(OpenID Connect)
contents: read
steps:
- uses: actions/checkout@v4
# AWS OIDC 认证(不需要长期密钥)
- name: 配置 AWS 凭证
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
aws-region: us-east-1
# 白话:用 OIDC 临时凭证,比放 Access Key 在 Secrets 更安全
4.6 可复用工作流
# .github/workflows/reusable-test.yml(可复用工作流)
name: 可复用测试
on:
workflow_call: # 标记为可被其他工作流调用
inputs:
python-version:
required: true
type: string
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- run: pip install -r requirements.txt && pytest
# .github/workflows/ci.yml(调用方)
jobs:
call-test:
uses: ./.github/workflows/reusable-test.yml # 调用可复用工作流
with:
python-version: '3.12'
五、常见报错与解决
| 问题 | 解决 |
|---|
Permission denied | 检查 permissions 配置,确保有对应权限 |
| 缓存不生效 | 检查 key 是否正确,hashFiles 路径是否存在 |
| Secret 为空 | Fork 仓库的 PR 无法访问 Secrets(安全设计) |
| 作业超时 | 默认 6 小时,用 timeout-minutes: 30 设置 |
| 并发冲突 | 用 concurrency 取消旧的运行 |
# 防止同一分支重复运行
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # 取消正在运行的旧作业
六、速查表
| 操作 | 配置 |
|---|
| 触发-推送 | on: push: branches: [main] |
| 触发-PR | on: pull_request |
| 触发-定时 | on: schedule: cron: '0 0 * * *' |
| 触发-手动 | on: workflow_dispatch |
| 检出代码 | uses: actions/checkout@v4 |
| 安装Node | uses: actions/setup-node@v4 |
| 安装Python | uses: actions/setup-python@v5 |
| 缓存依赖 | uses: actions/cache@v4 |
| 运行命令 | run: 命令 |
| 使用密钥 | ${{ secrets.NAME }} |
| 条件执行 | if: github.ref == 'refs/heads/main' |
| 作业依赖 | needs: [job1, job2] |
七、同类工具对比
| 特性 | GitHub Actions | GitLab CI | Jenkins | CircleCI |
|---|
| 集成度 | GitHub 内置 | GitLab 内置 | 独立部署 | SaaS |
| 配置 | YAML | YAML | Groovy | YAML |
| 免费额度 | 2000分钟/月 | 400分钟/月 | 自托管免费 | 6000分钟/月 |
| 生态 | Marketplace | 中等 | 插件最多 | Orbs |
| 学习曲线 | 低 | 低 | 高 | 低 |
| 自托管Runner | 支持 | 支持 | 默认 | 支持 |
选型建议:GitHub 仓库首选 GitHub Actions(零配置集成);GitLab 仓库用 GitLab CI;需要高度定制选 Jenkins。
参考资料:GitHub Actions 文档 | Actions Marketplace | Workflow 语法