2323ORIGIN = 'origin'
2424
2525# Runs git with the given args and returns the stdout.
26- # Raises an error if git does not exit successfully.
27- def run_git (* args ):
26+ # Raises an error if git does not exit successfully (unless passed
27+ # allow_non_zero_exit_code=True).
28+ def run_git (* args , allow_non_zero_exit_code = False ):
2829 cmd = ['git' , * args ]
2930 p = subprocess .run (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
30- if ( p .returncode != 0 ) :
31+ if not allow_non_zero_exit_code and p .returncode != 0 :
3132 raise Exception ('Call to ' + ' ' .join (cmd ) + ' exited with code ' + str (p .returncode ) + ' stderr:' + p .stderr .decode ('ascii' ))
3233 return p .stdout .decode ('ascii' )
3334
@@ -36,7 +37,9 @@ def branch_exists_on_remote(branch_name):
3637 return run_git ('ls-remote' , '--heads' , ORIGIN , branch_name ).strip () != ''
3738
3839# Opens a PR from the given branch to the target branch
39- def open_pr (repo , all_commits , source_branch_short_sha , new_branch_name , source_branch , target_branch , conductor , is_v2_release , labels ):
40+ def open_pr (
41+ repo , all_commits , source_branch_short_sha , new_branch_name , source_branch , target_branch ,
42+ conductor , is_v2_release , labels , conflicted_files ):
4043 # Sort the commits into the pull requests that introduced them,
4144 # and any commits that don't have a pull request
4245 pull_requests = []
@@ -81,6 +84,10 @@ def open_pr(repo, all_commits, source_branch_short_sha, new_branch_name, source_
8184
8285 body .append ('' )
8386 body .append ('Please review the following:' )
87+ if len (conflicted_files ) > 0 :
88+ body .append (' - [ ] You have amended the merge commit appearing in this branch to resolve ' +
89+ 'the merge conflicts in the following files:' )
90+ body .extend ([f' - [ ] `{ file } `' for file in conflicted_files ])
8491 body .append (' - [ ] The CHANGELOG displays the correct version and date.' )
8592 body .append (' - [ ] The CHANGELOG includes all relevant, user-facing changes since the last release.' )
8693 body .append (' - [ ] There are no unexpected commits being merged into the ' + target_branch + ' branch.' )
@@ -246,6 +253,11 @@ def main():
246253 # Create the new branch and push it to the remote
247254 print ('Creating branch ' + new_branch_name )
248255
256+ # The process of creating the v1 release can run into merge conflicts. We commit the unresolved
257+ # conflicts so a maintainer can easily resolve them (vs erroring and requiring maintainers to
258+ # reconstruct the release manually)
259+ conflicted_files = []
260+
249261 if args .mode == V1_MODE :
250262 # If we're performing a backport, start from the v1 branch
251263 print (f'Creating { new_branch_name } from the { ORIGIN } /v1 branch' )
@@ -274,7 +286,12 @@ def main():
274286 print (' Nothing to revert.' )
275287
276288 print (f'Merging { ORIGIN } /{ source_branch } into the release prep branch' )
277- run_git ('merge' , f'{ ORIGIN } /{ source_branch } ' , '--no-edit' )
289+ # Commit any conflicts (see the comment for `conflicted_files`)
290+ run_git ('merge' , f'{ ORIGIN } /{ source_branch } ' , allow_non_zero_exit_code = True )
291+ conflicted_files = run_git ('diff' , '--name-only' , '--diff-filter' , 'U' ).splitlines ()
292+ if len (conflicted_files ) > 0 :
293+ run_git ('add' , '.' )
294+ run_git ('commit' , '--no-edit' )
278295
279296 # Migrate the package version number from a v2 version number to a v1 version number
280297 print (f'Setting version number to { version } ' )
@@ -317,6 +334,7 @@ def main():
317334 conductor = args .conductor ,
318335 is_v2_release = args .mode == V2_MODE ,
319336 labels = ['Update dependencies' ] if args .mode == V1_MODE else [],
337+ conflicted_files = conflicted_files
320338 )
321339
322340if __name__ == '__main__' :
0 commit comments