Setting the file. One moment.
09 Review Round · 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/ 09-review-round.ps1
PowerShell · 138 lines · 5 KB
15 original failure mode this skill was built to survive — an agent
16 losing track of the count across a long run, drifting for 156 rounds —
17 cannot happen when the count is derived, not remembered.
18
19 This script does NOT decide anything. It does not stop the loop, does
20 not enforce a cap, and does not pick a verdict. It reports two facts;
21 the parent agent still owns the recap reasoning and the
22 CONTINUE / REVERT-AND-SHIP / HAND-OFF verdict (see
23 ../references/09-convergence.md). "No script decides the cap" stays
24 true — this script only makes the *trigger* (Nth round) deterministic
25 instead of a fallible mental tally.
26
27 Output JSON fields:
28 - PrNumber, Owner, Repo
29 - Round : count of Copilot Code Review submissions on the PR.
30 Full pagination — every Copilot submission, NOT the
31 most-recent-100 window 02-check-review-status.ps1
32 uses to find the latest review. The count must stay
33 correct on exactly the long loops the gate exists
34 to catch (a 100-review window would silently
35 undercount past round 100).
36 - RecapInterval : the recap cadence (default 10; override with
37 -RecapInterval).
38 - RecapDue : true iff Round > 0 AND Round % RecapInterval == 0 —
39 i.e. this is a 10th / 20th / 30th ... round and the
40 parent should RUN THE RECAP GATE before looping back
41 to step 1.
42
43 Parsing the JSON (any PowerShell version, 5.1 + 7.x):
44
45 $snap = pwsh -NoProfile -File 09-review-round.ps1 -PrNumber <n>
46 $round = if ($snap -match '"Round":(\d+)') { [int]$Matches[1] } else { 0 }
47 $recapDue = ($snap -match '"RecapDue":true')
48
49 . PARAMETER PrNumber
50 The pull request number. The only required parameter.
51
52 . PARAMETER Owner
53 Repository owner. OPTIONAL — auto-resolved from `gh repo view`.
54
55 . PARAMETER Repo
56 Repository name. OPTIONAL — auto-resolved from `gh repo view`.
57
58 . PARAMETER RecapInterval
59 Recap cadence in rounds. Default 10 (stop at 10, 20, 30, ...). Must be
60 a positive integer. Exposed as a single named knob so the cadence
61 isn't a magic number duplicated in prose, and so the gate boundary is
62 testable on a real PR without fabricating review history.
63
64 . EXAMPLE
65 pwsh ./scripts/09-review-round.ps1 -PrNumber 1944
66
67 # {"PrNumber":1944,"Owner":"github","Repo":"awesome-copilot","Round":154,"RecapInterval":10,"RecapDue":false}
68
69 . EXAMPLE
70 pwsh ./scripts/09-review-round.ps1 -PrNumber 1944 -RecapInterval 7
71
72 # 154 % 7 == 0 -> {"...","Round":154,"RecapInterval":7,"RecapDue":true}
73 #>
74 [ CmdletBinding ()]
75 param (
76 [ Parameter ( Mandatory = $true )]
77 [ int ]$PrNumber ,
78
79 [ string ]$Owner ,
80 [ string ]$Repo ,
81
82 [ ValidateRange ( 1 , [ int ]::MaxValue)]
83 [ int ]$RecapInterval = 10
84 )
85
86 $ErrorActionPreference = 'Stop'
87 . " $PSScriptRoot /_lib.ps1"
88
89 $coords = Resolve-RepoCoords - Owner $Owner - Repo $Repo
90 $Owner = $coords.Owner
91 $Repo = $coords.Repo
92
93 # Walk ALL reviews (full pagination). 02-check-review-status.ps1 only needs
94 # the most-recent-100 window to find the LATEST Copilot review; the round
95 # COUNT must include EVERY Copilot submission, because the gate exists
96 # precisely for long loops where the count can exceed 100. Counting is
97 # order-independent, so forward pagination is sufficient.
98 $qReviews = @'
99 query($o:String!,$r:String!,$n:Int!,$after:String){
100 repository(owner:$o,name:$r){
101 pullRequest(number:$n){
102 reviews(first:100, after:$after){
103 pageInfo{endCursor hasNextPage}
104 nodes{author{login}}
105 }
106 }
107 }
108 }
109 '@
110
111 $after = $null
112 $round = 0
113 do {
114 $ghArgs = @ ( '-f' , "query= $qReviews " , '-f' , "o= $Owner " , '-f' , "r= $Repo " , '-F' , "n= $PrNumber " )
115 if ($after) { $ghArgs = $ghArgs + @ ( '-f' , "after= $after " ) }
116 $resp = Invoke-GhGraphQL - GhArgs $ghArgs - Context "reviews count for $Owner / $Repo PR # $PrNumber "
117 $pagePr = $resp.data.repository.pullRequest
118 if ( -not $pagePr) { throw "PR # $PrNumber not found in $Owner / $Repo (reviews page)." }
119 $round += @ ($pagePr.reviews.nodes | Where-Object {
120 $_ .author -and $_ .author.login -and $_ .author.login -match $CopilotReviewerLoginRegex
121 }).Count
122 $after = $pagePr.reviews.pageInfo.endCursor
123 } while ($pagePr.reviews.pageInfo.hasNextPage)
124
125 # Gate TRIGGER only — not the verdict. RecapDue says "this is an Nth round,
126 # run the recap"; the parent agent reads the recap and picks
127 # CONTINUE / REVERT-AND-SHIP / HAND-OFF (09-convergence.md).
128 $recapDue = ($round -gt 0 ) -and (($round % $RecapInterval) -eq 0 )
129
130 $result = [ ordered ] @ {
131 PrNumber = $PrNumber
132 Owner = $Owner
133 Repo = $Repo
134 Round = $round
135 RecapInterval = $RecapInterval
136 RecapDue = $recapDue
137 }
138 $result | ConvertTo-Json - Depth 3 - Compress