Unverified 提交 0e6404c9 authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Use workflow_dispatch to re-trigger CI instead of closing/reopening PR (#2382)

## Summary Replace the PR close/reopen mechanism for CI re-triggering with GitHub's `workflow_dispatch` event, which is more reliable and avoids potential issues with PR state management. ## Key Changes - **ci.yml**: Added `workflow_dispatch` trigger with optional `pr_number` input parameter to allow manual CI runs - **ci.yml**: Updated test check logic to always run tests when triggered via `workflow_dispatch` - **ci.yml**: Pass `PR_NUMBER` environment variable to Playwright summary script for workflow_dispatch triggers - **pr-review-responder.yml**: Replaced PR close/reopen logic with `gh workflow run` command to trigger CI via `workflow_dispatch` ## Implementation Details - The `workflow_dispatch` trigger accepts an optional `pr_number` input that can be passed by the pr-review-responder workflow - When CI is triggered via `workflow_dispatch`, tests always run (skipping the file change check) - The new approach is more reliable because: - Avoids the risk of leaving a PR in a closed state if operations fail - Works with `GITHUB_TOKEN` without infinite loop concerns - Provides explicit control over when CI re-runs - Eliminates retry logic and recovery mechanisms needed with close/reopen approach https://claude.ai/code/session_014TKdhebC3RqZ7yusKuRSJD <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2382"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes GitHub Actions triggering, concurrency grouping, and checkout behavior (including fork PR handling) for CI and AI review bots; misconfiguration could lead to running workflows on the wrong ref or not running at all. > > **Overview** > Switches CI and AI-bot workflows to support manual `workflow_dispatch` runs via a required `pr_number`, enabling reliable re-triggers without PR close/reopen. > > `ci.yml` now derives checkout `repository`/`ref` from the PR head (fetched via `gh pr view` for dispatch), updates concurrency grouping to key by PR number, always runs tests for dispatch runs, and passes `PR_NUMBER` to the Playwright summary script so comments still attach to the correct PR. > > `pr-review-responder.yml` replaces the close/reopen hack with `gh workflow run` calls to dispatch `ci.yml`, `bugbot-trigger.yml`, and `claude-pr-review.yml` when Claude pushes commits. `bugbot-trigger.yml` and `claude-pr-review.yml` add dispatch support and PR-number fallbacks; BugBot additionally validates `pr_number` and re-checks skip tags before commenting. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 357dddba6b3c3c9144b21f6f400fc0b49e55e244. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Switch re-triggers to workflow_dispatch for CI, BugBot, and Claude PR Review. This replaces the close/reopen hack, works with GITHUB_TOKEN, and ensures tests and reviews run after automated commits. - **Refactors** - Added workflow_dispatch with pr_number input to ci.yml, bugbot-trigger.yml, and claude-pr-review.yml. - pr-review-responder now calls gh workflow run for all three when it pushes commits. - CI always runs tests on workflow_dispatch, checks out the PR head (supports forks), passes PR_NUMBER to the Playwright summary, and uses pr_number in concurrency. - Claude PR Review fetches PR head info on dispatch; concurrency keys use pr_number when provided. - BugBot dispatch uses inputs.pr_number, re-checks skip tags, and bypasses author gating for dispatch. <sup>Written for commit 357dddba6b3c3c9144b21f6f400fc0b49e55e244. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: 's avatarClaude <noreply@anthropic.com>
上级 8a53b927
......@@ -3,25 +3,59 @@ name: BugBot Trigger
on:
pull_request_target:
types: [opened, synchronize, ready_for_review, reopened]
workflow_dispatch:
inputs:
pr_number:
description: "PR number to trigger BugBot on (used by pr-review-responder)"
required: true
type: string
jobs:
trigger-bugbot:
environment: ai-bots
# Only review code from regular contributors since bug bot has a capped # of PR reviews.
# For workflow_dispatch, we check skip tags below since the caller may not have validated them.
if: |
(github.event.pull_request.user.login == 'wwwillchen' ||
github.event_name == 'workflow_dispatch' ||
((github.event.pull_request.user.login == 'wwwillchen' ||
github.event.pull_request.user.login == 'azizmejri1' ||
github.event.pull_request.user.login == 'princeaden1') &&
!contains(github.event.pull_request.body, '#skip-bugbot') &&
!contains(github.event.pull_request.body, '#skip-bb')
!contains(github.event.pull_request.body, '#skip-bb'))
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Validate pr_number format
if: github.event_name == 'workflow_dispatch'
run: |
if ! [[ "${{ inputs.pr_number }}" =~ ^[0-9]+$ ]]; then
echo "::error::pr_number must be a numeric value"
exit 1
fi
- name: Check skip tags for workflow_dispatch
if: github.event_name == 'workflow_dispatch'
id: check-skip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_BODY=$(gh pr view "${{ inputs.pr_number }}" --repo "${{ github.repository }}" --json body --jq '.body') || {
echo "::error::Failed to fetch PR body for skip tag check"
exit 1
}
if echo "$PR_BODY" | grep -qE '#skip-bugbot|#skip-bb'; then
echo "skip=true" >> $GITHUB_OUTPUT
echo "Skipping BugBot: PR contains skip tag"
else
echo "skip=false" >> $GITHUB_OUTPUT
fi
- name: Comment @BugBot run
if: steps.check-skip.outputs.skip != 'true'
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5
with:
# Use a PAT from wwwillchen to post on their behalf
token: ${{ secrets.WWWILLCHEN_PR_RW_PAT }}
issue-number: ${{ github.event.pull_request.number }}
issue-number: ${{ github.event.pull_request.number || inputs.pr_number }}
body: "@BugBot run"
......@@ -6,10 +6,17 @@ on:
- main
pull_request:
types: [opened, synchronize, reopened, closed]
workflow_dispatch:
inputs:
pr_number:
description: "PR number for CI re-run (used by pr-review-responder)"
required: true
type: string
concurrency:
# Use PR number for pull_request events to enable cancellation when PR is merged
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
# Use PR number for pull_request/workflow_dispatch events to enable proper per-PR cancellation
# For workflow_dispatch, inputs.pr_number ensures different PRs don't cancel each other
group: ${{ github.workflow }}-${{ github.event.pull_request.number || inputs.pr_number || github.ref }}
cancel-in-progress: true
defaults:
......@@ -23,14 +30,38 @@ jobs:
runs-on: ubuntu-latest
outputs:
should_run_tests: ${{ steps.check.outputs.should_run_tests }}
pr_head_ref: ${{ steps.pr-info.outputs.head_ref }}
pr_head_repo: ${{ steps.pr-info.outputs.head_repo }}
steps:
- name: Get PR info for workflow_dispatch
if: github.event_name == 'workflow_dispatch' && inputs.pr_number != ''
id: pr-info
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_DATA=$(gh pr view "${{ inputs.pr_number }}" --repo "${{ github.repository }}" --json headRefName,headRepository,headRepositoryOwner) || {
echo "::error::Failed to fetch PR info for PR #${{ inputs.pr_number }}"
exit 1
}
echo "head_ref=$(echo "$PR_DATA" | jq -r '.headRefName')" >> $GITHUB_OUTPUT
echo "head_repo=$(echo "$PR_DATA" | jq -r '.headRepositoryOwner.login + "/" + .headRepository.name')" >> $GITHUB_OUTPUT
- name: Checkout code
uses: actions/checkout@v4
with:
repository: ${{ steps.pr-info.outputs.head_repo || github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ steps.pr-info.outputs.head_ref || github.event.pull_request.head.ref || '' }}
fetch-depth: 0
- name: Check if only .claude files changed
id: check
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
# Always run tests for manual workflow dispatch (e.g., from pr-review-responder)
echo "should_run_tests=true" >> $GITHUB_OUTPUT
echo "Running tests: manual workflow dispatch"
exit 0
fi
if [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then
# Always run tests on pushes to main
echo "should_run_tests=true" >> $GITHUB_OUTPUT
......@@ -95,6 +126,9 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
repository: ${{ needs.check-changes.outputs.pr_head_repo || github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ needs.check-changes.outputs.pr_head_ref || github.event.pull_request.head.ref || '' }}
- name: Initialize environment
uses: actions/setup-node@v4
with:
......@@ -178,6 +212,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
repository: ${{ needs.check-changes.outputs.pr_head_repo || github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ needs.check-changes.outputs.pr_head_ref || github.event.pull_request.head.ref || '' }}
- uses: actions/setup-node@v4
with:
node-version: lts/*
......@@ -222,6 +259,8 @@ jobs:
uses: actions/github-script@v7
env:
PLAYWRIGHT_RUN_ID: ${{ github.run_id }}
# Pass PR number for workflow_dispatch triggers (from pr-review-responder)
PR_NUMBER: ${{ inputs.pr_number }}
with:
script: |
const { run } = require('./scripts/generate-playwright-summary.js');
......
......@@ -5,9 +5,15 @@ name: Claude PR Review
on:
pull_request_target:
types: [opened, synchronize, ready_for_review, reopened]
workflow_dispatch:
inputs:
pr_number:
description: "PR number to review (used by pr-review-responder)"
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
group: ${{ github.workflow }}-${{ github.event.pull_request.number || inputs.pr_number }}
cancel-in-progress: true
jobs:
......@@ -17,8 +23,10 @@ jobs:
# Only review code from regular contributors since claude code has non-trivial costs.
# It's also a safe-guard for preventing malicious PRs from doing bad things although we restrict
# the permissions and tools allowed in this job.
# For workflow_dispatch, we trust the caller (pr-review-responder) has already validated.
# https://github.com/anthropics/claude-code-action/blob/main/examples/pr-review-filtered-authors.yml
if: |
github.event_name == 'workflow_dispatch' ||
github.event.pull_request.user.login == 'wwwillchen' ||
github.event.pull_request.user.login == 'azizmejri1' ||
github.event.pull_request.user.login == 'princeaden1'
......@@ -27,11 +35,24 @@ jobs:
contents: read
pull-requests: write
steps:
- name: Get PR info for workflow_dispatch
if: github.event_name == 'workflow_dispatch'
id: pr-info
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_DATA=$(gh pr view "${{ inputs.pr_number }}" --repo "${{ github.repository }}" --json headRefName,headRepository,headRepositoryOwner) || {
echo "::error::Failed to fetch PR info for PR #${{ inputs.pr_number }}"
exit 1
}
echo "head_ref=$(echo "$PR_DATA" | jq -r '.headRefName')" >> $GITHUB_OUTPUT
echo "head_repo=$(echo "$PR_DATA" | jq -r '.headRepositoryOwner.login + "/" + .headRepository.name')" >> $GITHUB_OUTPUT
- name: Checkout repository
uses: actions/checkout@v5
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name || steps.pr-info.outputs.head_repo }}
ref: ${{ github.event.pull_request.head.ref || steps.pr-info.outputs.head_ref }}
fetch-depth: 1
- name: PR Review
......@@ -52,7 +73,7 @@ jobs:
track_progress: false
prompt: |
/dyad:multi-pr-review ${{ github.event.pull_request.number }}
/dyad:multi-pr-review ${{ github.event.pull_request.number || inputs.pr_number }}
# Uses .claude/settings.json for permissions; only add MCP tool not in settings
claude_args: |
......
......@@ -118,7 +118,7 @@ jobs:
prompt: |
/dyad:pr-fix ${{ steps.pr-info.outputs.pr_number }}
- name: Re-trigger CI if commits were pushed
- name: Re-trigger workflows if commits were pushed
# Use always() to ensure commits get tested even if Claude Code fails partway through
if: steps.pr-info.outputs.should_continue == 'true' && always()
env:
......@@ -135,19 +135,33 @@ jobs:
if [ "${{ steps.before-claude.outputs.sha }}" != "$PR_HEAD_SHA" ]; then
echo "Claude pushed new commits (before: ${{ steps.before-claude.outputs.sha }}, after: $PR_HEAD_SHA)"
echo "Re-triggering CI by closing and reopening PR"
if gh pr close ${{ steps.pr-info.outputs.pr_number }} --repo ${{ github.repository }}; then
if ! gh pr reopen ${{ steps.pr-info.outputs.pr_number }} --repo ${{ github.repository }}; then
echo "::warning::Failed to reopen PR after close. Attempting recovery..."
# Retry reopen once after a short delay
sleep 2
gh pr reopen ${{ steps.pr-info.outputs.pr_number }} --repo ${{ github.repository }} || echo "::error::PR may be left closed. Manual intervention required."
fi
else
echo "::warning::Failed to close PR, skipping re-trigger"
fi
echo "Re-triggering workflows via workflow_dispatch"
# Use workflow_dispatch to trigger workflows - this works with GITHUB_TOKEN unlike PR events
# which are blocked to prevent infinite loops
#
# Note: We use the default branch (no --ref) instead of head_branch because for fork PRs,
# head_branch only exists in the fork repo, not the main repo. The workflows will checkout
# the correct PR code using the pr_number input.
# Trigger CI
gh workflow run ci.yml \
--repo ${{ github.repository }} \
-f pr_number=${{ steps.pr-info.outputs.pr_number }} \
|| echo "::warning::Failed to trigger CI workflow"
# Trigger BugBot
gh workflow run bugbot-trigger.yml \
--repo ${{ github.repository }} \
-f pr_number=${{ steps.pr-info.outputs.pr_number }} \
|| echo "::warning::Failed to trigger BugBot workflow"
# Trigger Claude PR Review
gh workflow run claude-pr-review.yml \
--repo ${{ github.repository }} \
-f pr_number=${{ steps.pr-info.outputs.pr_number }} \
|| echo "::warning::Failed to trigger Claude PR Review workflow"
else
echo "No new commits pushed, skipping CI re-trigger"
echo "No new commits pushed, skipping workflow re-triggers"
fi
- name: Update labels to done
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论