name: act-workflow-syntax user-invocable: false description: 在创建或修改GitHub Actions工作流文件时使用。提供工作流语法、触发器、作业和表达式的指南,用于创建可以在本地使用act测试的有效GitHub Actions工作流。 allowed-tools:
- Read
- Write
- Edit
- Bash
- Grep
- Glob
Act - GitHub Actions 工作流语法
在创建或修改GitHub Actions工作流文件(.github/workflows/*.yml)时使用此技能。这涵盖了工作流结构、触发器、作业、步骤,以及适用于GitHub和本地使用act的工作流最佳实践。
工作流文件结构
每个GitHub Actions工作流都遵循以下基本结构:
name: 工作流名称
user-invocable: false
on: [push, pull_request] # 触发器
jobs:
作业名称:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 步骤名称
run: echo "命令在这里"
顶级字段
name: 人类可读的工作流名称(可选但推荐)on: 触发事件(push、pull_request、workflow_dispatch等)env: 所有作业可用的环境变量jobs: 作业定义的映射permissions: 工作流的令牌权限
工作流触发器
事件触发器
# 单一事件
on: push
# 多个事件
on: [push, pull_request]
# 带过滤器的事件
on:
push:
branches:
- main
- 'releases/**'
paths:
- '**.js'
- '!docs/**'
pull_request:
types: [opened, synchronize, reopened]
手动触发器
on:
workflow_dispatch:
inputs:
environment:
description: '目标环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
计划触发器
on:
schedule:
- cron: '0 9 * * 1' # 每周一上午9点UTC
作业配置
基本作业
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
带环境变量的作业
jobs:
deploy:
runs-on: ubuntu-latest
env:
NODE_ENV: production
API_URL: ${{ secrets.API_URL }}
steps:
- run: echo "部署到 $NODE_ENV"
作业依赖
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
test:
needs: build
runs-on: ubuntu-latest
steps:
- run: npm test
deploy:
needs: [build, test]
runs-on: ubuntu-latest
steps:
- run: npm run deploy
矩阵构建
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [18, 20, 22]
fail-fast: false
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
步骤
使用动作
steps:
# 检出代码
- uses: actions/checkout@v4
# 设置Node.js
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# 上传构件
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
运行命令
steps:
# 单行
- run: npm install
# 多行
- run: |
npm ci
npm run build
npm test
# 带名称
- name: 安装依赖
run: npm ci
# 带工作目录
- run: npm test
working-directory: ./packages/core
# 带shell
- run: echo "Hello"
shell: bash
条件步骤
steps:
- name: 部署到生产环境
if: github.ref == 'refs/heads/main'
run: npm run deploy
- name: 成功时运行
if: success()
run: echo "前一步骤成功"
- name: 失败时运行
if: failure()
run: echo "一个步骤失败"
- name: 总是运行
if: always()
run: echo "无论状态如何都运行"
表达式和上下文
常见上下文
steps:
- run: echo "事件: ${{ github.event_name }}"
- run: echo "分支: ${{ github.ref_name }}"
- run: echo "SHA: ${{ github.sha }}"
- run: echo "参与者: ${{ github.actor }}"
- run: echo "作业状态: ${{ job.status }}"
- run: echo "运行器操作系统: ${{ runner.os }}"
使用机密
steps:
- run: echo "令牌已设置"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
API_KEY: ${{ secrets.API_KEY }}
函数
steps:
- if: contains(github.event.head_commit.message, '[skip ci]')
run: echo "跳过CI"
- if: startsWith(github.ref, 'refs/tags/')
run: echo "这是一个标签"
- if: endsWith(github.ref, '/main')
run: echo "这是主分支"
- run: echo "${{ format('Hello {0}', github.actor) }}"
Act特定考虑
使用Act本地测试
# 运行所有工作流
act
# 运行特定事件
act push
# 运行特定作业
act -j build
# 干运行(验证而不执行)
act --dryrun
# 列出工作流
act -l
# 使用特定平台
act -P ubuntu-latest=catthehacker/ubuntu:act-latest
Act的环境变量
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 检查环境
run: |
if [ "$ACT" = "true" ]; then
echo "在act中运行"
else
echo "在GitHub上运行"
fi
使用Act的机密
创建.secrets文件用于本地测试:
GITHUB_TOKEN=ghp_your_token_here
API_KEY=your_api_key_here
然后运行:
act --secret-file .secrets
或单独传递机密:
act -s GITHUB_TOKEN=ghp_token -s API_KEY=key
最佳实践
应做
✅ 使用语义化的作业和步骤名称
✅ 固定动作版本(actions/checkout@v4)
✅ 对矩阵构建使用 fail-fast: false 以查看所有结果
✅ 为作业设置适当的 timeout-minutes
✅ 使用 working-directory 而不是cd命令
✅ 推送前使用 act --dryrun 本地测试工作流
✅ 对依赖使用缓存
✅ 对部署作业使用环境
不应做
❌ 在工作流文件中硬编码机密
❌ 对动作使用 latest 标签
❌ 在每个文件更改时运行工作流(使用路径过滤器)
❌ 创建过于复杂的工作流(拆分为多个文件)
❌ 忽略使用GitHub特定功能时的act兼容性
❌ 忘记验证YAML语法
常见模式
构建和测试
name: CI
user-invocable: false
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
- run: npm run build
在标签上部署
name: 部署
user-invocable: false
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 获取版本
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- run: echo "部署 ${{ steps.version.outputs.VERSION }}"
单仓库带变更文件检测
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
api: ${{ steps.changes.outputs.api }}
web: ${{ steps.changes.outputs.web }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
api:
- 'packages/api/**'
web:
- 'packages/web/**'
build-api:
needs: detect-changes
if: needs.detect-changes.outputs.api == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "构建API"
相关技能
- act-local-testing: 推送前本地测试工作流
- act-docker-setup: 为act配置Docker环境
- act-secrets-management: 管理本地测试的机密