Appearance
GitHub Actions触发器
GitHub Actions触发器(Triggers)是启动工作流执行的事件。理解各种触发器类型及其配置方法对于设计自动化工作流至关重要。
基本触发器类型
push事件
当代码推送到仓库时触发工作流:
yaml
# .github/workflows/push.yml
name: Push Trigger Example
on: push # 任何推送都会触发
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Print commit info
run: |
echo "Commit SHA: $GITHUB_SHA"
echo "Ref: $GITHUB_REF"
详细配置push事件
yaml
on:
push:
branches: [main, develop] # 仅在指定分支推送时触发
tags: ['v*'] # 仅在标签推送时触发
paths: # 仅在指定路径文件变更时触发
- 'src/**'
- 'package.json'
- 'Dockerfile'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build only on src changes
if: contains(github.event.head_commit.modified, 'src/')
run: echo "Source files changed, running build"
pull_request事件
当创建、更新或合并拉取请求时触发:
yaml
on:
pull_request:
branches: [main] # 仅针对指定目标分支的PR
types: [opened, synchronize, reopened] # 事件类型
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests on PR
run: npm test
完整的pull_request配置
yaml
on:
pull_request:
branches: [main, develop]
types:
- opened # PR创建
- synchronize # PR更新
- reopened # PR重新打开
- closed # PR关闭
- ready_for_review # PR准备就绪
paths-ignore: # 忽略某些路径
- 'docs/**'
- '*.md'
jobs:
security-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Security scan
run: |
echo "Scanning PR #${{ github.event.number }}"
echo "Source: ${{ github.event.pull_request.head.ref }}"
echo "Target: ${{ github.event.pull_request.base.ref }}"
高级触发器
schedule(定时触发)
使用cron表达式定期触发工作流:
yaml
on:
schedule:
# UTC时间 - 每天凌晨2点执行
- cron: '0 2 * * *'
# 每周一上午9点(UTC)
- cron: '0 9 * * 1'
# 每月1号凌晨3点
- cron: '0 3 1 * *'
jobs:
security-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run security audit
run: npm audit --audit-level high
- name: Send report
run: |
echo "Security report for $(date)" > report.txt
# 发送报告逻辑
workflow_dispatch(手动触发)
允许手动触发工作流:
yaml
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
tags:
description: 'Test scenario tags'
required: false
type: boolean
environment:
description: 'Environment to run tests against'
type: environment
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- run: |
echo "Log level: ${{ inputs.logLevel }}"
echo "Tags: ${{ inputs.tags }}"
echo "Environment: ${{ inputs.environment }}"
repository_dispatch
通过GitHub API触发工作流:
yaml
on:
repository_dispatch:
types: [custom-event]
jobs:
custom-workflow:
runs-on: ubuntu-latest
steps:
- name: Handle custom event
run: |
echo "Action: ${{ github.event.action }}"
echo "Client payload: ${{ toJSON(github.event.client_payload) }}"
特定事件触发器
release事件
在版本发布时触发:
yaml
on:
release:
types: [published, created, edited]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get release info
run: |
echo "Release tag: ${{ github.event.release.tag_name }}"
echo "Release name: ${{ github.event.release.name }}"
echo "Release body: ${{ github.event.release.body }}"
- name: Publish to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
issue_comment事件
在问题评论时触发:
yaml
on:
issue_comment:
types: [created, edited]
jobs:
auto-response:
runs-on: ubuntu-latest
steps:
- name: Check comment
run: |
COMMENT_BODY="${{ github.event.comment.body }}"
if [[ "$COMMENT_BODY" == "/deploy" ]]; then
echo "DEPLOY=true" >> $GITHUB_ENV
fi
- name: Deploy on command
if: env.DEPLOY == 'true'
run: echo "Deploying based on comment command"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
fork事件
当仓库被fork时触发:
yaml
on:
fork
jobs:
welcome:
runs-on: ubuntu-latest
steps:
- name: Send welcome message
run: |
echo "Thanks for forking the repository!"
# 可以通过API发送欢迎信息
复合事件配置
多事件触发
yaml
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
条件事件触发
yaml
on:
push:
branches: [main, develop]
paths:
- 'src/**'
- 'package.json'
pull_request:
branches: [main]
paths:
- 'src/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build on relevant changes
run: npm run build
事件过滤
路径过滤
yaml
on:
push:
paths:
- 'src/**' # src目录下所有文件
- 'package.json' # 特定文件
- 'config/**' # config目录
paths-ignore:
- 'docs/**' # 忽略docs目录
- '**/*.md' # 忽略所有markdown文件
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build only on code changes
run: npm run build
分支过滤
yaml
on:
push:
branches:
- main # main分支
- develop # develop分支
- feature/* # 所有feature/开头的分支
branches-ignore:
- experimental/* # 忽略experimental/开头的分支
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy based on branch
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "Deploying to production"
elif [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then
echo "Deploying to staging"
else
echo "Deploying to feature environment"
fi
标签过滤
yaml
on:
push:
tags:
- 'v*' # 所有v开头的标签
- 'release-*' # release-开头的标签
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Get tag info
run: |
TAG_NAME="${GITHUB_REF#refs/tags/}"
echo "Publishing version: $TAG_NAME"
if [[ "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Valid semantic version tag"
# 发布逻辑
else
echo "Invalid tag format"
exit 1
fi
事件负载访问
访问事件数据
yaml
on:
push:
branches: [main]
jobs:
analyze-push:
runs-on: ubuntu-latest
steps:
- name: Analyze push event
run: |
echo "Event name: ${{ github.event_name }}"
echo "Repository: ${{ github.repository }}"
echo "SHA: ${{ github.sha }}"
echo "Ref: ${{ github.ref }}"
echo "Actor: ${{ github.actor }}"
# 访问推送事件的具体数据
echo "Number of commits: ${{ github.event.size }}"
echo "Pusher: ${{ github.event.pusher.name }}"
# 遍历提交
for commit in ${{ toJSON(github.event.commits) }}; do
echo "Commit: $commit"
done
pull_request事件数据
yaml
on:
pull_request:
types: [opened, synchronize]
jobs:
pr-analysis:
runs-on: ubuntu-latest
steps:
- name: Analyze PR
run: |
echo "PR Number: ${{ github.event.number }}"
echo "PR Title: ${{ github.event.pull_request.title }}"
echo "PR Author: ${{ github.event.pull_request.user.login }}"
echo "PR Branch: ${{ github.event.pull_request.head.ref }}"
echo "Target Branch: ${{ github.event.pull_request.base.ref }}"
echo "PR Body: ${{ github.event.pull_request.body }}"
# 检查PR是否包含特定关键词
if [[ "${{ github.event.pull_request.title }}" =~ ^feat ]]; then
echo "TYPE=feature" >> $GITHUB_ENV
elif [[ "${{ github.event.pull_request.title }}" =~ ^fix ]]; then
echo "TYPE=bugfix" >> $GITHUB_ENV
else
echo "TYPE=other" >> $GITHUB_ENV
fi
高级触发模式
条件触发
yaml
on:
push:
branches: [main]
jobs:
conditional-build:
runs-on: ubuntu-latest
if: |
!contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[ci skip]')
steps:
- uses: actions/checkout@v4
- name: Build if not skipped
run: npm run build
环境特定触发
yaml
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
environment: staging
steps:
- name: Deploy to staging
run: echo "Deploying to staging environment"
deploy-production:
runs-on: ubuntu-latest
if: |
github.ref == 'refs/heads/main' &&
github.event_name == 'push'
environment: production
steps:
- name: Deploy to production
run: echo "Deploying to production environment"
实用触发器示例
自动化标签发布
yaml
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
jobs:
publish-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Extract version
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Create release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.version.outputs.version }}
release_name: Release ${{ steps.version.outputs.version }}
draft: false
prerelease: false
代码质量检查
yaml
on:
push:
branches: [main, develop]
paths:
- '**.js'
- '**.ts'
- '**.jsx'
- '**.tsx'
pull_request:
branches: [main]
paths:
- '**.js'
- '**.ts'
- '**.jsx'
- '**.tsx'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
- run: npm ci
- run: npm run lint
- run: npm run type-check
安全扫描
yaml
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 1' # 每周一午夜
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Dependency scan
run: |
npm audit --audit-level high
# 其他安全扫描工具
最佳实践
1. 精确触发
yaml
# 好的做法:精确过滤
on:
push:
branches: [main]
paths:
- 'src/**'
- 'package.json'
- 'Dockerfile'
# 避免:过于宽泛的触发
# on: push # 任何推送都触发,可能过于频繁
2. 分离关注点
yaml
# 将不同类型的触发器放在不同的工作流文件中
# .github/workflows/ci.yml - 代码变更触发
# .github/workflows/scheduled.yml - 定时任务
# .github/workflows/manual.yml - 手动触发
# .github/workflows/release.yml - 发布触发
3. 使用skip模式
yaml
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- run: echo "Build running..."
通过合理配置触发器,可以确保工作流在适当的时机执行,避免不必要的资源消耗,同时满足各种自动化需求。