Fix PR-triage eval trigger: dispatch evaluation.yml instead of bot-applied label#746
Conversation
The triage worker added the 'evaluate-now' label via GITHUB_TOKEN, but label events emitted by GITHUB_TOKEN do not start workflows (GitHub's recursion guard), so evaluation.yml's pull_request_target:[labeled] entry point never fired for the bot (repro: PR dotnet#745). workflow_dispatch and repository_dispatch are the only token-initiated events exempt from that guard. The worker now dispatches evaluation.yml directly via 'gh workflow run' with a pr_number input, routed through the existing gate job so the path is identical to /evaluate. A dispatched run's head_sha is the default branch (not the PR head), so idempotency now matches the deterministic run name 'Evaluate PR #<n> @ <sha7>'. The 'evaluate-now' label remains a valid human entry point. Worker granted actions:write for 'gh workflow run'.
|
Note This PR is from a fork and modifies infrastructure files ( Changes to infrastructure typically need to be submitted from a branch in Please consider recreating this PR from an upstream branch. If you don't have push access to |
There was a problem hiding this comment.
Pull request overview
Updates the PR-triage automation so that when a PR is deemed ready-for-eval, the worker triggers evaluation.yml via workflow_dispatch (instead of relying on a bot-applied label that can’t emit workflow-triggering events under GitHub’s recursion guard).
Changes:
- Add
workflow_dispatchinputs toevaluation.ymland routepr_numberdispatches through the existinggatePR pipeline/concurrency group. - Update the triage worker script to dispatch
evaluation.ymlviagh workflow runand enhance idempotency detection for dispatch-triggered runs. - Grant the triage worker
actions: writeso it can dispatchevaluation.yml, and update design docs to reflect the new trigger path.
Show a summary per file
| File | Description |
|---|---|
docs/design/pr-triage-workflows.md |
Updates architecture + evaluation entry-point documentation to reflect dispatch-based triggering. |
.github/workflows/pr-triage.yml |
Expands permissions to allow dispatching evaluation.yml from the worker. |
.github/workflows/evaluation.yml |
Adds dispatch inputs and updates gate/concurrency logic to support triage dispatch entry point. |
.github/scripts/pr-triage-act.sh |
Switches eval triggering from label application to workflow dispatch; adds dispatch-run idempotency lookup. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 1
|
👋 @JanKrivanek — this PR has 1 unresolved review thread(s). When you're ready, please address the feedback and push an update; the triage bot will pick up the next state automatically. (Add the |
|
/evaluate |
Skill Validation Results
[1] (Isolated) Quality unchanged but weighted score is -0.8% due to: efficiency metrics Model: claude-opus-4.6 | Judge: claude-opus-4.6 🔍 Full Results - additional metrics and failure investigation steps
▶ Sessions Visualisation -- interactive replay of all evaluation sessions |
Problem
When the PR-triage worker decides a PR is
ready-for-eval, it added theevaluate-nowlabel and relied onevaluation.yml'spull_request_target: [labeled]trigger to start evaluation. That trigger neverfires for the bot.
GitHub's recursion guard: events emitted by the default
GITHUB_TOKENdo notstart new workflow runs — and
labeledis one of them. The worker applies thelabel as
github-actions[bot](itsGITHUB_TOKEN), so thelabeledwebhook issuppressed and no evaluation runs.
Live repro — PR #745
github-actions[bot]evaluate-now/evaluateThe same worker run (
workflow_dispatch, dispatched by the batch viaGITHUB_TOKEN) is itself an A/B proof of the guard:workflow_dispatch→ fired (the worker executed)labeled(the label it added) → did not fireworkflow_dispatchandrepository_dispatchare the only token-initiated eventsexempt from the recursion guard.
Fix
The worker now dispatches
evaluation.ymldirectly viagh workflow run(workflow_dispatch) with a
pr_numberinput, instead of adding a label thatcan't fire. The dispatch is routed through the existing
gatejob, so the pathis identical to
/evaluate(same permission checks, PR fetch, fork handling,concurrency group, commit status, and result comment).
evaluation.yml: newworkflow_dispatchinputspr_number+head_sha;gate.ifand the concurrency group gain a third entry point;gatereads andnumerically validates
pr_number(via env, no interpolation);discoveronlyruns a full/plugin eval for a no-pr_number dispatch.
pr-triage-act.sh:do_eval_triggerdispatchesevaluation.ymlratherthan labeling. Idempotency (
eval_run_exists_for_head) gains a second path:a dispatched run's
head_shais the default branch (not the PR head), so it ismatched by the deterministic run name
Evaluate PR #<n> @ <sha7>.pr-triage.yml: worker grantedactions: write(required forgh workflow run).evaluate-nowlabel remains a valid human entry point (a humanadding the label is not subject to the recursion guard).
Verification
(see the A/B table above) —
workflow_dispatchviaGITHUB_TOKENalreadydrives the batch → worker chain.
evaluation.yml+pr-triage.ymlparse cleanly;pr-triage-act.shpassesbash -n.Docs
Updated pr-triage-workflows.md (architecture
diagram + the three
evaluation.ymlentry points).