@@ -94,3 +94,90 @@ def main():
94
94
95
95
if __name__ == "__main__" :
96
96
main ()
97
+
98
+
99
+ def wait_for_workflows (repo , pr_number , max_wait = 1800 , interval = 30 ):
100
+ """Waits for specified GitHub workflows to complete."""
101
+ workflows = ["auto-merge.yml" , "save-pr-number.yml" , "validation.yml" ]
102
+ start_time = time .time ()
103
+
104
+ while time .time () - start_time < max_wait :
105
+ runs = repo .get_workflow_runs (branch = f"refs/pull/{ pr_number } /merge" , status = "in_progress" )
106
+ if all (run .name not in workflows for run in runs ):
107
+ return True # All workflows completed
108
+
109
+ time .sleep (interval )
110
+
111
+ print ("❌ Workflows did not complete within the time limit." )
112
+ return False
113
+
114
+ import os
115
+ import requests
116
+
117
+ def approve_pull_request (repo , pr_number ):
118
+ """Approves the pull request using GitHub token if available, otherwise fallback to standard API."""
119
+ pr = repo .get_pull (pr_number )
120
+
121
+ # Dismiss previous approvals first
122
+ dismiss_previous_approvals (repo , pr_number )
123
+
124
+ # Validate PR files and domains, collect feedback comments
125
+ comments = []
126
+
127
+ if not validate_pr_files (pr ):
128
+ comments .append ({"file" : "unknown" , "line" : 0 , "comment" : "❌ PR contains invalid files. Please review file requirements." })
129
+
130
+ if not validate_domains (pr ):
131
+ comments .append ({"file" : "unknown" , "line" : 0 , "comment" : "❌ PR includes an invalid domain. Ensure compliance with domain policies." })
132
+
133
+ # Wait for workflows to complete
134
+ if not wait_for_workflows (repo , pr_number ):
135
+ comments .append ({"file" : "unknown" , "line" : 0 , "comment" : "❌ Workflows did not pass successfully. Please check GitHub Actions." })
136
+
137
+ # Post review comments if any issues are found
138
+ if comments :
139
+ post_review_comment (repo , pr_number , comments )
140
+ return
141
+
142
+ # Attempt to approve PR using GitHub Actions secret token
143
+ github_token = os .getenv ("GITHUB_TOKEN" )
144
+ if github_token :
145
+ headers = {"Authorization" : f"token { github_token } " }
146
+ approval_url = f"https://api.github.com/repos/{ repo .owner .login } /{ repo .name } /pulls/{ pr_number } /reviews"
147
+ data = {"event" : "APPROVE" , "body" : "✅ PR approved automatically as it complies with rules and all workflow checks passed." }
148
+
149
+ response = requests .post (approval_url , json = data , headers = headers )
150
+ if response .status_code in [200 , 201 ]:
151
+ print ("✅ PR approved successfully using GitHub token." )
152
+ return
153
+ else :
154
+ print (f"⚠️ GitHub token approval failed: { response .json ()} " )
155
+
156
+ # Fallback: Approve using repository API
157
+ try :
158
+ pr .create_review (event = "APPROVE" , body = "✅ PR approved automatically as it complies with rules and all workflow checks passed." )
159
+ print ("✅ PR approved successfully using repository API." )
160
+ except Exception as e :
161
+ print (f"❌ Failed to approve PR using repository API: { e } " )
162
+
163
+ def dismiss_previous_approvals (repo , pr_number ):
164
+ """Dismisses previous approvals for the PR."""
165
+ pr = repo .get_pull (pr_number )
166
+ reviews = pr .get_reviews ()
167
+
168
+ for review in reviews :
169
+ if review .state == "APPROVED" :
170
+ repo ._requester .requestJson ("PUT" , f"{ pr .url } /reviews/{ review .id } /dismissals" ,
171
+ input = {"message" : "Approval dismissed due to new commit." })
172
+ print (f"⚠️ Previous approval by { review .user .login } dismissed." )
173
+
174
+ def post_review_comment (repo , pr_number , comments ):
175
+ """Posts review comments on the PR instead of rejecting it outright."""
176
+ pr = repo .get_pull (pr_number )
177
+
178
+ review_comments = [{"path" : c ["file" ], "position" : c ["line" ], "body" : c ["comment" ]} for c in comments ]
179
+ if review_comments :
180
+ pr .create_review (event = "REQUEST_CHANGES" , comments = review_comments )
181
+ print ("⚠️ Review comments posted for required changes." )
182
+ else :
183
+ print ("✅ No issues found." )
0 commit comments