1+ #!/usr/bin/env ruby
2+
3+ # Render Cron Scraper V4 - Fetches PRs and Reviews for all configured repositories
4+ # This script fetches both PR data and PR reviews (approvals) for accurate tracking
5+
6+ require 'logger'
7+
8+ # Initialize logger
9+ logger = Logger . new ( STDOUT )
10+ logger . level = Logger ::INFO
11+ logger . formatter = proc do |severity , datetime , progname , msg |
12+ "[#{ datetime . strftime ( '%Y-%m-%d %H:%M:%S' ) } ] #{ severity } : #{ msg } \n "
13+ end
14+
15+ start_time = Time . now
16+ logger . info "============================================================"
17+ logger . info "Starting Render Cron Scraper V4"
18+ logger . info "============================================================"
19+
20+ begin
21+ # Log configured repositories
22+ logger . info "Configured repositories:"
23+ RepositoryConfig . all . each do |repo |
24+ logger . info " - #{ repo . owner } /#{ repo . name } "
25+ end
26+
27+ # Track results
28+ success_count = 0
29+ error_count = 0
30+ total_prs = 0
31+ total_reviews_fetched = 0
32+
33+ # Fetch PRs for each configured repository
34+ RepositoryConfig . all . each do |repo |
35+ logger . info ""
36+ logger . info "Processing #{ repo . owner } /#{ repo . name } ..."
37+
38+ begin
39+ # Check rate limit before proceeding
40+ github_service = GithubService . new ( owner : repo . owner , repo : repo . name )
41+ rate_limit = github_service . rate_limit
42+ logger . info "API rate limit: #{ rate_limit . remaining } /#{ rate_limit . limit } "
43+
44+ if rate_limit . remaining < 100
45+ logger . warn "Skipping #{ repo . name } due to low API rate limit (#{ rate_limit . remaining } )"
46+ next
47+ end
48+
49+ # Count existing PRs for this repo
50+ before_count = PullRequest . where (
51+ repository_name : repo . name ,
52+ repository_owner : repo . owner
53+ ) . count
54+
55+ # Run the fetch job
56+ FetchAllPullRequestsJob . perform_now (
57+ repository_name : repo . name ,
58+ repository_owner : repo . owner
59+ )
60+
61+ # Get all open PRs for this repository to fetch reviews
62+ open_prs = PullRequest . where (
63+ repository_name : repo . name ,
64+ repository_owner : repo . owner ,
65+ state : 'open'
66+ )
67+
68+ logger . info "Fetching reviews for #{ open_prs . count } open PRs..."
69+ reviews_count = 0
70+
71+ open_prs . find_each do |pr |
72+ begin
73+ # Fetch reviews from GitHub
74+ reviews = github_service . pull_request_reviews ( pr . number )
75+
76+ if reviews . any?
77+ reviews . each do |review_data |
78+ PullRequestReview . find_or_create_by (
79+ pull_request_id : pr . id ,
80+ github_id : review_data . id
81+ ) . update! (
82+ user : review_data . user . login ,
83+ state : review_data . state ,
84+ submitted_at : review_data . submitted_at
85+ )
86+ end
87+ reviews_count += reviews . count
88+ end
89+
90+ # Update approval status for this PR
91+ pr . update_backend_approval_status!
92+ pr . update_ready_for_backend_review!
93+ pr . update_approval_status!
94+
95+ rescue => e
96+ logger . error " Error fetching reviews for PR ##{ pr . number } : #{ e . message } "
97+ end
98+ end
99+
100+ # Count PRs after fetch
101+ after_count = PullRequest . where (
102+ repository_name : repo . name ,
103+ repository_owner : repo . owner
104+ ) . count
105+
106+ new_prs = after_count - before_count
107+ total_prs += after_count
108+ total_reviews_fetched += reviews_count
109+
110+ logger . info "✓ Successfully processed #{ repo . name } "
111+ logger . info " Total PRs: #{ after_count } (#{ new_prs } new)"
112+ logger . info " Reviews fetched: #{ reviews_count } "
113+ success_count += 1
114+
115+ rescue => e
116+ logger . error "✗ Error processing #{ repo . name } : #{ e . message } "
117+ logger . error e . backtrace . first ( 5 ) . join ( "\n " )
118+ error_count += 1
119+ end
120+ end
121+
122+ # Log final summary
123+ duration = Time . now - start_time
124+ logger . info ""
125+ logger . info "============================================================"
126+ logger . info "Cron job completed!"
127+ logger . info "Repositories processed: #{ success_count } successful, #{ error_count } errors"
128+ logger . info "Total PRs in database: #{ total_prs } "
129+ logger . info "Total reviews fetched: #{ total_reviews_fetched } "
130+ logger . info "Total time: #{ duration . round ( 2 ) } seconds"
131+
132+ # Show final PR distribution
133+ logger . info ""
134+ logger . info "PRs by repository:"
135+ PullRequest . group ( :repository_name ) . count . sort_by { |_ , count | -count } . each do |repo , count |
136+ logger . info " #{ repo } : #{ count } PRs"
137+ end
138+
139+ # Show sample of PRs with approvals
140+ logger . info ""
141+ logger . info "Sample PRs with approvals:"
142+ PullRequest . joins ( :pull_request_reviews )
143+ . where ( pull_request_reviews : { state : 'APPROVED' } )
144+ . distinct
145+ . limit ( 5 )
146+ . each do |pr |
147+ approved_by = pr . pull_request_reviews . where ( state : 'APPROVED' ) . pluck ( :user ) . join ( ', ' )
148+ logger . info " PR ##{ pr . number } : Approved by #{ approved_by } "
149+ end
150+
151+ logger . info "============================================================"
152+
153+ rescue => e
154+ logger . error "Fatal error in cron job: #{ e . message } "
155+ logger . error e . backtrace . join ( "\n " )
156+ raise e
157+ end
0 commit comments