Setting the file. One moment.
08 Reply And Resolve · Copilot PR Autopilot · github/awesome-copilot · Skills Docs
ContentsBack to the top of the page 94.10
10 Cleanup
(opens in a new tab)
scripts/ 08-reply-and-resolve.ps1
PowerShell · 97 lines · 3 KB
15
The GraphQL node ID of the review thread (e.g. PRRT_kw...).
16
17 . PARAMETER Body
18 The reply body. Markdown is supported.
19
20 . PARAMETER NoResolve
21 If set, posts the reply only and leaves the thread open. Useful when
22 you want to start a back-and-forth discussion rather than close out the
23 thread.
24
25 . EXAMPLE
26 pwsh 08-reply-and-resolve.ps1 -ThreadId PRRT_kw... -Body "Fixed in abc1234."
27
28 . EXAMPLE
29 # Decline with rationale, do not resolve yet
30 pwsh 08-reply-and-resolve.ps1 -ThreadId PRRT_kw... -NoResolve `
31 -Body "Declining: this would require cross-class plumbing for a hypothetical race."
32
33 . NOTES
34 Reply + resolve are TWO separate GraphQL mutations and the script
35 is NOT atomic: if the reply succeeds and the resolve then fails
36 (transient 5xx, rate limit, thread disappeared mid-call), the reply
37 is already posted. The script is also NOT idempotent on reply —
38 re-running it with the same -ThreadId and -Body will post a
39 duplicate reply because -Body is mandatory.
40
41 Recommended retry policy when a call fails:
42 - If "Replied to thread X" did NOT print, the reply step failed;
43 safe to re-run the whole command.
44 - If "Replied to thread X" DID print but "Resolved thread X" did
45 not, ONLY the resolve step failed. Do NOT re-run this script
46 (it would post a duplicate reply). Instead resolve directly:
47
48 gh api graphql `
49 -f query='mutation($t:ID!){resolveReviewThread(input:{threadId:$t}){thread{id}}}' `
50 -f t=$ThreadId
51
52 This raw call bypasses the Invoke-Gh helper but is safe here
53 because the mutation contains no embedded double-quote
54 characters, so the PowerShell-5.1 native-arg splitting bug
55 documented in references/api-quirks.md does not apply.
56 #>
57 [ CmdletBinding ()]
58 param (
59 [ Parameter ( Mandatory = $true )]
60 [ string ]$ThreadId ,
61
62 [ Parameter ( Mandatory = $true )]
63 [ string ]$Body ,
64
65 [ switch ]$NoResolve
66 )
67
68 $ErrorActionPreference = 'Stop'
69 . " $PSScriptRoot /_lib.ps1"
70
71 $replyMutation = @'
72 mutation($tid: ID!, $body: String!) {
73 addPullRequestReviewThreadReply(input: {
74 pullRequestReviewThreadId: $tid,
75 body: $body
76 }) {
77 comment { id }
78 }
79 }
80 '@
81
82 $replyArgs = @ ( '-f' , "query= $replyMutation " , '-f' , "tid= $ThreadId " , '-f' , "body= $Body " )
83 Invoke-GhGraphQL - GhArgs $replyArgs - Context "reply to thread $ThreadId " | Out-Null
84 Write-Output "Replied to thread $ThreadId "
85
86 if ( -not $NoResolve) {
87 $resolveMutation = @'
88 mutation($tid: ID!) {
89 resolveReviewThread(input: { threadId: $tid }) {
90 thread { isResolved }
91 }
92 }
93 '@
94 $resolveArgs = @ ( '-f' , "query= $resolveMutation " , '-f' , "tid= $ThreadId " )
95 Invoke-GhGraphQL - GhArgs $resolveArgs - Context "resolve thread $ThreadId " | Out-Null
96 Write-Output "Resolved thread $ThreadId "
97 }