GitHub Actions 定时触发 #

定时触发允许工作流按计划自动运行,适用于定期维护、报告生成等场景。本节详细介绍定时触发的配置和最佳实践。

schedule事件 #

基本语法 #

yaml
on:
  schedule:
    - cron: '0 0 * * *'

Cron表达式详解 #

text
┌───────────── 分钟 (0 - 59)
│ ┌───────────── 小时 (0 - 23)
│ │ ┌───────────── 日 (1 - 31)
│ │ │ ┌───────────── 月 (1 - 12)
│ │ │ │ ┌───────────── 星期 (0 - 6)
│ │ │ │ │
* * * * *

字段说明 #

字段 允许值 允许的特殊字符
分钟 0-59 * , -
小时 0-23 * , -
1-31 * , - ?
1-12 * , -
星期 0-6 (0是周日) * , - ?

特殊字符 #

字符 描述 示例
* 任意值 * * * * * 每分钟
, 值列表 0 0,12 * * * 每天0点和12点
- 范围 0 9-17 * * * 9点到17点每小时
? 任意值(日或星期) 0 0 ? * 1 每周一

常用Cron表达式 #

每天运行 #

yaml
on:
  schedule:
    - cron: '0 0 * * *'     # UTC 0点(北京时间8点)
    - cron: '0 8 * * *'     # UTC 8点(北京时间16点)

每周运行 #

yaml
on:
  schedule:
    - cron: '0 0 * * 0'     # 每周日UTC 0点
    - cron: '0 0 * * 1'     # 每周一UTC 0点
    - cron: '0 0 * * 1-5'   # 周一到周五UTC 0点

每月运行 #

yaml
on:
  schedule:
    - cron: '0 0 1 * *'     # 每月1日UTC 0点
    - cron: '0 0 1,15 * *'  # 每月1日和15日UTC 0点

间隔运行 #

yaml
on:
  schedule:
    - cron: '*/15 * * * *'  # 每15分钟
    - cron: '0 */6 * * *'   # 每6小时
    - cron: '0 0 */2 * *'   # 每2天

工作日运行 #

yaml
on:
  schedule:
    - cron: '0 9 * * 1-5'   # 周一到周五UTC 9点
    - cron: '0 17 * * 1-5'  # 周一到周五UTC 17点

时区处理 #

GitHub Actions使用UTC时间,需要转换为本地时间:

时区对照表 #

UTC 北京时间 (UTC+8) 美东时间 (UTC-5)
0:00 8:00 前一天19:00
8:00 16:00 3:00
16:00 24:00 11:00

北京时间示例 #

yaml
# 北京时间早上8点
- cron: '0 0 * * *'

# 北京时间下午5点
- cron: '0 9 * * *'

# 北京时间晚上10点
- cron: '0 14 * * *'

多定时任务 #

yaml
on:
  schedule:
    - cron: '0 0 * * *'     # 每天UTC 0点
    - cron: '0 12 * * *'    # 每天UTC 12点
    - cron: '0 0 * * 0'     # 每周日UTC 0点

定时任务示例 #

每日构建 #

yaml
name: Daily Build

on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - run: npm ci
      - run: npm run build
      - run: npm test
      
      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: daily-build
          path: dist/

定期清理 #

yaml
name: Cleanup

on:
  schedule:
    - cron: '0 0 * * 0'  # 每周日

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: Delete old artifacts
        uses: c-hive/gha-remove-artifacts@v1
        with:
          age: '7 days'
          skip-recent: 3
      
      - name: Delete old workflow runs
        uses: Mattraks/delete-workflow-runs@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          repository: ${{ github.repository }}
          retain_days: 30
          keep_minimum_runs: 3

定期报告 #

yaml
name: Weekly Report

on:
  schedule:
    - cron: '0 0 * * 0'  # 每周日
  workflow_dispatch:

jobs:
  report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Generate report
        run: |
          echo "## Weekly Report" > report.md
          echo "" >> report.md
          echo "Date: $(date)" >> report.md
          echo "" >> report.md
          echo "### Statistics" >> report.md
          echo "- Commits: $(git rev-list --count HEAD --since='1 week ago')" >> report.md
          echo "- Contributors: $(git shortlog -sn --since='1 week ago' | wc -l)" >> report.md
      
      - name: Create issue
        uses: peter-evans/create-issue-from-file@v4
        with:
          title: Weekly Report - ${{ github.run_number }}
          content-filepath: report.md
          labels: report

