如何通过GitHub Actions等工具定时重跑PR检查并保留PR上下文?
解决方案
问题根源是schedule触发的GitHub Action默认运行在仓库默认分支的上下文,不会自带任何PR相关的上下文数据,你需要主动在任务里拉取当前仓库所有处于打开状态的PR,再逐个执行你原本依赖PR上下文的逻辑。
具体实现步骤
- 第一步:调整工作流触发配置,保留你原有的两个触发器即可,不需要修改:
on: pull_request: schedule: - cron: '0 0 * * *'
- 第二步:添加步骤判断当前触发事件类型,如果是schedule触发,就调用GitHub API拉取所有打开的PR,可以直接使用官方的
actions/github-script来快速调用API,也可以用gh命令行工具。 - 第三步:对每个拉取到的PR,检出对应PR的代码,同时把PR的编号、标题、源分支、目标分支等你需要的上下文数据存入环境变量或者输出参数,供给后续步骤使用。
完整示例配置
on: pull_request: schedule: - cron: '0 0 * * *' jobs: nightly-pr-check: runs-on: ubuntu-latest steps: - name: 处理触发事件,获取PR列表 id: get-prs uses: actions/github-script@v7 with: script: | let prList = [] // 判断当前触发事件类型 if (context.eventName === 'pull_request') { // PR触发时直接取当前PR信息 prList = [{ number: context.payload.pull_request.number, head_sha: context.payload.pull_request.head.sha, head_ref: context.payload.pull_request.head.ref, base_ref: context.payload.pull_request.base.ref }] } else if (context.eventName === 'schedule') { // 定时触发时拉取所有打开的PR const { data: prs } = await github.rest.pulls.list({ owner: context.repo.owner, repo: context.repo.repo, state: 'open' }) prList = prs.map(pr => ({ number: pr.number, head_sha: pr.head.sha, head_ref: pr.head.ref, base_ref: pr.base.ref })) } // 输出PR列表给后续步骤使用 core.setOutput('pr_list', prList) - name: 遍历处理每个PR uses: actions/github-script@v7 with: script: | const prList = ${{ steps.get-prs.outputs.pr_list }} const { exec } = require('child_process') for (const pr of prList) { console.log(`处理PR #${pr.number},源分支:${pr.head_ref},目标分支:${pr.base_ref}`) // 这里写入你原本需要执行的逻辑,需要PR上下文的地方直接用pr对象里的属性即可 // 如果你需要单独为每个PR执行多步操作,也可以改用matrix矩阵来并行处理所有PR }
可选优化:用矩阵并行处理多个PR
如果你的仓库打开的PR比较多,可以把PR列表设置为job的矩阵输入,这样多个PR的任务可以并行运行,节省时间:
jobs: get-pr-list: runs-on: ubuntu-latest outputs: pr_matrix: ${{ steps.get-prs.outputs.pr_matrix }} steps: - id: get-prs uses: actions/github-script@v7 with: script: | let prList = [] if (context.eventName === 'pull_request') { prList = [{ number: context.payload.pull_request.number, head_sha: context.payload.pull_request.head.sha }] } else if (context.eventName === 'schedule') { const { data: prs } = await github.rest.pulls.list({ owner: context.repo.owner, repo: context.repo.repo, state: 'open' }) prList = prs.map(pr => ({ number: pr.number, head_sha: pr.head.sha })) } core.setOutput('pr_matrix', JSON.stringify({ include: prList })) process-pr: needs: get-pr-list runs-on: ubuntu-latest strategy: matrix: ${{ fromJson(needs.get-pr-list.outputs.pr_matrix) }} steps: - name: 检出PR代码 uses: actions/checkout@v4 with: ref: ${{ matrix.head_sha }} # 这里直接写你原本依赖PR上下文的步骤,PR编号可以通过 ${{ matrix.number }} 获取 - name: 运行测试 run: echo "运行PR #${{ matrix.number }} 的测试逻辑"
内容的提问来源于stack exchange,提问作者swaggieX
相关产品推荐
相关产品推荐

