aboutsummaryrefslogtreecommitdiff
path: root/scripts/squash_typos.py
diff options
context:
space:
mode:
authordundargoc <33953936+dundargoc@users.noreply.github.com>2021-08-09 15:21:50 +0200
committerGitHub <noreply@github.com>2021-08-09 15:21:50 +0200
commit7dbbd5d8b1831ae190fe29cc6630b08cbc90c568 (patch)
tree4fe618e7bb0a55334119d01954b7c7422e4bd3ac /scripts/squash_typos.py
parent9ef7003c38c3be31e47732256fd591b5884613d1 (diff)
downloadrneovim-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.py148
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()