GitHub Actions 基础
GitHub Actions 是 GitHub 提供的持续集成和持续部署(CI/CD)平台,可以自动化构建、测试和部署流程。
核心概念
工作流(Workflow)
工作流是一个可配置的自动化过程,定义在一个或多个作业中。工作流文件使用 YAML 格式,存放在仓库的 .github/workflows 目录下。
一个仓库可以有多个工作流文件,每个文件定义一个独立的工作流。
作业(Job)
作业是工作流中的一组步骤,在同一个运行器上执行。默认情况下,多个作业并行运行,可以通过依赖关系配置顺序执行。
步骤(Step)
步骤是作业中的最小执行单元,可以是:
- 执行 shell 命令
- 运行一个 Action
Action
Action 是可重用的代码单元,可以在工作流中引用。GitHub 提供了官方 Actions,社区也贡献了大量第三方 Actions。
运行器(Runner)
运行器是执行工作流的服务器。GitHub 提供:
ubuntu-latest:Linux 环境windows-latest:Windows 环境macos-latest:macOS 环境
也可以使用自托管运行器。
工作流文件结构
一个完整的工作流文件包含以下部分:
name: 工作流名称
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 运行脚本
run: echo "Hello, GitHub Actions!"
触发器配置
on 字段定义工作流的触发条件。
推送触发
on:
push:
branches:
- main
- 'release/*'
tags:
- 'v*'
paths:
- 'src/**'
- '.github/workflows/**'
拉取请求触发
on:
pull_request:
branches: [ main ]
types: [ opened, synchronize, closed ]
定时触发
使用 cron 表达式定时执行:
on:
schedule:
- cron: '0 0 * * *'
cron 表达式格式:分 时 日 月 周
0 0 * * *:每天零点0 0 * * 1:每周一零点0 0 1 * *:每月一号零点
手动触发
on:
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
多事件触发
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
作业配置
运行环境
jobs:
build:
runs-on: ubuntu-latest
支持的运行器:
| 运行器 | 系统 | 说明 |
|---|---|---|
ubuntu-latest | Ubuntu | 最常用,预装主流开发工具 |
windows-latest | Windows | 支持 .NET、PowerShell |
macos-latest | macOS | 支持 iOS、macOS 开发 |
作业依赖
使用 needs 指定作业依赖关系:
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "构建完成"
test:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "测试完成"
deploy:
needs: [build, test]
runs-on: ubuntu-latest
steps:
- run: echo "部署完成"
条件执行
使用 if 条件控制作业或步骤执行:
jobs:
deploy:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "部署到生产环境"
常用条件表达式:
if: github.event_name == 'push'
if: github.ref == 'refs/heads/main'
if: startsWith(github.ref, 'refs/tags/')
if: github.event.pull_request.merged == true
环境变量
作业级别环境变量:
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_ENV: production
DATABASE_URL: postgres://localhost:5432/test
steps:
- run: echo $NODE_ENV
工作流级别环境变量:
env:
GLOBAL_VAR: value
jobs:
build:
runs-on: ubuntu-latest
默认值
为所有 run 步骤设置默认 shell 和工作目录:
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./app
steps:
- run: pwd
步骤配置
运行命令
使用 run 执行 shell 命令:
steps:
- name: 安装依赖
run: npm install
- name: 多行命令
run: |
npm install
npm run build
npm test
使用 Action
使用 uses 引用 Action:
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
条件步骤
steps:
- name: 仅在主分支执行
if: github.ref == 'refs/heads/main'
run: echo "主分支"
- name: 仅在失败时执行
if: failure()
run: echo "前面的步骤失败了"
- name: 始终执行
if: always()
run: echo "清理工作"
继续执行
即使步骤失败也继续执行后续步骤:
steps:
- name: 可能失败的步骤
continue-on-error: true
run: exit 1
- name: 继续执行
run: echo "继续执行"
超时设置
steps:
- name: 限时步骤
timeout-minutes: 10
run: ./long-running-script.sh
Secrets 和上下文
使用 Secrets
Secrets 用于存储敏感信息,在仓库设置中配置:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 部署
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
echo "使用 API_KEY 进行部署"
GitHub 上下文
GitHub 提供了丰富的上下文信息:
steps:
- name: 打印上下文
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
常用上下文变量:
| 变量 | 说明 |
|---|---|
github.event_name | 触发事件名称 |
github.ref | 分支或标签引用 |
github.sha | 提交 SHA |
github.repository | 仓库名称 |
github.workflow | 工作流名称 |
github.run_id | 运行 ID |
github.run_number | 运行序号 |
github.actor | 触发者用户名 |
环境变量引用
env:
MY_VAR: ${{ github.repository }}-${{ github.run_number }}
steps:
- run: echo $MY_VAR
输出变量
步骤可以定义输出变量供后续步骤使用:
jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- id: get_version
run: echo "version=1.0.0" >> $GITHUB_OUTPUT
- run: echo "版本是 ${{ steps.get_version.outputs.version }}"
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "部署版本 ${{ needs.build.outputs.version }}"
矩阵构建
矩阵构建可以在多个配置组合下运行作业:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
fail-fast: false
max-parallel: 4
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
这个配置会生成 9 个作业(3 系统 × 3 Node 版本)。
排除特定组合
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20]
exclude:
- os: windows-latest
node: 18
包含特定组合
strategy:
matrix:
os: [ubuntu-latest]
node: [18, 20]
include:
- os: macos-latest
node: 20
experimental: true
缓存依赖
缓存可以加速工作流执行:
steps:
- uses: actions/checkout@v4
- name: 缓存 Node 模块
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- run: npm ci
常用缓存路径:
| 包管理器 | 路径 |
|---|---|
| npm | ~/.npm |
| pnpm | ~/.pnpm-store |
| Yarn | ~/.cache/yarn |
| pip | ~/.cache/pip |
| Maven | ~/.m2/repository |
| Gradle | ~/.gradle/caches |
工件上传
工件用于在作业间共享文件或保存构建产物:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
- name: 上传构建产物
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 5
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: 下载构建产物
uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
完整示例
以下是一个完整的 Node.js 项目 CI 工作流:
name: Node.js CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
NODE_ENV: test
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
needs: lint
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm ci
- run: npm test
- name: 上传覆盖率
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
常用官方 Actions
| Action | 用途 |
|---|---|
actions/checkout | 检出代码 |
actions/setup-node | 配置 Node.js |
actions/setup-python | 配置 Python |
actions/setup-java | 配置 Java |
actions/setup-go | 配置 Go |
actions/cache | 缓存依赖 |
actions/upload-artifact | 上传工件 |
actions/download-artifact | 下载工件 |
actions/github-script | 执行 GitHub API 脚本 |
最佳实践
- 使用具体的 Action 版本:使用 SHA 或具体版本号,避免使用
@main - 最小权限原则:配置
permissions限制 GITHUB_TOKEN 权限 - 使用缓存:缓存依赖加速构建
- 保护 Secrets:不要在日志中暴露敏感信息
- 设置超时:防止工作流无限运行
- 使用矩阵构建:多版本、多系统测试
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
packages: write