|
32 | 32 | import commonmark
|
33 | 33 | import git
|
34 | 34 | from click.exceptions import ClickException
|
| 35 | +from git import GitCommandError, Repo |
35 | 36 | from github import Github
|
36 | 37 | from packaging import version
|
37 | 38 |
|
@@ -78,6 +79,8 @@ def cli() -> None:
|
78 | 79 |
|
79 | 80 | # Optional: generate some nice links for the announcement
|
80 | 81 |
|
| 82 | + ./scripts-dev/release.py merge-back |
| 83 | +
|
81 | 84 | ./scripts-dev/release.py announce
|
82 | 85 |
|
83 | 86 | If the env var GH_TOKEN (or GITHUB_TOKEN) is set, or passed into the
|
@@ -441,6 +444,79 @@ def upload() -> None:
|
441 | 444 | )
|
442 | 445 |
|
443 | 446 |
|
| 447 | +def _merge_into(repo: Repo, source: str, target: str) -> None: |
| 448 | + """ |
| 449 | + Merges branch `source` into branch `target`. |
| 450 | + Pulls both before merging and pushes the result. |
| 451 | + """ |
| 452 | + |
| 453 | + # Update our branches and switch to the target branch |
| 454 | + for branch in [source, target]: |
| 455 | + click.echo(f"Switching to {branch} and pulling...") |
| 456 | + repo.heads[branch].checkout() |
| 457 | + # Pull so we're up to date |
| 458 | + repo.remote().pull() |
| 459 | + |
| 460 | + assert repo.active_branch.name == target |
| 461 | + |
| 462 | + try: |
| 463 | + # TODO This seemed easier than using GitPython directly |
| 464 | + click.echo(f"Merging {source}...") |
| 465 | + repo.git.merge(source) |
| 466 | + except GitCommandError as exc: |
| 467 | + # If a merge conflict occurs, give some context and try to |
| 468 | + # make it easy to abort if necessary. |
| 469 | + click.echo(exc) |
| 470 | + if not click.confirm( |
| 471 | + f"Likely merge conflict whilst merging ({source} → {target}). " |
| 472 | + f"Have you resolved it?" |
| 473 | + ): |
| 474 | + repo.git.merge("--abort") |
| 475 | + return |
| 476 | + |
| 477 | + # Push result. |
| 478 | + click.echo("Pushing...") |
| 479 | + repo.remote().push() |
| 480 | + |
| 481 | + |
| 482 | +@cli.command() |
| 483 | +def merge_back() -> None: |
| 484 | + """Merge the release branch back into the appropriate branches. |
| 485 | + All branches will be automatically pulled from the remote and the results |
| 486 | + will be pushed to the remote.""" |
| 487 | + |
| 488 | + synapse_repo = get_repo_and_check_clean_checkout() |
| 489 | + branch_name = synapse_repo.active_branch.name |
| 490 | + |
| 491 | + if not branch_name.startswith("release-v"): |
| 492 | + raise RuntimeError("Not on a release branch. This does not seem sensible.") |
| 493 | + |
| 494 | + # Pull so we're up to date |
| 495 | + synapse_repo.remote().pull() |
| 496 | + |
| 497 | + current_version = get_package_version() |
| 498 | + |
| 499 | + if current_version.is_prerelease: |
| 500 | + # Release candidate |
| 501 | + if click.confirm(f"Merge {branch_name} → develop?", default=True): |
| 502 | + _merge_into(synapse_repo, branch_name, "develop") |
| 503 | + else: |
| 504 | + # Full release |
| 505 | + sytest_repo = get_repo_and_check_clean_checkout("../sytest", "sytest") |
| 506 | + |
| 507 | + if click.confirm(f"Merge {branch_name} → master?", default=True): |
| 508 | + _merge_into(synapse_repo, branch_name, "master") |
| 509 | + |
| 510 | + if click.confirm("Merge master → develop?", default=True): |
| 511 | + _merge_into(synapse_repo, "master", "develop") |
| 512 | + |
| 513 | + if click.confirm(f"On SyTest, merge {branch_name} → master?", default=True): |
| 514 | + _merge_into(sytest_repo, branch_name, "master") |
| 515 | + |
| 516 | + if click.confirm("On SyTest, merge master → develop?", default=True): |
| 517 | + _merge_into(sytest_repo, "master", "develop") |
| 518 | + |
| 519 | + |
444 | 520 | @cli.command()
|
445 | 521 | def announce() -> None:
|
446 | 522 | """Generate markdown to announce the release."""
|
|
0 commit comments