2626ORIGIN = 'origin'
2727
2828# Runs git with the given args and returns the stdout.
29- # Raises an error if git does not exit successfully.
30- def run_git (* args ):
29+ # Raises an error if git does not exit successfully (unless passed
30+ # allow_non_zero_exit_code=True).
31+ def run_git (* args , allow_non_zero_exit_code = False ):
3132 cmd = ['git' , * args ]
3233 p = subprocess .run (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
33- if ( p .returncode != 0 ) :
34+ if not allow_non_zero_exit_code and p .returncode != 0 :
3435 raise Exception ('Call to ' + ' ' .join (cmd ) + ' exited with code ' + str (p .returncode ) + ' stderr:' + p .stderr .decode ('ascii' ))
3536 return p .stdout .decode ('ascii' )
3637
@@ -39,7 +40,9 @@ def branch_exists_on_remote(branch_name):
3940 return run_git ('ls-remote' , '--heads' , ORIGIN , branch_name ).strip () != ''
4041
4142# Opens a PR from the given branch to the target branch
42- def open_pr (repo , all_commits , source_branch_short_sha , new_branch_name , source_branch , target_branch , conductor , is_v2_release , labels ):
43+ def open_pr (
44+ repo , all_commits , source_branch_short_sha , new_branch_name , source_branch , target_branch ,
45+ conductor , is_v2_release , labels , conflicted_files ):
4346 # Sort the commits into the pull requests that introduced them,
4447 # and any commits that don't have a pull request
4548 pull_requests = []
@@ -84,6 +87,10 @@ def open_pr(repo, all_commits, source_branch_short_sha, new_branch_name, source_
8487
8588 body .append ('' )
8689 body .append ('Please review the following:' )
90+ if len (conflicted_files ) > 0 :
91+ body .append (' - [ ] You have amended the merge commit appearing in this branch to resolve ' +
92+ 'the merge conflicts in the following files:' )
93+ body .extend ([f' - [ ] `{ file } `' for file in conflicted_files ])
8794 body .append (' - [ ] The CHANGELOG displays the correct version and date.' )
8895 body .append (' - [ ] The CHANGELOG includes all relevant, user-facing changes since the last release.' )
8996 body .append (' - [ ] There are no unexpected commits being merged into the ' + target_branch + ' branch.' )
@@ -245,6 +252,11 @@ def main():
245252 # Create the new branch and push it to the remote
246253 print ('Creating branch ' + new_branch_name )
247254
255+ # The process of creating the v1 release can run into merge conflicts. We commit the unresolved
256+ # conflicts so a maintainer can easily resolve them (vs erroring and requiring maintainers to
257+ # reconstruct the release manually)
258+ conflicted_files = []
259+
248260 if args .mode == V1_MODE :
249261 # If we're performing a backport, start from the target branch
250262 print (f'Creating { new_branch_name } from the { ORIGIN } /{ target_branch } branch' )
@@ -273,7 +285,12 @@ def main():
273285 print (' Nothing to revert.' )
274286
275287 print (f'Merging { ORIGIN } /{ source_branch } into the release prep branch' )
276- run_git ('merge' , f'{ ORIGIN } /{ source_branch } ' , '--no-edit' )
288+ # Commit any conflicts (see the comment for `conflicted_files`)
289+ run_git ('merge' , f'{ ORIGIN } /{ source_branch } ' , allow_non_zero_exit_code = True )
290+ conflicted_files = run_git ('diff' , '--name-only' , '--diff-filter' , 'U' ).splitlines ()
291+ if len (conflicted_files ) > 0 :
292+ run_git ('add' , '.' )
293+ run_git ('commit' , '--no-edit' )
277294
278295 # Migrate the package version number from a v2 version number to a v1 version number
279296 print (f'Setting version number to { version } ' )
@@ -316,6 +333,7 @@ def main():
316333 conductor = args .conductor ,
317334 is_v2_release = args .mode == V2_MODE ,
318335 labels = ['Update dependencies' ] if args .mode == V1_MODE else [],
336+ conflicted_files = conflicted_files
319337 )
320338
321339if __name__ == '__main__' :
0 commit comments