diff options
author | dundargoc <33953936+dundargoc@users.noreply.github.com> | 2021-08-09 15:21:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-09 15:21:50 +0200 |
commit | 7dbbd5d8b1831ae190fe29cc6630b08cbc90c568 (patch) | |
tree | 4fe618e7bb0a55334119d01954b7c7422e4bd3ac /scripts/squash_typos.py | |
parent | 9ef7003c38c3be31e47732256fd591b5884613d1 (diff) | |
download | rneovim-7dbbd5d8b1831ae190fe29cc6630b08cbc90c568.tar.gz rneovim-7dbbd5d8b1831ae190fe29cc6630b08cbc90c568.tar.bz2 rneovim-7dbbd5d8b1831ae190fe29cc6630b08cbc90c568.zip |
ci: create GitHub Action that squashes all typo PRs into a single PR (#15041)
The action adds all pull-request authors (and Marvim) as a co-author to the
newly created PR and also links to the closed PRs.
Diffstat (limited to 'scripts/squash_typos.py')
-rw-r--r-- | scripts/squash_typos.py | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/scripts/squash_typos.py b/scripts/squash_typos.py new file mode 100644 index 0000000000..e7ee2e24a8 --- /dev/null +++ b/scripts/squash_typos.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +""" + +This script squashes a PR tagged with the "typo" label into a single, dedicated +"squash PR". + +""" + +import subprocess +import os +import re + + +def get_authors_and_emails_from_pr(): + """ + + For a given PR number, returns all contributing authors and their emails + for that PR. This includes co-authors, meaning that if two authors are + credited for a single commit, which is possible with GitHub, then both will + get credited. + + """ + + # Get a list of all authors involved in the pull request (including co-authors). + authors = subprocess.check_output( + ["gh", "pr", "view", "--json", "commits", "--jq", ".[][].authors.[].name"], + text=True, + ).splitlines() + + # Get a list of emails of the aforementioned authors. + emails = subprocess.check_output( + ["gh", "pr", "view", "--json", "commits", "--jq", ".[][].authors.[].email"], + text=True, + ).splitlines() + + return [(author, mail) for author, mail in zip(authors, emails)] + + +def rebase_onto_pr(pr, squash_branch): + """ + + Add all commits from PR into current branch. This is done by rebasing + current branch onto the PR. + + """ + + # Check out the pull request. + subprocess.call(["gh", "pr", "checkout", pr]) + + pr_branch_name = subprocess.check_output( + ["git", "branch", "--show-current"], text=True + ).strip() + + # Change back to the original branch. + subprocess.call(["git", "switch", squash_branch]) + + # Rebase onto the pull request, aka include the commits in the pull + # request in the current branch. + subprocess.call(["git", "rebase", pr_branch_name]) + + +def squash_all_commits(): + """ + + Squash all commits into a single commit. Credit all authors by name and + email. + + """ + + authors_and_emails = get_authors_and_emails_from_pr() + subprocess.call(["git", "reset", "--soft", f"{os.environ['GITHUB_BASE_REF']}"]) + + authors_and_emails = sorted(set(authors_and_emails)) + commit_message_coauthors = "\n" + "\n".join( + [f"Co-authored-by: {i[0]} <{i[1]}>" for i in authors_and_emails] + ) + subprocess.call( + ["git", "commit", "-m", "chore: typo fixes", "-m", commit_message_coauthors] + ) + + +def force_push(branch): + gh_actor = os.environ["GITHUB_ACTOR"] + gh_token = os.environ["GITHUB_TOKEN"] + gh_repo = os.environ["GITHUB_REPOSITORY"] + subprocess.call( + [ + "git", + "push", + "--force", + f"https://{gh_actor}:{gh_token}@github.com/{gh_repo}", + branch, + ] + ) + + +def main(): + squash_branch = "marvim/squash-typos" + all_pr_urls = "" + + pr_number = re.sub(r"\D", "", os.environ["GITHUB_REF"]) + + show_ref_output = subprocess.check_output(["git", "show-ref"], text=True).strip() + + if squash_branch in show_ref_output: + subprocess.call( + ["git", "checkout", "-b", squash_branch, f"origin/{squash_branch}"] + ) + squash_branch_exists = True + + all_pr_urls += subprocess.check_output( + ["gh", "pr", "view", "--json", "body", "--jq", ".body"], text=True + ) + else: + subprocess.call(["git", "checkout", "-b", squash_branch]) + squash_branch_exists = False + + all_pr_urls += subprocess.check_output( + ["gh", "pr", "view", pr_number, "--json", "url", "--jq", ".url"], text=True + ).strip() + + rebase_onto_pr(pr_number, squash_branch) + force_push(squash_branch) + + subprocess.call(["gh", "pr", "close", pr_number]) + + squash_all_commits() + force_push(squash_branch) + + if not squash_branch_exists: + subprocess.call( + [ + "gh", + "pr", + "create", + "--fill", + "--head", + squash_branch, + "--title", + "Dedicated PR for all typo fixes.", + ] + ) + + subprocess.call(["gh", "pr", "edit", "--add-label", "typo", "--body", all_pr_urls]) + + +if __name__ == "__main__": + main() |