依赖更新检查 #

yaml
name: Dependency Check

on:
  schedule:
    - cron: '0 0 * * 1'  # 每周一
  workflow_dispatch:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Check for updates
        run: |
          npm outdated --json > outdated.json || true
      
      - name: Create issue if updates available
        if: hashFiles('outdated.json') != ''
        uses: peter-evans/create-issue-from-file@v4
        with:
          title: Dependency Updates Available
          content-filepath: outdated.json
          labels: dependencies

安全扫描 #

yaml
name: Security Scan

on:
  schedule:
    - cron: '0 0 * * *'  # 每天
  workflow_dispatch:

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          scan-ref: '.'
          severity: 'CRITICAL,HIGH'
          format: 'sarif'
          output: 'trivy-results.sarif'
      
      - name: Upload results
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: 'trivy-results.sarif'

注意事项 #

延迟执行 #

定时任务可能延迟执行:

  • GitHub在高负载时可能延迟
  • 最小间隔为5分钟
  • 延迟可能长达数小时

执行限制 #

yaml
# 添加超时限制
jobs:
  scheduled:
    runs-on: ubuntu-latest
    timeout-minutes: 60
    steps:
      - run: echo "Long running task"

避免重复执行 #

yaml
concurrency:
  group: ${{ github.workflow }}
  cancel-in-progress: false

检查是否由定时触发 #

yaml
jobs:
  scheduled:
    if: github.event_name == 'schedule'
    runs-on: ubuntu-latest
    steps:
      - run: echo "This is a scheduled run"

调试定时任务 #

手动触发测试 #

yaml
on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:  # 添加手动触发用于测试

查看下次运行时间 #

在仓库的Actions页面可以看到下次运行时间。

日志记录 #

yaml
steps:
  - name: Log execution
    run: |
      echo "Scheduled run at $(date)"
      echo "Event: ${{ github.event_name }}"
      echo "Run ID: ${{ github.run_id }}"

高级用法 #

条件执行 #

yaml
jobs:
  check:
    runs-on: ubuntu-latest
    outputs:
      should_run: ${{ steps.check.outputs.should_run }}
    steps:
      - id: check
        run: |
          if [ "$(date +%u)" -le 5 ]; then
            echo "should_run=true" >> $GITHUB_OUTPUT
          else
            echo "should_run=false" >> $GITHUB_OUTPUT
          fi

  run-if-needed:
    needs: check
    if: needs.check.outputs.should_run == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Running..."

使用矩阵 #

yaml
jobs:
  scheduled:
    strategy:
      matrix:
        task: [cleanup, report, scan]
    runs-on: ubuntu-latest
    steps:
      - name: Run ${{ matrix.task }}
        run: ./scripts/${{ matrix.task }}.sh

通知 #

yaml
jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Send notification
        if: failure()
        uses: slackapi/slack-github-action@v1
        with:
          channel-id: 'C0123456789'
          slack-message: 'Scheduled task failed: ${{ github.workflow }}'
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

最佳实践 #

1. 添加手动触发 #

yaml
on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

2. 设置超时 #

yaml
jobs:
  scheduled:
    timeout-minutes: 30

3. 添加并发控制 #

yaml
concurrency:
  group: ${{ github.workflow }}
  cancel-in-progress: false

4. 记录执行日志 #

yaml
steps:
  - name: Log execution
    run: |
      echo "## Execution Log" >> $GITHUB_STEP_SUMMARY
      echo "Time: $(date)" >> $GITHUB_STEP_SUMMARY

5. 处理失败情况 #

yaml
jobs:
  scheduled:
    runs-on: ubuntu-latest
    steps:
      - name: Main task
        id: main
        run: ./task.sh
        continue-on-error: true
      
      - name: Handle failure
        if: failure() || steps.main.outcome == 'failure'
        run: ./handle-failure.sh

下一步学习 #

小结 #

  • 使用schedule事件配置定时触发
  • Cron表达式定义执行时间
  • GitHub Actions使用UTC时间
  • 定时任务可能延迟执行
  • 添加手动触发便于测试
  • 设置超时和并发控制
  • 记录执行日志便于调试
最后更新:2026-03-28