77 "sort"
88 "strings"
99 "time"
10+
11+ "github.com/codeGROOVE-dev/prx/pkg/prx/github"
1012)
1113
1214// pullRequestViaGraphQL fetches pull request data using GraphQL with minimal REST fallbacks.
@@ -79,31 +81,31 @@ func (c *Client) pullRequestViaGraphQL(ctx context.Context, owner, repo string,
7981
8082// fetchRulesetsREST fetches repository rulesets via REST API (not available in GraphQL).
8183func (c * Client ) fetchRulesetsREST (ctx context.Context , owner , repo string ) ([]string , error ) {
82- rulesetPath := fmt .Sprintf ("/repos/%s/%s/rulesets" , owner , repo )
83- var rulesets []githubRuleset
84+ path := fmt .Sprintf ("/repos/%s/%s/rulesets" , owner , repo )
85+ var rulesets []github. Ruleset
8486
85- _ , err := c .github .get (ctx , rulesetPath , & rulesets )
86- if err != nil {
87+ if _ , err := c .github .Get (ctx , path , & rulesets ); err != nil {
8788 return nil , err
8889 }
8990
90- var requiredChecks []string
91- for _ , ruleset := range rulesets {
92- if ruleset .Target == "branch" {
93- for _ , rule := range ruleset .Rules {
94- if rule .Type == "required_status_checks" && rule .Parameters .RequiredStatusChecks != nil {
95- for _ , check := range rule .Parameters .RequiredStatusChecks {
96- requiredChecks = append (requiredChecks , check .Context )
97- }
91+ var required []string
92+ for _ , rs := range rulesets {
93+ if rs .Target != "branch" {
94+ continue
95+ }
96+ for _ , rule := range rs .Rules {
97+ if rule .Type == "required_status_checks" && rule .Parameters .RequiredStatusChecks != nil {
98+ for _ , chk := range rule .Parameters .RequiredStatusChecks {
99+ required = append (required , chk .Context )
98100 }
99101 }
100102 }
101103 }
102104
103105 c .logger .InfoContext (ctx , "fetched required checks from rulesets" ,
104- "count" , len (requiredChecks ), "checks" , requiredChecks )
106+ "count" , len (required ), "checks" , required )
105107
106- return requiredChecks , nil
108+ return required , nil
107109}
108110
109111// fetchCheckRunsREST fetches check runs via REST API for a specific commit.
@@ -113,8 +115,8 @@ func (c *Client) fetchCheckRunsREST(ctx context.Context, owner, repo, sha string
113115 }
114116
115117 path := fmt .Sprintf ("/repos/%s/%s/commits/%s/check-runs?per_page=100" , owner , repo , sha )
116- var checkRuns githubCheckRuns
117- if _ , err := c .github .get (ctx , path , & checkRuns ); err != nil {
118+ var checkRuns github. CheckRuns
119+ if _ , err := c .github .Get (ctx , path , & checkRuns ); err != nil {
118120 return nil , fmt .Errorf ("fetching check runs: %w" , err )
119121 }
120122
@@ -172,33 +174,26 @@ func (c *Client) fetchCheckRunsREST(ctx context.Context, owner, repo, sha string
172174// Errors fetching individual commits are logged but don't stop the overall process.
173175func (c * Client ) fetchAllCheckRunsREST (ctx context.Context , owner , repo string , prData * PullRequestData ) []Event {
174176 // Collect all unique commit SHAs from the PR
175- commitSHAs := make ([] string , 0 )
177+ shas := make (map [ string ] bool )
176178
177179 // Add HEAD SHA (most important)
178180 if prData .PullRequest .HeadSHA != "" {
179- commitSHAs = append ( commitSHAs , prData .PullRequest .HeadSHA )
181+ shas [ prData .PullRequest .HeadSHA ] = true
180182 }
181183
182184 // Add all other commit SHAs from commit events
183185 for i := range prData .Events {
184186 e := & prData .Events [i ]
185187 if e .Kind == "commit" && e .Body != "" {
186- // Body contains the commit SHA for commit events
187- commitSHAs = append (commitSHAs , e .Body )
188+ shas [e .Body ] = true
188189 }
189190 }
190191
191- // Deduplicate SHAs (in case HEAD is also in commit events)
192- uniqueSHAs := make (map [string ]bool )
193- for _ , sha := range commitSHAs {
194- uniqueSHAs [sha ] = true
195- }
196-
197192 // Fetch check runs for each unique commit
198- var allEvents []Event
199- seenCheckRuns := make (map [string ]bool ) // Track unique check runs by "name:timestamp"
193+ var all []Event
194+ seen := make (map [string ]bool ) // Track unique check runs by "name:timestamp"
200195
201- for sha := range uniqueSHAs {
196+ for sha := range shas {
202197 events , err := c .fetchCheckRunsREST (ctx , owner , repo , sha )
203198 if err != nil {
204199 c .logger .WarnContext (ctx , "failed to fetch check runs for commit" , "sha" , sha , "error" , err )
@@ -207,19 +202,17 @@ func (c *Client) fetchAllCheckRunsREST(ctx context.Context, owner, repo string,
207202
208203 // Add only unique check runs (same check can run on multiple commits)
209204 for i := range events {
210- event := & events [i ]
211- // Create a unique key based on check name and timestamp
212- key := fmt .Sprintf ("%s:%s" , event .Body , event .Timestamp .Format (time .RFC3339Nano ))
213- if ! seenCheckRuns [key ] {
214- seenCheckRuns [key ] = true
215- // Add the commit SHA to the Target field
216- event .Target = sha
217- allEvents = append (allEvents , * event )
205+ ev := & events [i ]
206+ key := fmt .Sprintf ("%s:%s" , ev .Body , ev .Timestamp .Format (time .RFC3339Nano ))
207+ if ! seen [key ] {
208+ seen [key ] = true
209+ ev .Target = sha
210+ all = append (all , * ev )
218211 }
219212 }
220213 }
221214
222- return allEvents
215+ return all
223216}
224217
225218// existingRequiredChecks extracts required checks that were already identified.
@@ -228,19 +221,17 @@ func (*Client) existingRequiredChecks(prData *PullRequestData) []string {
228221
229222 // Extract from existing events that are marked as required
230223 for i := range prData .Events {
231- event := & prData .Events [i ]
232- if event .Required && (event .Kind == "check_run" || event .Kind == "status_check" ) {
233- required = append (required , event .Body )
224+ e := & prData .Events [i ]
225+ if e .Required && (e .Kind == "check_run" || e .Kind == "status_check" ) {
226+ required = append (required , e .Body )
234227 }
235228 }
236229
237230 // Also extract from pending checks in check summary (these are required but haven't run)
238231 if prData .PullRequest .CheckSummary != nil {
239- for check := range prData .PullRequest .CheckSummary .Pending {
240- // Check if it's not already in the list
241- found := slices .Contains (required , check )
242- if ! found {
243- required = append (required , check )
232+ for chk := range prData .PullRequest .CheckSummary .Pending {
233+ if ! slices .Contains (required , chk ) {
234+ required = append (required , chk )
244235 }
245236 }
246237 }
@@ -252,16 +243,16 @@ func (*Client) existingRequiredChecks(prData *PullRequestData) []string {
252243// This recalculates the entire check summary from ALL events to ensure we have the latest state.
253244func (c * Client ) recalculateCheckSummaryWithCheckRuns (_ /* ctx */ context.Context , prData * PullRequestData , _ /* checkRunEvents */ []Event ) {
254245 // Get existing required checks before we overwrite the summary
255- var requiredChecks []string
246+ var required []string
256247 if prData .PullRequest .CheckSummary != nil {
257- for check := range prData .PullRequest .CheckSummary .Pending {
258- requiredChecks = append (requiredChecks , check )
248+ for chk := range prData .PullRequest .CheckSummary .Pending {
249+ required = append (required , chk )
259250 }
260251 }
261252
262253 // Recalculate the entire check summary from ALL events (including the new check runs)
263254 // This ensures we get the latest state based on timestamps
264- prData .PullRequest .CheckSummary = calculateCheckSummary (prData .Events , requiredChecks )
255+ prData .PullRequest .CheckSummary = calculateCheckSummary (prData .Events , required )
265256
266257 // Update test state based on the recalculated check summary
267258 prData .PullRequest .TestState = c .calculateTestStateFromCheckSummary (prData .PullRequest .CheckSummary )
0 commit comments