12
12
import sys
13
13
import logging
14
14
import tempfile
15
- from typing import List
15
+ from typing import List , Tuple
16
16
from github import Github
17
17
from github .Repository import Repository
18
18
from github .PullRequest import PullRequest
23
23
24
24
logger = logging .getLogger (__name__ )
25
25
26
-
27
26
# ===============================================================================
28
27
# Parameters
29
28
# ===============================================================================
@@ -130,11 +129,13 @@ def create_or_get_branch(github_url: str,
130
129
branches : List [str ],
131
130
repo_path : str ,
132
131
token : str ,
133
- dry_run : bool = False ) -> str :
132
+ dry_run : bool = False ) -> Tuple [ str , bool ] :
134
133
"""Create a new branch if it doesn't exist, or get the existing branch."""
134
+ branch_created : bool = False
135
135
auto_branch = f"auto_update_{ target_br } "
136
136
if auto_branch not in branches :
137
137
logger .info ("Create branch: %s" , auto_branch )
138
+ branch_created = True
138
139
# Branch does not exist yet, create it now
139
140
local_repo = Repo (repo_path )
140
141
origin = local_repo .remotes .origin
@@ -147,10 +148,34 @@ def create_or_get_branch(github_url: str,
147
148
github_url = f"{ protocol } ://x-access-token:{ token } @{ rest } "
148
149
local_repo .git .remote ("set-url" , "origin" , github_url )
149
150
local_repo .git .push ('--set-upstream' , 'origin' , auto_branch )
150
- return auto_branch
151
+ return auto_branch , branch_created
152
+
151
153
154
+ def branch_delete (repo : Repo , auto_branch : str , default_branch : str , dry_run : bool = False ) -> None :
155
+ """Delete the specified branch."""
156
+ repo .git .checkout (default_branch )
157
+ # Delete the local branch
158
+ try :
159
+ repo .git .branch ('-D' , auto_branch ) # Force delete
160
+ logger .info ("Deleted local branch: %s" , auto_branch )
161
+ except GitCommandError as abort_err :
162
+ logger .warning ("Failed to delete the local branch: %s" , abort_err )
152
163
153
- def cherry_pick_commits (repo_path : str , commits : List [str ], auto_branch : str , dry_run : bool = False ) -> bool :
164
+ if not dry_run :
165
+ # Delete the remote branch
166
+ try :
167
+ repo .git .push ('origin' , '--delete' , auto_branch )
168
+ logger .info ("Deleted remote branch: %s" , auto_branch )
169
+ except GitCommandError as abort_err :
170
+ logger .warning ("Failed to delete the remote branch: %s" , abort_err )
171
+
172
+
173
+ def cherry_pick_commits (repo_path : str ,
174
+ commits : List [str ],
175
+ auto_branch : str ,
176
+ default_branch : str ,
177
+ branch_created : bool ,
178
+ dry_run : bool = False ) -> bool :
154
179
"""Cherry-pick the specified commits onto the auto_update branch."""
155
180
repo = Repo (repo_path )
156
181
origin = repo .remotes .origin
@@ -178,8 +203,10 @@ def cherry_pick_commits(repo_path: str, commits: List[str], auto_branch: str, dr
178
203
# Abort cherry-pick on conflict
179
204
try :
180
205
repo .git .cherry_pick ('--abort' )
181
- except GitCommandError as abort_err :
182
- logger .warning ("Failed to abort cherry-pick (no cherry-pick in progress?): %s" , abort_err )
206
+ except GitCommandError :
207
+ pass
208
+ if branch_created :
209
+ branch_delete (repo , auto_branch , default_branch , dry_run )
183
210
return False
184
211
185
212
# Push the branch if needed
@@ -189,7 +216,10 @@ def cherry_pick_commits(repo_path: str, commits: List[str], auto_branch: str, dr
189
216
return True
190
217
191
218
192
- def create_pull_request_if_needed (repo : Repository , auto_branch : str , target_br : str ) -> None :
219
+ def create_pull_request_if_needed (repo : Repository ,
220
+ auto_branch : str ,
221
+ target_br : str ,
222
+ pull_number : int ) -> None :
193
223
"""Create a pull request if one does not already exist."""
194
224
pr_auto_title = f"[AUTO_UPDATE] Branch { target_br } "
195
225
prs = repo .get_pulls (state = "open" , base = target_br )
@@ -199,7 +229,7 @@ def create_pull_request_if_needed(repo: Repository, auto_branch: str, target_br:
199
229
try :
200
230
repo .create_pull (
201
231
title = pr_auto_title ,
202
- body = "Automated update" ,
232
+ body = f "Automated update from # { pull_number } " ,
203
233
head = auto_branch ,
204
234
base = target_br
205
235
)
@@ -232,6 +262,7 @@ def main():
232
262
# Retrieve repo object
233
263
repo = github .get_repo (f"{ GITHUB_ORG_NAME } /{ args .repo } " )
234
264
logger .debug ("Repo Name: %s" , repo .name )
265
+ default_branch = repo .default_branch
235
266
236
267
# Retrieve PR object
237
268
pull = get_pull_request (repo , args .pull )
@@ -252,6 +283,7 @@ def main():
252
283
github_url = f"https://github.com/{ GITHUB_ORG_NAME } /{ args .repo } .git"
253
284
254
285
# Loop for all target branches
286
+ result = 0
255
287
for target_br in target_branches :
256
288
logger .info ("-------------" )
257
289
logger .info ("Target branch: %s" , target_br )
@@ -261,21 +293,30 @@ def main():
261
293
clone_repo (github_url , local_repo_path , args .token )
262
294
263
295
# Check if dedicated auto_update branch exists, else create it
264
- auto_branch = create_or_get_branch (github_url ,
265
- target_br ,
266
- branches ,
267
- local_repo_path ,
268
- args .token ,
269
- args .dry_run )
296
+ auto_branch , branch_created = create_or_get_branch (github_url ,
297
+ target_br ,
298
+ branches ,
299
+ local_repo_path ,
300
+ args .token ,
301
+ args .dry_run )
270
302
271
303
# Cherry-pick the commits onto the auto_update branch
272
- if not cherry_pick_commits (local_repo_path , commits , auto_branch , args .dry_run ):
304
+ if not cherry_pick_commits (local_repo_path ,
305
+ commits ,
306
+ auto_branch ,
307
+ default_branch ,
308
+ branch_created ,
309
+ args .dry_run ):
310
+ result = 1
273
311
continue
274
312
275
313
if not args .dry_run :
276
314
# Create a pull request if needed
277
- create_pull_request_if_needed (repo , auto_branch , target_br )
315
+ create_pull_request_if_needed (repo , auto_branch , target_br , args . pull )
278
316
317
+ if result != 0 :
318
+ logger .error ("One or more operations failed." )
319
+ sys .exit (1 )
279
320
280
321
if __name__ == "__main__" :
281
322
main ()
0 commit comments