GitHub Actions CI/CD¶
一句话概述:GitHub Actions 是 GitHub 内置的 CI/CD 平台,通过 YAML 定义工作流,自动完成代码构建、测试、部署全流程,每天执行超过 600 万个工作流。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| Workflow | 工作流 = 一个自动化流水线,用 YAML 文件定义 |
| Job | 作业 = 流水线中的一个大步骤,可并行执行 |
| Step | 步骤 = 作业里的一个小操作(运行命令或调用 Action) |
| Action | 可复用的"积木块",别人写好的功能你直接拿来用 |
| Runner | 运行器 = 执行你工作流的服务器(GitHub 提供免费的) |
| Event | 触发事件 = 什么时候启动工作流(push、PR、定时等) |
| Artifact | 产物 = 工作流产生的文件(如构建结果、测试报告) |
| Secret | 密钥 = 加密存储的敏感信息(API Key、密码等) |
| Matrix | 矩阵 = 同一个作业在多个环境下并行运行(如多 Python 版本) |
| Reusable Workflow | 可复用工作流 = 写一次、到处调用的模板 |
安装配置¶
GitHub Actions 无需安装,只要你的代码托管在 GitHub 上就能用。
# 在项目根目录创建工作流目录
mkdir -p .github/workflows # 创建 .github/workflows 目录,所有工作流 YAML 放这里
# 创建第一个工作流文件
touch .github/workflows/ci.yml # 创建 CI 工作流文件
基本 YAML 结构¶
# .github/workflows/ci.yml
name: CI Pipeline # 工作流名称,显示在 Actions 页面
on: # 触发条件
push: # 代码 push 时触发
branches: [main, develop] # 只在这些分支上触发
pull_request: # PR 时触发
branches: [main] # 只在向 main 提 PR 时触发
permissions: # 权限设置(2026 年新建仓库默认只读)
contents: read # 代码只读权限
jobs: # 定义作业
test: # 作业名称
runs-on: ubuntu-latest # 运行环境(Linux 4vCPU/16GB,2026 年新价格)
timeout-minutes: 30 # 超时时间,防止卡住浪费额度
steps: # 步骤列表
- uses: actions/checkout@v4 # 拉取代码
- name: Run tests # 步骤名称
run: echo "Hello CI" # 执行命令
基本使用¶
1. Python 项目 CI¶
name: Python CI # Python 项目持续集成
on:
push:
branches: [main] # main 分支 push 时触发
pull_request:
branches: [main] # 向 main 提 PR 时触发
jobs:
test:
runs-on: ubuntu-latest # 使用最新 Ubuntu 运行器
timeout-minutes: 20 # 设置 20 分钟超时
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12'] # 矩阵策略:测试多个 Python 版本
steps:
- uses: actions/checkout@v4 # 第1步:拉取代码
- name: Set up Python # 第2步:安装 Python
uses: actions/setup-python@v5 # 使用官方 Python 安装 Action
with:
python-version: ${{ matrix.python-version }} # 使用矩阵中的版本
cache: 'pip' # 缓存 pip 依赖,加速后续运行
- name: Install dependencies # 第3步:安装依赖
run: |
python -m pip install --upgrade pip # 升级 pip
pip install -r requirements.txt # 安装项目依赖
pip install pytest pytest-cov # 安装测试工具
- name: Run tests # 第4步:运行测试
run: pytest --cov=src --cov-report=xml # 运行测试并生成覆盖率报告
- name: Upload coverage # 第5步:上传覆盖率报告
uses: actions/upload-artifact@v4 # 上传为构建产物
with:
name: coverage-${{ matrix.python-version }} # 产物名称带版本号
path: coverage.xml # 上传覆盖率文件
2. 生信项目 CI(Conda 环境)¶
name: Bioinformatics CI # 生信项目 CI
on:
push:
branches: [main]
jobs:
bioinfo-test:
runs-on: ubuntu-latest
timeout-minutes: 45 # 生信工具安装慢,给多点时间
steps:
- uses: actions/checkout@v4 # 拉取代码
- name: Setup Conda # 安装 Conda
uses: conda-incubator/setup-miniconda@v3 # 使用 Conda 安装 Action
with:
activate-environment: bioinfo # 激活名为 bioinfo 的环境
environment-file: environment.yml # 从 environment.yml 创建环境
auto-activate-base: false # 不自动激活 base 环境
- name: Run pipeline # 运行流程
shell: bash -el {0} # 使用 bash 并加载环境
run: |
conda list # 列出已安装的包
python scripts/run_pipeline.py # 运行分析流程
3. 自动部署¶
name: Deploy # 部署工作流
on:
push:
tags: ['v*'] # 只在打 v 开头的 tag 时触发(如 v1.0.0)
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # 使用 production 环境(可设置审批)
permissions:
id-token: write # OIDC 认证需要的权限
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS # 配置 AWS 凭证(推荐 OIDC 方式)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }} # 使用 IAM 角色,不用密钥
aws-region: us-east-1 # AWS 区域
- name: Deploy # 执行部署
run: aws s3 sync ./dist s3://my-bucket # 同步文件到 S3
高级用法¶
1. 可复用工作流¶
# .github/workflows/reusable-test.yml(可复用工作流模板)
name: Reusable Test Workflow
on:
workflow_call: # 允许被其他工作流调用
inputs:
python-version: # 输入参数
required: true
type: string
secrets:
DEPLOY_KEY: # 密钥参数
required: false
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }} # 使用传入的版本
- run: pytest
# .github/workflows/ci.yml(调用可复用工作流)
name: CI
on: [push]
jobs:
call-test:
uses: ./.github/workflows/reusable-test.yml # 调用可复用工作流
with:
python-version: '3.12' # 传入参数
secrets: inherit # 继承所有密钥
2. 缓存优化¶
- name: Cache pip # 缓存 pip 依赖
uses: actions/cache@v4
with:
path: ~/.cache/pip # 缓存路径
key: pip-${{ runner.os }}-${{ hashFiles('requirements.txt') }} # 缓存键(依赖文件变化就更新)
restore-keys: | # 后备键(找不到精确匹配时用)
pip-${{ runner.os }}-
3. 条件执行与环境变量¶
steps:
- name: Deploy to production # 仅在 main 分支部署
if: github.ref == 'refs/heads/main' # 条件:只在 main 分支
run: ./deploy.sh
env:
API_KEY: ${{ secrets.API_KEY }} # 从密钥中读取环境变量
NODE_ENV: production # 设置环境变量
常见报错¶
| 报错信息 | 原因 | 解决方法 |
|---|---|---|
Error: Process completed with exit code 1 | 命令执行失败 | 本地先跑一遍命令,确认能通过 |
Resource not accessible by integration | 权限不足 | 在 permissions 中添加对应权限 |
No matching runner found | 没有可用的运行器 | 检查 runs-on 是否拼写正确 |
Error: Input required and not supplied: xxx | Action 缺少必填参数 | 查看 Action 文档补充 with 参数 |
Error: HttpError: API rate limit exceeded | GitHub API 限速 | 用 ${{ secrets.GITHUB_TOKEN }} 认证 |
Error: The template is not valid | YAML 语法错误 | 用 actionlint 检查 YAML 格式 |
Annotation: Node.js 16 actions are deprecated | Action 版本过旧 | 升级 Action 到最新版(如 v4) |
速查表¶
# === 触发条件 ===
on: push # push 时触发
on: pull_request # PR 时触发
on: schedule: [{cron: '0 2 * * 1'}] # 每周一凌晨2点
on: workflow_dispatch # 手动触发
on: workflow_call # 被其他工作流调用
# === 运行环境 ===
runs-on: ubuntu-latest # Linux(4vCPU/16GB)
runs-on: windows-latest # Windows
runs-on: macos-latest # macOS
# === 常用 Action ===
actions/checkout@v4 # 拉取代码
actions/setup-python@v5 # 安装 Python
actions/setup-node@v4 # 安装 Node.js
actions/cache@v4 # 缓存依赖
actions/upload-artifact@v4 # 上传产物
actions/download-artifact@v4 # 下载产物
# === 常用表达式 ===
${{ github.ref }} # 当前分支/标签
${{ github.sha }} # 当前提交 SHA
${{ github.actor }} # 触发者用户名
${{ secrets.MY_SECRET }} # 读取密钥
${{ matrix.version }} # 矩阵变量
${{ needs.job1.result }} # 依赖作业的结果
# === 安全最佳实践 ===
# 1. 固定 Action 到 SHA(防止供应链攻击)
uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675
# 2. 设置最小权限
permissions: { contents: read }
# 3. 使用 OIDC 替代长期密钥
# 4. 设置超时防止卡住
timeout-minutes: 30
参考:GitHub Actions 文档 | 2026 安全路线图 | 更新于 2026 年