Skip to content
On this page

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..."

通过合理配置触发器,可以确保工作流在适当的时机执行,避免不必要的资源消耗,同时满足各种自动化需求。