GitHub Actions速查
workflow结构/触发器/矩阵/secrets速查
🚦 workflow 文件结构
放在 .github/workflows/*.yml,推送后自动生效。
name: CI
on: [push, pull_request]
jobs:
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 test
name / on / jobs 是三个核心顶层字段。
name: 构建部署 # 工作流显示名
run-name: ${{ github.actor }} 触发 # 每次运行的动态名称
on: # 触发器
push:
branches: [main]
env: # 全局环境变量
NODE_VERSION: '20'
concurrency: # 并发分组
group: deploy-${{ github.ref }}
jobs:
build:
runs-on: ubuntu-latest
steps: []
🎯 on 触发器
按分支、标签、路径精确过滤触发条件。
on:
push:
branches:
- main
- 'release/**'
tags:
- 'v*'
paths:
- 'src/**'
- 'package-lock.json'
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
cron 使用 UTC 时间;workflow_dispatch 支持手动输入参数。
on:
schedule:
- cron: '0 2 * * *' # 每天 UTC 02:00(北京时间 10:00)
workflow_dispatch:
inputs:
env:
description: '部署环境'
type: choice
required: true
default: dev
options: [dev, staging, prod]
reason:
description: '发布原因'
type: string
release、workflow_run 链式调用,或 ignore 反向过滤。
on:
release:
types: [published]
workflow_run:
workflows: ["CI"]
types:
- completed
branches: [main]
issue_comment:
types: [created]
push:
branches-ignore:
- 'docs/**'
paths-ignore:
- '**.md'
🧱 jobs 与 steps
runs-on 指定运行环境;needs 构成有向无环依赖图。
jobs:
build:
name: 构建
runs-on: ubuntu-latest # ubuntu / windows / macos,或 self-hosted
timeout-minutes: 10
environment: production
outputs:
version: ${{ steps.meta.outputs.version }}
steps:
- id: meta
run: echo "version=1.0.${{ github.run_number }}" >> "$GITHUB_OUTPUT"
被依赖 job 成功后才执行;可引用其 outputs。
jobs:
lint:
runs-on: ubuntu-latest
steps: [{ run: npm run lint }]
test:
runs-on: ubuntu-latest
steps: [{ run: npm test }]
deploy:
needs: [lint, test]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "上游产物 ${{ needs.lint.result }}"
多行用 |;$ 原样输出用单引号;可指定工作目录与 shell。
- name: 安装与构建
working-directory: ./web
shell: bash
run: |
node -v
npm ci
npm run build
echo "BUILD_AT=$(date -u +%FT%TZ)" >> "$GITHUB_ENV"
- run: echo "简单一行命令"
- run: dir
shell: cmd
step 写 $GITHUB_OUTPUT 暴露,job 声明 outputs 供 needs 读取。
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.set.outputs.tag }}
steps:
- id: set
run: echo "tag=${GITHUB_REF_NAME:-dev}" >> "$GITHUB_OUTPUT"
build:
needs: prepare
runs-on: ubuntu-latest
steps:
- run: echo "构建标签 ${{ needs.prepare.outputs.tag }}"
遵循最小权限原则,默认收紧后按需放开。
permissions:
contents: read # 全局默认只读
jobs:
release:
permissions:
contents: write # 发 release 需要
packages: write
id-token: write # OIDC 免密连云厂商
pull-requests: write
steps:
- run: gh release create v1.0.0
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
🧩 官方常用 Action
几乎所有 workflow 第一步;浅克隆更快,发版需要完整历史。
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 完整历史,standard-version 等需要
submodules: recursive # 一并拉子模块
path: src # 检出到子目录
ref: develop # 指定 ref
token: ${{ secrets.PAT }}
安装指定 Node 版本;内置 cache 可省掉单独缓存步骤。
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm' # 自动缓存 ~/.npm
cache-dependency-path: package-lock.json
registry-url: 'https://registry.npmjs.org'
# 多版本交给矩阵
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
artifact 在同 workflow 的 job 间共享,保留期默认 90 天。
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 7
if-no-files-found: error
- uses: actions/download-artifact@v4
with:
name: dist
path: ./dist
# 其它常用
- uses: actions/cache@v4
- uses: actions/configure-pages@v5
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
🔀 矩阵 matrix
矩阵做笛卡尔积,自动生成多份并行 job。
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci && npm test
include 追加或给组合附加字段;exclude 剔除个别组合。
strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest, macos-latest]
include:
- node: 22
os: ubuntu-latest
experimental: true
exclude:
- node: 18
os: macos-latest
steps:
- if: matrix.experimental
run: echo "实验性版本允许失败"
🔐 环境变量与 Secrets
workflow / job / step 三级,内层覆盖外层。
env:
APP_NAME: myapp
jobs:
test:
env:
NODE_ENV: test
steps:
- run: echo $APP_NAME $NODE_ENV $STEP_VAR
env:
STEP_VAR: hello
# 写入 $GITHUB_ENV 后后续 step 都可见
- run: echo "NOW=$(date)" >> "$GITHUB_ENV"
- run: echo "$NOW"
仓库 Settings → Secrets 配置;日志中自动打码,不能直接 echo。
steps:
- name: 部署
run: ./deploy.sh
env:
API_TOKEN: ${{ secrets.API_TOKEN }}
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# 环境级 secret(绑定 environment,更严格)
environment:
name: production
# 组织级 secret:secrets.ORG_TOKEN 并在仓库设置中授权
自定义变量走 vars,密钥走 secrets,运行元数据在 github。
${{ github.actor }} # 触发者用户名
${{ github.repository }} # owner/repo
${{ github.ref }} # refs/heads/main
${{ github.ref_name }} # main / v1.0.0
${{ github.sha }} # 完整 commit SHA
${{ github.event_name }} # push / pull_request ...
${{ github.event.pull_request.number }}
${{ github.run_id }} / ${{ github.run_number }}
${{ vars.SITE_URL }} # 仓库/环境变量(非机密)
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
❓ 条件与容错
job 级或 step 级都可用;表达式内部可省略 ${{ }}。
if: github.ref == 'refs/heads/main'
if: github.event_name == 'pull_request'
if: matrix.node == 20
if: github.repository == 'org/prod-repo'
if: github.actor != 'dependabot[bot]'
if: vars.ENABLE_DEPLOY == 'true'
if: failure() # 上游失败才执行(告警场景)
if: always() # 无论成败(清理场景)
if: cancelled() == false
contains / startsWith / endsWith / fromJSON / join。
if: contains(github.event.head_commit.message, '[skip ci]') == false
if: startsWith(github.ref, 'refs/tags/v')
if: endsWith(matrix.os, 'latest')
- name: 解析 JSON
env:
MATRIX: ${{ vars.BUILD_MATRIX }}
run: |
echo "${MATRIX}"
node -e "console.log(JSON.parse(process.env.MATRIX))"
允许单步失败不中断整体;timeout-minutes 防止挂死。
- name: 实验性检查
continue-on-error: true
run: npm run experimental-check
- name: 可预期失败的矩阵
continue-on-error: ${{ matrix.experimental == true }}
run: npm test
jobs:
build:
timeout-minutes: 15
steps:
- timeout-minutes: 5 # step 级超时
run: ./slow-test.sh
🗄 缓存
Node 项目首选,零配置缓存 npm/yarn/pnpm 下载目录。
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: |
package-lock.json
subdir/package-lock.json
- run: npm ci
key 命中直接还原;restore-keys 支持前缀回退。
- uses: actions/cache@v4
with:
path: |
~/.cache/pip
**/__pycache__
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
# pnpm
- uses: actions/cache@v4
with:
path: ~/.local/share/pnpm/store
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
🚦 并发与复用
同组只保留一个运行,省 CI 时间;部署场景常用。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# 也可以放在单个 job 内
jobs:
preview:
concurrency:
group: preview-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
可配置环境保护规则:人工审批、等待计时器、环境专属 secret。
jobs:
deploy-prod:
needs: build
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- run: ./deploy.sh
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
把通用流程抽成 reusable workflow,其他仓库/流程统一调用。
# 调用方
jobs:
call:
uses: org/reusable/.github/workflows/build.yml@v1
with:
node-version: 20
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# 被调用方(build.yml 需声明 workflow_call)
on:
workflow_call:
inputs:
node-version: { type: string, required: false, default: '20' }
secrets:
NPM_TOKEN: { required: true }
😶 没有匹配的条目,换个关键词试试
📖 使用说明
全程在浏览器本地运行。
操作步骤:
- 搜索或浏览分类条目;
- 查看YAML配置示例;
- 点击复制代码块。
💬 用户评论 (0)
还没有评论,快来抢沙发!