Always minimize /review, /review rerun, and /review tests command comments once authorized - #36021
Conversation
…s:write The copilot-review-tests pre-activation job minimizes the triggering `/review tests` comment via GraphQL minimizeComment(classifier: RESOLVED), but its token only had issues:write. Because the comment lives on a pull request, that call requires pull-requests:write and otherwise fails with "Resource not accessible by integration" (observed on PR #30311, run 27824496263). The sibling /review and /review rerun jobs in review-trigger.yml already have pull-requests:write and minimize correctly. Add pull-requests:write to the pre-activation job (on.permissions) and recompile the lock file. The agent job stays read-only; body_hash is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously the /review comment was only minimized when the AzDO pipeline trigger succeeded, and /review rerun only when the rerun was eligible, so lock-skipped / failed / ineligible commands lingered in the conversation. Hide the command comment whenever the actor is authorized and the command was recognized, regardless of the downstream outcome. Gate on a new `id: auth` step outcome plus !cancelled() so the hide still runs after an upstream step fails, while unauthorized commenters' comments stay visible. Minimizing remains transparent to the rerun scanner, which keys on comment id/body/created_at and never on isMinimized. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36021Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36021" |
Document recent workflow improvements: - Command comments are now minimized (collapsed as Resolved) after authorization (dotnet#35895, dotnet#36021) - /review rerun eligibility now requires PR author activity only (dotnet#35874) - Automated hourly rerun scanner processes queued reruns (dotnet#35685) - Add troubleshooting entries for rerun eligibility and command visibility Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PureWeen
left a comment
There was a problem hiding this comment.
Adversarial multi-model review — ✅ no blocking issues
Reviewed by 3 independent reviewers with adversarial consensus. All three converged on clean — no must-fix or should-fix findings. No prior reviews existed.
What was verified (consensus in parentheses):
- Authorization is preserved. An unauthorized commenter can never hide their own comment: the new gate requires
steps.auth.outcome == 'success', and the permission stepexit 1s for unauthorized actors (outcome == 'failure') — and is'skipped'onworkflow_dispatch, where the hide step'sgithub.event_name == 'issue_comment'clause also blocks it. (3/3) !cancelled()is the right broadening. It lets the hide run after an upstream failure (ineligible rerun, lock-skip, failed AzDO trigger) while still skipping on real cancellation — matching the stated intent of "collapse once authorized, regardless of result." Usingoutcome(notconclusion) is correct here. (3/3)pull-requests: writeis minimal and corroborated.minimizeCommenton a PR conversation comment needspull-requests: write—issues: writealone yields "Resource not accessible by integration." This is corroborated in-repo: bothreview-trigger.ymljobs already declare both scopes for the identical mutation. The grant is scoped to the pre-activation job; the AI agent job stays read-only. (3/3)- Transparent to the rerun scanner.
Resolve-RerunEligibility.ps1/Query-RerunReadyPRs.ps1key purely on commentid/body/created_atand never onisMinimized; the REST list endpoint still returns minimized comments. Independently grep-confirmed — zeroisMinimizedreferences in the scanner path. (verified) .lock.ymlis a faithful recompile.body_hashis unchanged (44becb59…); onlyfrontmatter_hashand the new pre-activation permission changed (gh-awv0.79.8). No hand-edit tampering. (3/3)- No regression. The new gate is strictly broader than the old ones for authorized users, so nothing that was previously hidden is now left visible; the only behavioral change is the intended one (ineligible reruns / lock-skips / failed triggers now also collapse).
Non-blocking observations (💡, no change requested):
issues: writemay now be redundant alongsidepull-requests: writefor the minimize-only scope — worth a future audit, but keeping both mirrors existing precedent and is safer to leave as-is.- With
cancel-in-progress: false, two near-simultaneous identical commands could both try to minimize the samenode_id;minimizeCommentis idempotent and a failed hide only emits::warning::, so this is harmless.
Test coverage: Workflow-YAML/permission changes with no unit-test surface; validated by gh aw compile (0 errors / 0 warnings, no stray diff), YAML parse, and the cited failing-run evidence (27824496263) for the permission root cause. Reasonable for this change class.
Methodology: 3 independent reviewers, different models, with adversarial cross-validation of disputed findings. Review-only — not an approval.
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Summary
Follow-up to #35895, which switched the
/review,/review rerun, and/review testscommand-comment cleanup from delete to GraphQLminimizeComment(classifier: RESOLVED). In practice the command comments were still left visible in several cases. This PR makes all three reliably collapse once the command is recognized and the commenter is authorized — regardless of the command's result.Root causes (observed on #30311)
/review tests— permission bug. The gh-awcopilot-review-testspre-activation job that minimizes the comment only hadissues: write. The comment lives on a pull request, sominimizeCommentneedspull-requests: write; with onlyissues: writeit failed withResource not accessible by integration(run27824496263) and the comment stayed visible. Hide/review,/review rerun, and/review testscommand comments as resolved #35895's assumption that "minimizing requires the sameissues:writescope that deletion did" is incorrect for PR conversation comments./review rerun— eligibility gate. Themark-rerun-readyhide step was gated oneligible == 'true', so an ineligible rerun (e.g.no-new-comments-or-commits) left the comment fully visible./review— trigger-outcome gate. Thetrigger-reviewhide step was gated ontrigger_azdo.outcome == 'success', so a lock-skip or a failed AzDO trigger left the comment visible.Changes
copilot-review-tests.md(gh-aw)pull-requests: writeto the pre-activation job (on.permissions) so it can minimize a PR comment. The AI agent job stays read-only.copilot-review-tests.lock.ymlwith gh-awv0.79.8; onlyfrontmatter_hashand the pre-activation permission change —body_hashis unchanged.review-trigger.yml/review rerunand/reviewnow minimize the command comment whenever the actor is authorized and the command was recognized, no matter the downstream outcome.id: auth; the hide step is gated on!cancelled() && github.event_name == 'issue_comment' && steps.auth.outcome == 'success'.!cancelled()lets the hide run even after an upstream step failed (failed trigger / ineligible rerun / errored eligibility), while thesteps.authgate keeps unauthorized commenters' comments fully visible.Safety / scope
steps.auth.outcome == 'success'gate, and the internal collaborator check in the/review testsscript).Resolve-RerunEligibility.ps1/Query-RerunReadyPRs.ps1/Get-LatestRerunCommentBeforekey on commentid, body andcreated_at— never onisMinimized— and minimized comments are still returned by the REST list endpoint. Verified there are noisMinimizedreferences in those scripts.::warning::and never fails the review/rerun/tests trigger.!cancelled()skips on interruption); every completed outcome is covered.Validation
gh aw compile→ 0 errors / 0 warnings; recompiling produced no stray diff.review-trigger.ymlparses as valid YAML.