From 65ba12bd6ce6f0bd3ee7b9c99e2340b23d4c8e76 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 24 Apr 2020 03:11:48 -0500 Subject: [PATCH 001/153] Allow for a backport request that ends in a period --- meeseeksdev/meeseeksbox/commands.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index d69d5f5..1d7bab9 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -140,7 +140,7 @@ def blackify(*, session, payload, arguments, local_config=None): commits_url = pr_data['commits_url'] commits_data = session.ghrequest( "GET",commits_url).json() - + for commit in commits_data: if len(commit['parents']) != 1: comment_url = payload["issue"]["comments_url"] @@ -157,7 +157,7 @@ def blackify(*, session, payload, arguments, local_config=None): # requester has technically no access to committer repo. # TODO, check if maintainer target_session = yield "{}/{}".format(author_login, repo_name) - if target_session: + if target_session: print('installed on target repository') atk = target_session.token() else: @@ -244,7 +244,7 @@ def lpr(*args): body=dedent(""" I've rebased this Pull Request, applied `black` on all the individual commits, and pushed. You may have trouble pushing further - commits, but feel free to force push and ask me to reformat again. + commits, but feel free to force push and ask me to reformat again. """) ) @@ -309,7 +309,10 @@ def keen_stats(): "GET", f"https://api.github.com/repos/{org_name}/{repo_name}/branches" ).json() existing_branches_names = {b["name"] for b in existing_branches} - if target_branch not in existing_branches_names: + if target_branch not in existing_branches_names and target_branch.endswith('.'): + target_branch = target_branch[:-1] + + if target_branch not in existing_branches_names print( red + f"Request to backport to `{target_branch}`, which does not seem to exist. Known : {existing_branches_names}" From 87f00e51bd67c094b12e77ef3c84349c0dc6bb79 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 29 Apr 2020 04:06:20 -0500 Subject: [PATCH 002/153] fix syntax --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 1d7bab9..599e3e0 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -312,7 +312,7 @@ def keen_stats(): if target_branch not in existing_branches_names and target_branch.endswith('.'): target_branch = target_branch[:-1] - if target_branch not in existing_branches_names + if target_branch not in existing_branches_names: print( red + f"Request to backport to `{target_branch}`, which does not seem to exist. Known : {existing_branches_names}" From 95608a53fcad0886c0d821652e16ab32c339241c Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 8 Jun 2020 11:16:59 -0700 Subject: [PATCH 003/153] reformat --- meeseeksdev/meeseeksbox/commands.py | 207 +++++++++++++++------------- meeseeksdev/meeseeksbox/core.py | 10 +- meeseeksdev/tests/test_misc.py | 21 +-- 3 files changed, 129 insertions(+), 109 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 679f523..62bf4f7 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -116,37 +116,40 @@ def _compute_pwd_changes(whitelist): from difflib import SequenceMatcher from pathlib import Path import glob + post_changes = [] import os - print('== pwd', os.getcwd()) - print('== listdir', os.listdir()) - for p in glob.glob('**/*.py', recursive=True): - print('=== scanning', p, p in whitelist) + print("== pwd", os.getcwd()) + print("== listdir", os.listdir()) + + for p in glob.glob("**/*.py", recursive=True): + print("=== scanning", p, p in whitelist) if p not in whitelist: # we don't touch files not in this PR. continue p = Path(p) old = p.read_text() new = black.format_str(old, mode=black.FileMode()) - if new != old: - print('will differ') + if new != old: + print("will differ") nl = new.splitlines() ol = old.splitlines() s = SequenceMatcher(None, ol, nl) for t, a1, a2, b1, b2 in s.get_opcodes(): - if t == 'replace': + if t == "replace": + + c = "```suggestion\n" - c = '```suggestion\n' - for n in nl[b1:b2]: - c+=n - c+='\n' - c+='```' + c += n + c += "\n" + c += "```" ch = (p.as_posix(), a1, a2, c) post_changes.append(ch) return post_changes + @admin def black_suggest(*, session, payload, arguments, local_config=None): print("===== reformatting suggestions. =====") @@ -172,18 +175,15 @@ def black_suggest(*, session, payload, arguments, local_config=None): author_login = pr_data["head"]["repo"]["owner"]["login"] repo_name = pr_data["head"]["repo"]["name"] - commits_url = pr_data['commits_url'] + commits_url = pr_data["commits_url"] - commits_data = session.ghrequest( "GET",commits_url).json() - - - + commits_data = session.ghrequest("GET", commits_url).json() # that will likely fail, as if PR, we need to bypass the fact that the # requester has technically no access to committer repo. # TODO, check if maintainer ## target_session = yield "{}/{}".format(author_login, repo_name) - ## if target_session: + ## if target_session: ## print('installed on target repository') ## atk = target_session.token() ## else: @@ -212,16 +212,21 @@ def black_suggest(*, session, payload, arguments, local_config=None): # this process can take some time, regen token # paginated by 30 files, let's nto go that far (yet) - files_response = session.ghrequest("GET", f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/files") - pr_files = [r['filename'] for r in files_response.json()] - print('== PR contains', len(pr_files), 'files') + files_response = session.ghrequest( + "GET", + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/files", + ) + pr_files = [r["filename"] for r in files_response.json()] + print("== PR contains", len(pr_files), "files") if os.path.exists(repo_name): print("== Cleaning up previsous work... ") subprocess.run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") - print(f"== Cloning repository from {org_name}/{repo_name}, this can take some time..") + print( + f"== Cloning repository from {org_name}/{repo_name}, this can take some time.." + ) process = subprocess.run( [ "git", @@ -234,59 +239,59 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Cloned..") process.check_returncode() - subprocess.run("git config --global user.email meeseeksmachine@gmail.com".split(" ")) + subprocess.run( + "git config --global user.email meeseeksmachine@gmail.com".split(" ") + ) subprocess.run("git config --global user.name FriendlyBot".split(" ")) # do the pep8ify on local filesystem repo = git.Repo(repo_name) - #branch = master - #print(f"== Fetching branch `{branch}` ...") - #repo.remotes.origin.fetch("{}:workbranch".format(branch)) - #repo.git.checkout("workbranch") + # branch = master + # print(f"== Fetching branch `{branch}` ...") + # repo.remotes.origin.fetch("{}:workbranch".format(branch)) + # repo.git.checkout("workbranch") print("== Fetching Commits to reformat...") repo.remotes.origin.fetch("{head_sha}".format(head_sha=head_sha)) print("== All has been fetched correctly") repo.git.checkout(head_sha) print(f"== checked PR head {head_sha}") - print("== Computing changes....") os.chdir(repo_name) changes = _compute_pwd_changes(pr_files) - os.chdir('..') + os.chdir("..") print("... computed", len(changes), changes) - - COMFORT_FADE = 'application/vnd.github.comfort-fade-preview+json' + COMFORT_FADE = "application/vnd.github.comfort-fade-preview+json" # comment_url = payload["issue"]["comments_url"] # session.post_comment( # comment_url, # body=dedent(""" # I've rebased this Pull Request, applied `black` on all the # individual commits, and pushed. You may have trouble pushing further - # commits, but feel free to force push and ask me to reformat again. + # commits, but feel free to force push and ask me to reformat again. # """) # ) for path, start, end, body in changes: - print(f'== will suggest the following on {path} {start+1} to {end}\n', body) - if start+1 != end: + print(f"== will suggest the following on {path} {start+1} to {end}\n", body) + if start + 1 != end: data = { - "body": body, - "commit_id": head_sha, - "path": path, - "start_line": start+1, - "start_side": "RIGHT", - "line": end, - "side": "RIGHT" + "body": body, + "commit_id": head_sha, + "path": path, + "start_line": start + 1, + "start_side": "RIGHT", + "line": end, + "side": "RIGHT", } try: resp = session.ghrequest( - "POST", - f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", - json=data, - override_accept_header=COMFORT_FADE, + "POST", + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", + json=data, + override_accept_header=COMFORT_FADE, ) except Exception: # likely unprecessable entity out of range @@ -294,18 +299,18 @@ def black_suggest(*, session, payload, arguments, local_config=None): else: # we can't seem to do single line with COMFORT_FADE data = { - "body": body, - "commit_id": head_sha, - "path": path, - "line": end, - "side": "RIGHT" + "body": body, + "commit_id": head_sha, + "path": path, + "line": end, + "side": "RIGHT", } try: resp = session.ghrequest( - "POST", - f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", - json=data, + "POST", + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", + json=data, ) except Exception: # likely unprecessable entity out of range @@ -315,7 +320,6 @@ def black_suggest(*, session, payload, arguments, local_config=None): subprocess.run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") - @admin def blackify(*, session, payload, arguments, local_config=None): @@ -343,31 +347,31 @@ def blackify(*, session, payload, arguments, local_config=None): author_login = pr_data["head"]["repo"]["owner"]["login"] repo_name = pr_data["head"]["repo"]["name"] - commits_url = pr_data['commits_url'] + commits_url = pr_data["commits_url"] + + commits_data = session.ghrequest("GET", commits_url).json() - commits_data = session.ghrequest( "GET",commits_url).json() - for commit in commits_data: - if len(commit['parents']) != 1: + if len(commit["parents"]) != 1: comment_url = payload["issue"]["comments_url"] session.post_comment( comment_url, - body="It looks like the history is not linear in this pull-request. I'm afraid I can't rebase.\n" + body="It looks like the history is not linear in this pull-request. I'm afraid I can't rebase.\n", ) return # so far we assume that the commit we rebase on is the first. - to_rebase_on = commits_data[0]['parents'][0]['sha'] + to_rebase_on = commits_data[0]["parents"][0]["sha"] # that will likely fail, as if PR, we need to bypass the fact that the # requester has technically no access to committer repo. # TODO, check if maintainer target_session = yield "{}/{}".format(author_login, repo_name) - if target_session: - print('installed on target repository') + if target_session: + print("installed on target repository") atk = target_session.token() else: - print('use allow edit as maintainer') + print("use allow edit as maintainer") atk = session.token() comment_url = payload["issue"]["comments_url"] session.post_comment( @@ -375,7 +379,7 @@ def blackify(*, session, payload, arguments, local_config=None): body="Would you mind installing me on your fork so that I can update your branch ? \n" "Click [here](https://github.com/apps/meeseeksdev/installations/new)" "to do that, and follow the instruction to add your fork." - "I'm going to try to push as a maintainer but this may not work." + "I'm going to try to push as a maintainer but this may not work.", ) # if not target_session: # comment_url = payload["issue"]["comments_url"] @@ -396,7 +400,9 @@ def blackify(*, session, payload, arguments, local_config=None): subprocess.run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") - print(f"== Cloning repository from {author_login}/{repo_name}, this can take some time..") + print( + f"== Cloning repository from {author_login}/{repo_name}, this can take some time.." + ) process = subprocess.run( [ "git", @@ -409,7 +415,9 @@ def blackify(*, session, payload, arguments, local_config=None): print("== Cloned..") process.check_returncode() - subprocess.run("git config --global user.email meeseeksmachine@gmail.com".split(" ")) + subprocess.run( + "git config --global user.email meeseeksmachine@gmail.com".split(" ") + ) subprocess.run("git config --global user.name FriendlyBot".split(" ")) # do the pep8ify on local filesystem @@ -424,16 +432,29 @@ def blackify(*, session, payload, arguments, local_config=None): os.chdir(repo_name) def lpr(*args): - print('Should run:', *args) + print("Should run:", *args) - lpr('git rebase -x "black --fast . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', to_rebase_on ) + lpr( + 'git rebase -x "black --fast . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', + to_rebase_on, + ) ## todo check error code. - subprocess.run(['git','rebase', '-x','black --fast . && git commit -a --amend --no-edit','--strategy-option=theirs','--autosquash', to_rebase_on]) + subprocess.run( + [ + "git", + "rebase", + "-x", + "black --fast . && git commit -a --amend --no-edit", + "--strategy-option=theirs", + "--autosquash", + to_rebase_on, + ] + ) ## write the commit message - #msg = "Autofix pep 8 of #%i: %s" % (prnumber, prtitle) + "\n\n" - #repo.git.commit("-am", msg) + # msg = "Autofix pep 8 of #%i: %s" % (prnumber, prtitle) + "\n\n" + # repo.git.commit("-am", msg) ## Push the pep8ify work print("== Pushing work....:") @@ -442,18 +463,18 @@ def lpr(*args): repo.git.checkout("master") repo.branches.workbranch.delete(repo, "workbranch", force=True) - comment_url = payload["issue"]["comments_url"] session.post_comment( comment_url, - body=dedent(""" + body=dedent( + """ I've rebased this Pull Request, applied `black` on all the individual commits, and pushed. You may have trouble pushing further commits, but feel free to force push and ask me to reformat again. - """) + """ + ), ) - #os.chdir("..") - + # os.chdir("..") @write @@ -632,7 +653,6 @@ def keen_stats(): traceback.print_exc() ## end optimise-fetch-experiment - clone_epoch = time.time() action = "set-url" what_was_done = "Fast-Forwarded" @@ -900,11 +920,11 @@ def tag(session, payload, arguments, local_config=None): num = payload.get("issue", payload.get("pull_request")).get("number") url = f"https://api.github.com/repos/{org}/{repo}/issues/{num}/labels" arguments = arguments.replace("'", '"') - quoted = re.findall(r'\"(.+?)\"',arguments.replace("'", '"')) + quoted = re.findall(r"\"(.+?)\"", arguments.replace("'", '"')) for q in quoted: - arguments = arguments.replace('"%s"' % q, '') + arguments = arguments.replace('"%s"' % q, "") tags = [arg.strip() for arg in arguments.split(",") if arg.strip()] + quoted - print('raw tags:', tags) + print("raw tags:", tags) to_apply = [] not_applied = [] try: @@ -915,51 +935,48 @@ def tag(session, payload, arguments, local_config=None): label_payloads = [label_payload] def get_next_link(req): - all_links = req.headers.get('Link') + all_links = req.headers.get("Link") if 'rel="next"' in all_links: - links = all_links.split(',') - next_link = [l for l in links if 'next' in l][0] # assume only one. + links = all_links.split(",") + next_link = [l for l in links if "next" in l][0] # assume only one. if next_link: - return next_link.split(';')[0].strip(' <>') - + return next_link.split(";")[0].strip(" <>") # let's assume no more than 200 labels resp = label_payload try: for i in range(10): - print('get labels page',i) + print("get labels page", i) next_link = get_next_link(resp) if next_link: - resp = session.ghrequest( "GET", next_link) + resp = session.ghrequest("GET", next_link) label_payloads.append(resp) else: break except Exception: traceback.print_exc() - - know_labels = [] for p in label_payloads: know_labels.extend([label["name"] for label in p.json()]) - print('known labels', know_labels) + print("known labels", know_labels) not_known_tags = [t for t in tags if t not in know_labels] known_tags = [t for t in tags if t in know_labels] - print('known tags', known_tags) - print('known labels', not_known_tags) + print("known tags", known_tags) + print("known labels", not_known_tags) # try to look at casing nk = [] known_lower_normal = {l.lower(): l for l in know_labels} - print('known labels lower', known_lower_normal) + print("known labels lower", known_lower_normal) for t in not_known_tags: target = known_lower_normal.get(t.lower()) - print('mapping t', t, target) + print("mapping t", t, target) if target: known_tags.append(t) else: - print('will not apply', t) + print("will not apply", t) nk.append(t) to_apply = known_tags diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index edf5de4..3d99262 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -81,12 +81,14 @@ class MainHandler(BaseHandler): def get(self): self.finish("No") + def _strip_please(c): - if c.startswith('please '): + if c.startswith("please "): return c[6:].lstrip() else: return c + def process_mentionning_comment(body, bot_re): """ Given a comment body and a bot name parse this into a tuple of (command, arguments) @@ -530,7 +532,7 @@ def user_can(user, command, repo, org, session): if user in conf.get("blacklisted_users", []): return False, {} - + user_section = conf.get("users", {}).get(user, {}) custom_allowed_commands = user_section.get("can", []) @@ -584,9 +586,9 @@ def user_can(user, command, repo, org, session): traceback.print_exc() - has_scope = (permission_level.value >= handler.scope.value) + has_scope = permission_level.value >= handler.scope.value if has_scope: - local_config={} + local_config = {} if (has_scope) or ( is_legitimate_author diff --git a/meeseeksdev/tests/test_misc.py b/meeseeksdev/tests/test_misc.py index 66b9f18..efbdd32 100644 --- a/meeseeksdev/tests/test_misc.py +++ b/meeseeksdev/tests/test_misc.py @@ -3,21 +3,22 @@ import re - def test1(): - botname = 'meeseeksdev' + botname = "meeseeksdev" reg = re.compile("@?" + re.escape(botname) + "(?:\[bot\])?", re.IGNORECASE) - assert process_mentionning_comment(textwrap.dedent(''' + assert ( + process_mentionning_comment( + textwrap.dedent( + """ @meeseeksdev nothing @meeseeksdev[bot] do nothing meeseeksdev[bot] do something - '''), reg) == [['nothing', None], - ['do', 'nothing'], - ['do', 'something']] - - - - + """ + ), + reg, + ) + == [["nothing", None], ["do", "nothing"], ["do", "something"]] + ) From de1c217bc35a310b9201b826ced522dbbdb663f5 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 8 Jun 2020 17:18:23 -0700 Subject: [PATCH 004/153] Update meeseeksdev/meeseeksbox/commands.py Co-authored-by: meeseeksdev[bot] <24485218+meeseeksdev[bot]@users.noreply.github.com> --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 2b2a4b7..c54f78d 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -536,7 +536,7 @@ def keen_stats(): "GET", f"https://api.github.com/repos/{org_name}/{repo_name}/branches" ).json() existing_branches_names = {b["name"] for b in existing_branches} - if target_branch not in existing_branches_names and target_branch.endswith('.'): + if target_branch not in existing_branches_names and target_branch.endswith("."): target_branch = target_branch[:-1] if target_branch not in existing_branches_names: From 978c77403bc0ab46f0765679e0cce6eec3abff3e Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 31 Mar 2021 01:09:24 -0400 Subject: [PATCH 005/153] Print milestone description if backport didn't happen. --- meeseeksdev/meeseeksbox/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 3d99262..43d09c7 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -401,6 +401,7 @@ def dispatch_action(self, type_, payload): '"on-merge:" found in milestone description, but unable to parse command.', 'Is "on-merge:" on a separate line?', ) + print(description) else: print(f"({repo}) Hum, closed, PR but not merged") else: From c6d1b2fbcb5b7acf56c245f101a0f3da6a796704 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Wed, 31 Mar 2021 09:18:19 -0700 Subject: [PATCH 006/153] try default branch --- meeseeksdev/meeseeksbox/commands.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index c54f78d..05442dd 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -532,6 +532,9 @@ def keen_stats(): maybe_wrong_named_branch = False s_slug = f"{org_name}/{repo_name}" try: + default_branch = session.ghrequest( + "GET", f"https://api.github.com/repos/{org_name}/{repo_name}" + ).json()["default_branch"] existing_branches = session.ghrequest( "GET", f"https://api.github.com/repos/{org_name}/{repo_name}/branches" ).json() @@ -630,12 +633,13 @@ def keen_stats(): ).check_returncode() repo = git.Repo(repo_name) - print("FF: Git fetch master") - repo.remotes.origin.fetch("master") + print(f"FF: Git fetch {default_branch}") + repo.remotes.origin.fetch(default_branch) repo.git.checkout("master") - print("FF: Reset hard origin/master") + print(f"FF: Reset hard origin/{default_branch}") subprocess.run( - ["git", "reset", "--hard", "origin/master"], cwd=repo_name + ["git", "reset", "--hard", f"origin/{default_branch}"], + cwd=repo_name, ).check_returncode() print("FF: Git describe tags....") subprocess.run(["git", "describe", "--tag"], cwd=repo_name) From 82c1269129c1fec2945b0c3143f7aadfb6732d53 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Wed, 31 Mar 2021 09:23:08 -0700 Subject: [PATCH 007/153] second try --- meeseeksdev/meeseeksbox/commands.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 05442dd..994f140 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -397,7 +397,7 @@ def blackify(*, session, payload, arguments, local_config=None): if os.path.exists(repo_name): print("== Cleaning up previsous work... ") - subprocess.run("rm -rf {}".format(repo_name).split(" ")) + subprocess.run("rm -rf {}".format(repo_name).split(" "), check=True) print("== Done cleaning ") print( @@ -452,15 +452,15 @@ def lpr(*args): ] ) - ## write the commit message + # write the commit message # msg = "Autofix pep 8 of #%i: %s" % (prnumber, prtitle) + "\n\n" # repo.git.commit("-am", msg) - ## Push the pep8ify work + # Push the pep8ify work print("== Pushing work....:") lpr(f"pushing with workbranch:{branch}") repo.remotes.origin.push("workbranch:{}".format(branch), force=True) - repo.git.checkout("master") + repo.git.checkout(default_branch) repo.branches.workbranch.delete(repo, "workbranch", force=True) comment_url = payload["issue"]["comments_url"] @@ -635,7 +635,7 @@ def keen_stats(): repo = git.Repo(repo_name) print(f"FF: Git fetch {default_branch}") repo.remotes.origin.fetch(default_branch) - repo.git.checkout("master") + repo.git.checkout(default_branch) print(f"FF: Reset hard origin/{default_branch}") subprocess.run( ["git", "reset", "--hard", f"origin/{default_branch}"], @@ -860,10 +860,10 @@ def keen_stats(): keen_stats() # TODO comment on issue print(e) - repo.git.checkout("master") + repo.git.checkout(default_branch) repo.branches.workbranch.delete(repo, "workbranch", force=True) - # TODO checkout master and get rid of branch + # TODO checkout the default_branch and get rid of branch # Make the PR on GitHub print( From cc0f35d323120d3191073983c62d0e6656b25e11 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 5 May 2021 17:16:44 -0400 Subject: [PATCH 008/153] Ensure labels and milestones are newline-separated. --- meeseeksdev/meeseeksbox/core.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 43d09c7..b3d098a 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -354,7 +354,7 @@ def dispatch_action(self, type_, payload): + f"(https://github.com/{repo}/pull/{num}) merged (action: {action}, merged:{merged}) by {login}" ) if merged_by: - description = "" + description = [] try: raw_labels = is_pr.get("labels", []) if raw_labels: @@ -366,21 +366,17 @@ def dispatch_action(self, type_, payload): raw_label.get("url", ""), override_accept_header=ACCEPT_HEADER_SYMMETRA, ).json() - label_desc = label.get("description", "") # apparently can still be none-like ? - if not label_desc: - label_desc = "" - description += "\n" + label_desc.replace("&", "\n") + label_desc = label.get("description", "") or "" + description.append(label_desc.replace("&", "\n")) except: import traceback traceback.print_exc() milestone = is_pr.get("milestone", {}) if milestone: - e = milestone.get("description", "") - if not e: - e = "" - description += e + description.append(milestone.get("description", "") or "") + description = "\n".join(description) if ( "on-merge:" in description and is_pr["base"]["ref"] == "master" From e1d527b716cbbb636231518c056d9dec14dab2f5 Mon Sep 17 00:00:00 2001 From: Simon Conseil Date: Wed, 26 May 2021 18:37:05 +0200 Subject: [PATCH 009/153] Fix propagation of labels --- meeseeksdev/meeseeksbox/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 994f140..ced45cf 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -592,8 +592,8 @@ def keen_stats(): milestone_number = int(milestone_number) labels_names = [] try: - label_names = [l["name"] for l in pr_data["labels"]] - if not label_names and ("issue" in payload.keys()): + labels_names = [l["name"] for l in pr_data["labels"]] + if not labels_names and ("issue" in payload.keys()): labels_names = [l["name"] for l in payload["issue"]["labels"]] except KeyError: print("Did not find labels|", pr_data) From 6f6b02e18d656f78e3eaa9849d4f13cbd498a7be Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Wed, 28 Jul 2021 11:37:15 +0200 Subject: [PATCH 010/153] Workaround #50 we should likely look at repo base branch. For now hardcode both master and main. --- meeseeksdev/meeseeksbox/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index b3d098a..54ae60f 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -377,9 +377,9 @@ def dispatch_action(self, type_, payload): if milestone: description.append(milestone.get("description", "") or "") description = "\n".join(description) - if ( - "on-merge:" in description - and is_pr["base"]["ref"] == "master" + if "on-merge:" in description and is_pr["base"]["ref"] in ( + "master", + "main", ): did_backport = False for description_line in description.splitlines(): From d329d7d2f44f238d54015141f5555031d9facb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krassowski?= <5832902+krassowski@users.noreply.github.com> Date: Thu, 19 Aug 2021 11:12:56 +0100 Subject: [PATCH 011/153] Add a remainder about removing the label, add title to backported PR --- meeseeksdev/meeseeksbox/commands.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index ced45cf..bc84588 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -789,11 +789,13 @@ def keen_stats(): 5. Create a PR against branch {target_branch}, I would have named this PR: -> "Backport PR #{prnumber} on branch {target_branch}" +> "Backport PR #{prnumber} on branch {target_branch} ({prtitle})" And apply the correct labels and milestones. -Congratulation you did some good work ! Hopefully your backport PR will be tested by the continuous integration and merged soon! +Congratulation you did some good work! Hopefully your backport PR will be tested by the continuous integration and merged soon! + +Remember to remove `Still Needs Manual Backport` label once the PR gets merged. If these instruction are inaccurate, feel free to [suggest an improvement](https://github.com/MeeseeksBox/MeeseeksDev). """, From ac051e7ee76e16deec0423ac65f607a9f41e265a Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Fri, 27 Aug 2021 15:24:10 -0700 Subject: [PATCH 012/153] remove ununsed varaible slow down + create issues --- meeseeksdev/meeseeksbox/commands.py | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index bc84588..1b9a32b 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -155,7 +155,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("===== reformatting suggestions. =====") prnumber = payload["issue"]["number"] - prtitle = payload["issue"]["title"] + # prtitle = payload["issue"]["title"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] @@ -170,14 +170,14 @@ def black_suggest(*, session, payload, arguments, local_config=None): ) pr_data = r.json() head_sha = pr_data["head"]["sha"] - base_sha = pr_data["base"]["sha"] - branch = pr_data["head"]["ref"] - author_login = pr_data["head"]["repo"]["owner"]["login"] + # base_sha = pr_data["base"]["sha"] + # branch = pr_data["head"]["ref"] + # author_login = pr_data["head"]["repo"]["owner"]["login"] repo_name = pr_data["head"]["repo"]["name"] - commits_url = pr_data["commits_url"] + # commits_url = pr_data["commits_url"] - commits_data = session.ghrequest("GET", commits_url).json() + # commits_data = session.ghrequest("GET", commits_url).json() # that will likely fail, as if PR, we need to bypass the fact that the # requester has technically no access to committer repo. @@ -287,7 +287,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): } try: - resp = session.ghrequest( + _ = session.ghrequest( "POST", f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", json=data, @@ -307,13 +307,13 @@ def black_suggest(*, session, payload, arguments, local_config=None): } try: - resp = session.ghrequest( + _ = session.ghrequest( "POST", f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}/comments", json=data, ) except Exception: - # likely unprecessable entity out of range + # likely unprocessable entity out of range pass if os.path.exists(repo_name): print("== Cleaning up repo... ") @@ -327,7 +327,6 @@ def blackify(*, session, payload, arguments, local_config=None): print("===== ============ =====") # collect initial payload prnumber = payload["issue"]["number"] - prtitle = payload["issue"]["title"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] @@ -342,7 +341,6 @@ def blackify(*, session, payload, arguments, local_config=None): ) pr_data = r.json() head_sha = pr_data["head"]["sha"] - base_sha = pr_data["base"]["sha"] branch = pr_data["head"]["ref"] author_login = pr_data["head"]["repo"]["owner"]["login"] repo_name = pr_data["head"]["repo"]["name"] @@ -569,7 +567,6 @@ def keen_stats(): ) pr_data = r.json() merge_sha = pr_data["merge_commit_sha"] - body = pr_data["body"] milestone = pr_data["milestone"] if milestone: milestone_number = pr_data["milestone"].get("number", None) @@ -646,7 +643,7 @@ def keen_stats(): re_fetch_delta = time.time() - re_fetch_epoch print(blue + f"FF took {re_fetch_delta}s") s_ff_time = re_fetch_delta - except Exception as e: + except Exception: # something went wrong. Kill repository it's going to be # recloned. clean_epoch = time.time() @@ -706,12 +703,9 @@ def keen_stats(): print( "== Fetching Commits to {mergesha} backport...".format(mergesha=merge_sha) ) - repo.remotes.origin.fetch("{mergesha}".format(num=prnumber, mergesha=merge_sha)) + repo.remotes.origin.fetch("{mergesha}".format(mergesha=merge_sha)) print("== All has been fetched correctly") - # remove mentions from description, to avoid pings: - description = body.replace("@", " ").replace("#", " ") - print("Cherry-picking %s" % merge_sha) args = ("-m", "1", merge_sha) From 0aef35d272da98ebbe266d1831abf4f468eb0a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Robert?= Date: Sat, 6 Nov 2021 17:02:40 +0100 Subject: [PATCH 013/153] ENH: remove symbolic shell prompt ('$') from automated replies to make them copy-pastable directly from github to the command line --- meeseeksdev/meeseeksbox/commands.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 1b9a32b..c6d6bae 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -760,19 +760,19 @@ def keen_stats(): 1. Checkout backport branch and update it. ``` -$ git checkout {target_branch} -$ git pull +git checkout {target_branch} +git pull ``` 2. Cherry pick the first parent branch of the this PR on top of the older branch: ``` -$ git cherry-pick -m1 {merge_sha} +git cherry-pick -m1 {merge_sha} ``` 3. You will likely have some merge/cherry-pick conflict here, fix them and commit: ``` -$ git commit -am {msg!r} +git commit -am {msg!r} ``` 4. Push to a named branch : From 90b3373b1166e1ffe7a44decdc057d4547614cee Mon Sep 17 00:00:00 2001 From: Jason Weill <93281816+jweill-aws@users.noreply.github.com> Date: Mon, 15 Nov 2021 10:01:27 -0800 Subject: [PATCH 014/153] Copy edits --- meeseeksdev/meeseeksbox/commands.py | 64 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index c6d6bae..e9b1c23 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -192,16 +192,16 @@ def black_suggest(*, session, payload, arguments, local_config=None): ## comment_url = payload["issue"]["comments_url"] ## session.post_comment( ## comment_url, - ## body="Would you mind installing me on your fork so that I can update your branch ? \n" + ## body="Would you mind installing me on your fork so that I can update your branch? \n" ## "Click [here](https://github.com/apps/meeseeksdev/installations/new)" - ## "to do that, and follow the instruction to add your fork." + ## "to do that, and follow the instructions to add your fork." ## "I'm going to try to push as a maintainer but this may not work." ## ) # if not target_session: # comment_url = payload["issue"]["comments_url"] # session.post_comment( # comment_url, - # body="I'm afraid I can't do that. Maybe I need to be installed on target repository ?\n" + # body="I'm afraid I can't do that. Maybe I need to be installed on target repository?\n" # "Click [here](https://github.com/apps/meeseeksdev/installations/new) to do that.".format( # botname="meeseeksdev" # ), @@ -220,12 +220,12 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== PR contains", len(pr_files), "files") if os.path.exists(repo_name): - print("== Cleaning up previsous work... ") + print("== Cleaning up previous work ... ") subprocess.run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") print( - f"== Cloning repository from {org_name}/{repo_name}, this can take some time.." + f"== Cloning repository from {org_name}/{repo_name}, this can take some time ..." ) process = subprocess.run( [ @@ -247,12 +247,12 @@ def black_suggest(*, session, payload, arguments, local_config=None): # do the pep8ify on local filesystem repo = git.Repo(repo_name) # branch = master - # print(f"== Fetching branch `{branch}` ...") + # print(f"== Fetching branch `{branch}` ...") # repo.remotes.origin.fetch("{}:workbranch".format(branch)) # repo.git.checkout("workbranch") - print("== Fetching Commits to reformat...") + print("== Fetching Commits to reformat ...") repo.remotes.origin.fetch("{head_sha}".format(head_sha=head_sha)) - print("== All has been fetched correctly") + print("== All have been fetched correctly") repo.git.checkout(head_sha) print(f"== checked PR head {head_sha}") @@ -374,16 +374,16 @@ def blackify(*, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] session.post_comment( comment_url, - body="Would you mind installing me on your fork so that I can update your branch ? \n" + body="Would you mind installing me on your fork so that I can update your branch? \n" "Click [here](https://github.com/apps/meeseeksdev/installations/new)" - "to do that, and follow the instruction to add your fork." + "to do that, and follow the instructions to add your fork." "I'm going to try to push as a maintainer but this may not work.", ) # if not target_session: # comment_url = payload["issue"]["comments_url"] # session.post_comment( # comment_url, - # body="I'm afraid I can't do that. Maybe I need to be installed on target repository ?\n" + # body="I'm afraid I can't do that. Maybe I need to be installed on target repository?\n" # "Click [here](https://github.com/apps/meeseeksdev/installations/new) to do that.".format( # botname="meeseeksdev" # ), @@ -394,12 +394,12 @@ def blackify(*, session, payload, arguments, local_config=None): # this process can take some time, regen token if os.path.exists(repo_name): - print("== Cleaning up previsous work... ") + print("== Cleaning up previsous work ... ") subprocess.run("rm -rf {}".format(repo_name).split(" "), check=True) print("== Done cleaning ") print( - f"== Cloning repository from {author_login}/{repo_name}, this can take some time.." + f"== Cloning repository from {author_login}/{repo_name}, this can take some time ..." ) process = subprocess.run( [ @@ -423,9 +423,9 @@ def blackify(*, session, payload, arguments, local_config=None): print(f"== Fetching branch `{branch}` to pep8ify on ...") repo.remotes.origin.fetch("{}:workbranch".format(branch)) repo.git.checkout("workbranch") - print("== Fetching Commits to pep8ify...") + print("== Fetching Commits to pep8ify ...") repo.remotes.origin.fetch("{head_sha}".format(head_sha=head_sha)) - print("== All has been fetched correctly") + print("== All have been fetched correctly") os.chdir(repo_name) @@ -557,7 +557,7 @@ def keen_stats(): try: # collect extended payload on the PR - print("== Collecting data on Pull-request...") + print("== Collecting data on Pull-request ...") r = session.ghrequest( "GET", "https://api.github.com/repos/{}/{}/pulls/{}".format( @@ -581,7 +581,7 @@ def keen_stats(): parts = milestone_title.split(".") parts[-1] = "x" infered_target_branch = ".".join(parts) - print("inferring branch....", infered_target_branch) + print("inferring branch ...", infered_target_branch) target_branch = infered_target_branch keen.add_event("backport_infering_branch", {"infering_remove_x": 1}) @@ -648,7 +648,7 @@ def keen_stats(): # recloned. clean_epoch = time.time() if os.path.exists(repo_name): - print("== Cleaning up previsous work... ") + print("== Cleaning up previous work... ") subprocess.run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") s_clean_time = time.time() - clean_epoch @@ -682,8 +682,8 @@ def keen_stats(): "git", "remote", action, - session.personnal_account_name, - f"https://x-access-token:{session.personnal_account_token}@github.com/{session.personnal_account_name}/{repo_name}", + session.personal_account_name, + f"https://x-access-token:{session.personal_account_token}@github.com/{session.personal_account_name}/{repo_name}", ], cwd=repo_name, ) @@ -775,7 +775,7 @@ def keen_stats(): git commit -am {msg!r} ``` -4. Push to a named branch : +4. Push to a named branch: ``` git push YOURFORK {target_branch}:{remote_submit_branch} @@ -787,11 +787,11 @@ def keen_stats(): And apply the correct labels and milestones. -Congratulation you did some good work! Hopefully your backport PR will be tested by the continuous integration and merged soon! +Congratulations — you did some good work! Hopefully your backport PR will be tested by the continuous integration and merged soon! -Remember to remove `Still Needs Manual Backport` label once the PR gets merged. +Remember to remove the `Still Needs Manual Backport` label once the PR gets merged. -If these instruction are inaccurate, feel free to [suggest an improvement](https://github.com/MeeseeksBox/MeeseeksDev). +If these instructions are inaccurate, feel free to [suggest an improvement](https://github.com/MeeseeksBox/MeeseeksDev). """, ) org = payload["repository"]["owner"]["login"] @@ -809,7 +809,7 @@ def keen_stats(): else: session.post_comment( comment_url, - "Oops, something went wrong applying the patch... Please have a look at my logs.", + "Oops, something went wrong applying the patch ... Please have a look at my logs.", ) print(e.stderr) print("----") @@ -842,9 +842,9 @@ def keen_stats(): print("== Pushing work....:") try: print( - f"Tryign to push to {remote_submit_branch} of {session.personnal_account_name}" + f"Tryign to push to {remote_submit_branch} of {session.personal_account_name}" ) - repo.remotes[session.personnal_account_name].push( + repo.remotes[session.personal_account_name].push( "workbranch:{}".format(remote_submit_branch) ) except Exception as e: @@ -875,7 +875,7 @@ def keen_stats(): "title": f"Backport PR #{prnumber} on branch {target_branch} ({prtitle})", "body": msg, "head": "{}:{}".format( - session.personnal_account_name, remote_submit_branch + session.personal_account_name, remote_submit_branch ), "base": target_branch, }, @@ -893,15 +893,15 @@ def keen_stats(): except Exception as e: extra_info = "" if maybe_wrong_named_branch: - extra_info = "\n\n It seem that the branch you are trying to backport to does not exists." + extra_info = "\n\n It seems that the branch you are trying to backport to does not exist." session.post_comment( comment_url, - "Something went wrong ... Please have a look at my logs." + extra_info, + "Something went wrong ... Please have a look at my logs." + extra_info, ) keen.add_event("error", {"unknown_crash": 1}) print("Something went wrong") print(e) - s_reason = "Remote branches does not exists" + s_reason = "Remote branch does not exist" keen_stats() raise @@ -1011,7 +1011,7 @@ def get_next_link(req): comment_url, f"Aww {user}, I was not able to apply the following label(s): `{lf}`. Either " "because they are not existing labels on this repository or because you do not have the permission to apply these." - "I tried my best to guess by looking at the casing, but was unable to find matching labels.", + "I tried my best to guess by looking at the casing, but I was unable to find matching labels.", ) From 47be66b7e658add7e674e13032693278d3d4a222 Mon Sep 17 00:00:00 2001 From: Jason Weill Date: Mon, 15 Nov 2021 10:03:10 -0800 Subject: [PATCH 015/153] Fix typo of "personnal" to "personal" --- meeseeksdev/__init__.py | 4 ++-- meeseeksdev/meeseeksbox/core.py | 8 ++++---- meeseeksdev/meeseeksbox/utils.py | 18 +++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 5c1d5db..b7caa5b 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -99,8 +99,8 @@ def load_config_from_env(): # for some functionalities of mr-meeseeks. Indeed, github does not allow # cross repositories pull-requests with Applications, so I use a personal # account just for that. - config["personnal_account_name"] = os.environ.get("PERSONAL_ACCOUNT_NAME") - config["personnal_account_token"] = os.environ.get("PERSONAL_ACCOUNT_TOKEN") + config["personal_account_name"] = os.environ.get("PERSONAL_ACCOUNT_NAME") + config["personal_account_token"] = os.environ.get("PERSONAL_ACCOUNT_TOKEN") return Config(**config).validate() diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 54ae60f..7398883 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -41,8 +41,8 @@ class Config: at_botname = None integration_id = None webhook_secret = None - personnal_account_name = None - personnal_account_token = None + personal_account_name = None + personal_account_token = None def __init__(self, **kwargs): self.__dict__.update(kwargs) @@ -665,8 +665,8 @@ def __init__(self, commands, config): self.auth = Authenticator( self.config.integration_id, self.config.key, - self.config.personnal_account_token, - self.config.personnal_account_name, + self.config.personal_account_token, + self.config.personal_account_name, ) self.auth._build_auth_id_mapping() diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 12c30bf..a6d2cb5 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -80,15 +80,15 @@ def fix_comment_body(body, original_poster, original_url, original_org, original class Authenticator: def __init__( - self, integration_id, rsadata, personnal_account_token, personnal_account_name + self, integration_id, rsadata, personal_account_token, personal_account_name ): self.since = int(datetime.datetime.now().timestamp()) self.duration = 60 * 10 self._token = None self.integration_id = integration_id self.rsadata = rsadata - self.personnal_account_token = personnal_account_token - self.personnal_account_name = personnal_account_name + self.personal_account_token = personal_account_token + self.personal_account_name = personal_account_name # TODO: this mapping is built at startup, we should update it when we # have new / deleted installations self.idmap = {} @@ -104,8 +104,8 @@ def session(self, installation_id): self.integration_id, self.rsadata, installation_id, - self.personnal_account_token, - self.personnal_account_name, + self.personal_account_token, + self.personal_account_name, ) def list_installations(self): @@ -173,11 +173,11 @@ def __init__( integration_id, rsadata, installation_id, - personnal_account_token, - personnal_account_name, + personal_account_token, + personal_account_name, ): super().__init__( - integration_id, rsadata, personnal_account_token, personnal_account_name + integration_id, rsadata, personal_account_token, personal_account_name ) self.installation_id = installation_id @@ -205,7 +205,7 @@ def personal_request(self, method, url, json=None, raise_for_status=True): def prepare(): headers = { - "Authorization": "token {}".format(self.personnal_account_token), + "Authorization": "token {}".format(self.personal_account_token), "Host": "api.github.com", "User-Agent": "python/requests", } From bbb3231b8b93689b261b7d899b7f035028d6d080 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:05:56 +0100 Subject: [PATCH 016/153] try to skip disable installations --- meeseeksdev/meeseeksbox/utils.py | 52 +++++++++++++++++++------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index a6d2cb5..6a3a031 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -17,6 +17,7 @@ API_COLLABORATORS_TEMPLATE = ( "https://api.github.com/repos/{org}/{repo}/collaborators/{username}/permission" ) +ACCEPT_HEADER_V3 = "application/vnd.github.v3+json" ACCEPT_HEADER = "application/vnd.github.machine-man-preview" ACCEPT_HEADER_KORA = "json,application/vnd.github.korra-preview" ACCEPT_HEADER_SYMMETRA = "application/vnd.github.symmetra-preview+json" @@ -40,7 +41,7 @@ def fix_issue_body( ): """ This, for now does only simple fixes, like link to the original issue. - + This should be improved to quote mention of people """ @@ -48,24 +49,21 @@ def fix_issue_body( "{org}/{repo}\\1".format(org=original_org, repo=original_repo), body ) - return ( - body - + """\n\n---- + return body + """\n\n---- \nOriginally opened as {org}/{repo}#{number} by @{reporter}, migration requested by @{requester} """.format( - org=original_org, - repo=original_repo, - number=original_number, - reporter=original_poster, - requester=migration_requester, - ) + org=original_org, + repo=original_repo, + number=original_number, + reporter=original_poster, + requester=migration_requester, ) def fix_comment_body(body, original_poster, original_url, original_org, original_repo): """ This, for now does only simple fixes, like link to the original comment. - + This should be improved to quote mention of people """ @@ -137,11 +135,15 @@ def _build_auth_id_mapping(self): for installation in installations: iid = installation["id"] session = self.session(iid) - repositories = session.ghrequest( - "GET", installation["repositories_url"], json=None - ).json() - for repo in repositories["repositories"]: - self.idmap[repo["full_name"]] = iid + try: + repositories = session.ghrequest( + "GET", installation["repositories_url"], json=None + ).json() + for repo in repositories["repositories"]: + self.idmap[repo["full_name"]] = iid + except Forbidden: + print("Forbidden for", iid) + continue def _integration_authenticated_request(self, method, url): self.since = int(datetime.datetime.now().timestamp()) @@ -157,7 +159,7 @@ def _integration_authenticated_request(self, method, url): headers = { "Authorization": "Bearer {}".format(tok.decode()), - "Accept": ACCEPT_HEADER, + "Accept": ACCEPT_HEADER_V3, "Host": "api.github.com", "User-Agent": "python/requests", } @@ -167,6 +169,10 @@ def _integration_authenticated_request(self, method, url): return s.send(prepared) +class Forbidden(Exception): + pass + + class Session(Authenticator): def __init__( self, @@ -191,6 +197,9 @@ def regen_token(self): method = "POST" url = f"https://api.github.com/app/installations/{self.installation_id}/access_tokens" resp = self._integration_authenticated_request(method, url) + if resp.status_code == 403: + raise Forbidden(installation_id) + try: self._token = json.loads(resp.content.decode())["token"] except: @@ -294,8 +303,7 @@ def _get_permission(self, org, repo, username): return getattr(Permission, permission) def has_permission(self, org, repo, username, level=None): - """ - """ + """ """ if not level: level = Permission.none @@ -305,8 +313,10 @@ def post_comment(self, comment_url, body): self.ghrequest("POST", comment_url, json={"body": body}) def get_collaborator_list(self, org, repo): - get_collaborators_query = "https://api.github.com/repos/{org}/{repo}/collaborators".format( - org=org, repo=repo + get_collaborators_query = ( + "https://api.github.com/repos/{org}/{repo}/collaborators".format( + org=org, repo=repo + ) ) resp = self.ghrequest("GET", get_collaborators_query, None) if resp.status_code == 200: From a0f3df90ad1906cae7cd06a9127606b5a1af4d05 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:07:24 +0100 Subject: [PATCH 017/153] typo --- meeseeksdev/meeseeksbox/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 6a3a031..711c986 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -198,7 +198,7 @@ def regen_token(self): url = f"https://api.github.com/app/installations/{self.installation_id}/access_tokens" resp = self._integration_authenticated_request(method, url) if resp.status_code == 403: - raise Forbidden(installation_id) + raise Forbidden(self.installation_id) try: self._token = json.loads(resp.content.decode())["token"] From 96a7376deec4a2c1b8e3f3196caa20f8a585a869 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:08:11 +0100 Subject: [PATCH 018/153] bump pyml --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 34310ed..2efa7ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,5 @@ mock==3.0.5 cryptography==2.8 yieldbreaker==0.0.1 black -pyyaml==5.3 +pyyaml==5.4.1 keen From 10ed1b8bde92420642e0b4b8406e25c383a94733 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:22:42 +0100 Subject: [PATCH 019/153] requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 2efa7ab..d06e2ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,5 @@ cryptography==2.8 yieldbreaker==0.0.1 black pyyaml==5.4.1 +gitdb2-2.0.6 keen From 1d05da858a16075c58d9457978924aa046a32b80 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:25:54 +0100 Subject: [PATCH 020/153] == --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d06e2ae..9721439 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,5 +8,5 @@ cryptography==2.8 yieldbreaker==0.0.1 black pyyaml==5.4.1 -gitdb2-2.0.6 +gitdb2==2.0.6 keen From 60a5d93d78f56d1bda2180c71daa9b72e78dd919 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:27:35 +0100 Subject: [PATCH 021/153] runtime --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 6f651a3..f72c511 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.7.3 +python-3.9.0 From 5ab4f7320e5bd9233185f7599e241dc46ade28ae Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 20 Mar 2022 10:29:59 +0100 Subject: [PATCH 022/153] pin gitdb --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 9721439..01b068c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,5 @@ yieldbreaker==0.0.1 black pyyaml==5.4.1 gitdb2==2.0.6 +gitdb==0.6.4 keen From 9418663d0b4290c7d8f213950aa0620d44081d83 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 04:57:11 -0500 Subject: [PATCH 023/153] add pre-commit command --- meeseeksdev/__init__.py | 2 + meeseeksdev/meeseeksbox/commands.py | 70 +++++++++++++++-------------- requirements.txt | 1 + 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index b7caa5b..1a45623 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -114,6 +114,7 @@ def load_config_from_env(): untag, blackify, black_suggest, + precommit, quote, say, debug, @@ -162,6 +163,7 @@ def main(): "reformat": blackify, "black": blackify, "suggestions": black_suggest, + "precommit": precommit, "ready": ready, "merge": merge, "say": say, diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index e9b1c23..a0c446a 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -321,14 +321,15 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Done cleaning ") -@admin -def blackify(*, session, payload, arguments, local_config=None): - print("===== reformatting =====") + +def run_command_and_push(name, command, session, paylog, arguments, local_config=None): + print(f"===== running command {name} =====") print("===== ============ =====") # collect initial payload prnumber = payload["issue"]["number"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] + comment_url = payload["issue"]["comments_url"] # collect extended payload on the PR print("== Collecting data on Pull-request...") @@ -351,7 +352,6 @@ def blackify(*, session, payload, arguments, local_config=None): for commit in commits_data: if len(commit["parents"]) != 1: - comment_url = payload["issue"]["comments_url"] session.post_comment( comment_url, body="It looks like the history is not linear in this pull-request. I'm afraid I can't rebase.\n", @@ -379,22 +379,9 @@ def blackify(*, session, payload, arguments, local_config=None): "to do that, and follow the instructions to add your fork." "I'm going to try to push as a maintainer but this may not work.", ) - # if not target_session: - # comment_url = payload["issue"]["comments_url"] - # session.post_comment( - # comment_url, - # body="I'm afraid I can't do that. Maybe I need to be installed on target repository?\n" - # "Click [here](https://github.com/apps/meeseeksdev/installations/new) to do that.".format( - # botname="meeseeksdev" - # ), - # ) - # return - - # clone locally - # this process can take some time, regen token if os.path.exists(repo_name): - print("== Cleaning up previsous work ... ") + print("== Cleaning up previous work ... ") subprocess.run("rm -rf {}".format(repo_name).split(" "), check=True) print("== Done cleaning ") @@ -418,12 +405,12 @@ def blackify(*, session, payload, arguments, local_config=None): ) subprocess.run("git config --global user.name FriendlyBot".split(" ")) - # do the pep8ify on local filesystem + # do the command on local filesystem repo = git.Repo(repo_name) - print(f"== Fetching branch `{branch}` to pep8ify on ...") + print(f"== Fetching branch `{branch}` to run {name} on ...") repo.remotes.origin.fetch("{}:workbranch".format(branch)) repo.git.checkout("workbranch") - print("== Fetching Commits to pep8ify ...") + print(f"== Fetching Commits to run {name} on ...") repo.remotes.origin.fetch("{head_sha}".format(head_sha=head_sha)) print("== All have been fetched correctly") @@ -433,46 +420,61 @@ def lpr(*args): print("Should run:", *args) lpr( - 'git rebase -x "black --fast . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', + f'git rebase -x "{command} . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', to_rebase_on, ) - ## todo check error code. - subprocess.run( + process = subprocess.run( [ "git", "rebase", "-x", - "black --fast . && git commit -a --amend --no-edit", + f"{command} . && git commit -a --amend --no-edit", "--strategy-option=theirs", "--autosquash", to_rebase_on, ] ) - # write the commit message - # msg = "Autofix pep 8 of #%i: %s" % (prnumber, prtitle) + "\n\n" - # repo.git.commit("-am", msg) - # Push the pep8ify work + if process.returncode != 0: + session.post_comment( + comment_url, + body=dedent( + f""" + I was unable to run "{name}" due to an error. + """ + ), + ) + return + + # Push the work print("== Pushing work....:") lpr(f"pushing with workbranch:{branch}") repo.remotes.origin.push("workbranch:{}".format(branch), force=True) repo.git.checkout(default_branch) repo.branches.workbranch.delete(repo, "workbranch", force=True) - comment_url = payload["issue"]["comments_url"] session.post_comment( comment_url, body=dedent( - """ - I've rebased this Pull Request, applied `black` on all the + f""" + I've rebased this Pull Request, applied {name} on all the individual commits, and pushed. You may have trouble pushing further - commits, but feel free to force push and ask me to reformat again. + commits, but feel free to force push and ask me to reformat again. """ ), ) - # os.chdir("..") + + +@admin +def precommit(*, session, payload, arguments, local_config=None): + run_command_and_push("pre-commit", "pre-commit --all-files --hook-stage=manual") + + +@admin +def blackify(*, session, payload, arguments, local_config=None): + run_command_and_push("black", "black --fast .") @write diff --git a/requirements.txt b/requirements.txt index 01b068c..fb6b34e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ pyyaml==5.4.1 gitdb2==2.0.6 gitdb==0.6.4 keen +pre-commit From 71135fbc71218afc6f3b074c891d304a5a4d20c7 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 05:16:36 -0500 Subject: [PATCH 024/153] cleanup --- meeseeksdev/meeseeksbox/commands.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index a0c446a..f07e2e1 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -321,8 +321,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Done cleaning ") - -def run_command_and_push(name, command, session, paylog, arguments, local_config=None): +def run_command_and_push(name, command, session, payload, arguments, local_config=None): print(f"===== running command {name} =====") print("===== ============ =====") # collect initial payload @@ -330,6 +329,15 @@ def run_command_and_push(name, command, session, paylog, arguments, local_config org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] comment_url = payload["issue"]["comments_url"] + author_association = payload["issue"]["comment"]["author_association"] + commenter = payload["issue"]["comment"]["user"]["login"] + + # Check if maintainer + if author_association not in ["COLLABORATOR", "MEMBER", "OWNER"]: + session.post_comment( + comment_url, + body=f"Cannot run this command on behalf of {commenter} with association {author_association}.", + ) # collect extended payload on the PR print("== Collecting data on Pull-request...") @@ -363,7 +371,6 @@ def run_command_and_push(name, command, session, paylog, arguments, local_config # that will likely fail, as if PR, we need to bypass the fact that the # requester has technically no access to committer repo. - # TODO, check if maintainer target_session = yield "{}/{}".format(author_login, repo_name) if target_session: print("installed on target repository") @@ -371,7 +378,6 @@ def run_command_and_push(name, command, session, paylog, arguments, local_config else: print("use allow edit as maintainer") atk = session.token() - comment_url = payload["issue"]["comments_url"] session.post_comment( comment_url, body="Would you mind installing me on your fork so that I can update your branch? \n" @@ -436,7 +442,6 @@ def lpr(*args): ] ) - if process.returncode != 0: session.post_comment( comment_url, @@ -452,9 +457,15 @@ def lpr(*args): print("== Pushing work....:") lpr(f"pushing with workbranch:{branch}") repo.remotes.origin.push("workbranch:{}".format(branch), force=True) + + # Clean up + default_branch = session.ghrequest( + "GET", f"https://api.github.com/repos/{org_name}/{repo_name}" + ).json()["default_branch"] repo.git.checkout(default_branch) repo.branches.workbranch.delete(repo, "workbranch", force=True) + # Tell the caller we've finished session.post_comment( comment_url, body=dedent( @@ -469,7 +480,7 @@ def lpr(*args): @admin def precommit(*, session, payload, arguments, local_config=None): - run_command_and_push("pre-commit", "pre-commit --all-files --hook-stage=manual") + run_command_and_push("pre-commit", "pre-commit run --all-files --hook-stage=manual") @admin From 059c61bc78316f79e183d64ad158020a8c42b5ae Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 05:25:04 -0500 Subject: [PATCH 025/153] cleanup --- meeseeksdev/meeseeksbox/commands.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index f07e2e1..061136b 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -325,6 +325,7 @@ def run_command_and_push(name, command, session, payload, arguments, local_confi print(f"===== running command {name} =====") print("===== ============ =====") # collect initial payload + # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#issue_comment prnumber = payload["issue"]["number"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] @@ -480,12 +481,17 @@ def lpr(*args): @admin def precommit(*, session, payload, arguments, local_config=None): - run_command_and_push("pre-commit", "pre-commit run --all-files --hook-stage=manual") + cmd = "pre-commit run --all-files --hook-stage=manual" + try: + run_command_and_push("pre-commit", cmd, session, payload, arguments, local_config=local_config) + finally: + # Remove the installed pre-commit files + subprocess.run(["pre-commit run clean"]) @admin def blackify(*, session, payload, arguments, local_config=None): - run_command_and_push("black", "black --fast .") + run_command_and_push("black", "black --fast .", session, payload, arguments, local_config=local_config) @write From 3475c8ba3bc49d827934cfe13d7ef5fea06ca7fc Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 06:11:13 -0500 Subject: [PATCH 026/153] refactor --- meeseeksdev/meeseeksbox/commands.py | 160 +++++++++++++++++++--------- 1 file changed, 112 insertions(+), 48 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 061136b..4798fd4 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -321,7 +321,11 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Done cleaning ") -def run_command_and_push(name, command, session, payload, arguments, local_config=None): +def lpr(*args): + print("Should run:", *args) + + +def prep_for_command(name, session, payload, arguments, local_config=None): print(f"===== running command {name} =====") print("===== ============ =====") # collect initial payload @@ -355,21 +359,6 @@ def run_command_and_push(name, command, session, payload, arguments, local_confi author_login = pr_data["head"]["repo"]["owner"]["login"] repo_name = pr_data["head"]["repo"]["name"] - commits_url = pr_data["commits_url"] - - commits_data = session.ghrequest("GET", commits_url).json() - - for commit in commits_data: - if len(commit["parents"]) != 1: - session.post_comment( - comment_url, - body="It looks like the history is not linear in this pull-request. I'm afraid I can't rebase.\n", - ) - return - - # so far we assume that the commit we rebase on is the first. - to_rebase_on = commits_data[0]["parents"][0]["sha"] - # that will likely fail, as if PR, we need to bypass the fact that the # requester has technically no access to committer repo. target_session = yield "{}/{}".format(author_login, repo_name) @@ -423,11 +412,111 @@ def run_command_and_push(name, command, session, payload, arguments, local_confi os.chdir(repo_name) - def lpr(*args): - print("Should run:", *args) + +def push_the_work(session, payload, arguments, local_config=None): + prnumber = payload["issue"]["number"] + org_name = payload["repository"]["owner"]["login"] + repo_name = payload["repository"]["name"] + + # collect extended payload on the PR + print("== Collecting data on Pull-request...") + r = session.ghrequest( + "GET", + "https://api.github.com/repos/{}/{}/pulls/{}".format( + org_name, repo_name, prnumber + ), + json=None, + ) + pr_data = r.json() + branch = pr_data["head"]["ref"] + repo_name = pr_data["head"]["repo"]["name"] + repo = git.Repo(repo_name) + + # Push the work + print("== Pushing work....:") + lpr(f"pushing with workbranch:{branch}") + repo.remotes.origin.push("workbranch:{}".format(branch), force=True) + + # Clean up + default_branch = session.ghrequest( + "GET", f"https://api.github.com/repos/{org_name}/{repo_name}" + ).json()["default_branch"] + repo.git.checkout(default_branch) + repo.branches.workbranch.delete(repo, "workbranch", force=True) + + +@admin +def precommit(*, session, payload, arguments, local_config=None): + prep_for_command("precommit", session, payload, arguments, local_config=local_config) + + cmd = "pre-commit run --all-files --hook-stage=manual" + + lpr(cmd) + process = subprocess.run(cmd) + + # See if the pre-commit failed. + if process.returncode != 0: + # Add any changed files, and try again. + subprocess.run('git add .') + process = subprocess.run(cmd) + + # If that fails, then we can't auto-fix. + if process.returncode != 0: + # Clean up the pre-commit files + subprocess.run(["pre-commit run clean"]) + + # Alert the caller and bail. + comment_url = payload["issue"]["comments_url"] + session.post_comment( + comment_url, + body=dedent( + f""" + I was unable to run "pre-commit" due to an error, changes must be made manually. + """ + ), + ) + return + + # Clean up the pre-commit files. + subprocess.run(["pre-commit run clean"]) + + push_the_work(session, payload, arguments, local_config=local_config) + + # Tell the caller we've finished + comment_url = payload["issue"]["comments_url"] + session.post_comment( + comment_url, + body=dedent( + f""" + I've applied "pre-commit" and pushed. You may have trouble pushing further + commits, but feel free to force push and ask me to run again. + """ + ), + ) + + +@admin +def blackify(*, session, payload, arguments, local_config=None): + + prep_for_command("blackify", session, payload, arguments, local_config=local_config) + + comment_url = payload["issue"]["comments_url"] + commits_url = payload["repository"]["commits_url"] + commits_data = session.ghrequest("GET", commits_url).json() + + for commit in commits_data: + if len(commit["parents"]) != 1: + session.post_comment( + comment_url, + body="It looks like the history is not linear in this pull-request. I'm afraid I can't rebase.\n", + ) + return + + # so far we assume that the commit we rebase on is the first. + to_rebase_on = commits_data[0]["parents"][0]["sha"] lpr( - f'git rebase -x "{command} . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', + f'git rebase -x "black --fast . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', to_rebase_on, ) @@ -436,7 +525,7 @@ def lpr(*args): "git", "rebase", "-x", - f"{command} . && git commit -a --amend --no-edit", + f"black --fast . && git commit -a --amend --no-edit", "--strategy-option=theirs", "--autosquash", to_rebase_on, @@ -448,30 +537,20 @@ def lpr(*args): comment_url, body=dedent( f""" - I was unable to run "{name}" due to an error. + I was unable to run "blackify" due to an error. """ ), ) return - # Push the work - print("== Pushing work....:") - lpr(f"pushing with workbranch:{branch}") - repo.remotes.origin.push("workbranch:{}".format(branch), force=True) - - # Clean up - default_branch = session.ghrequest( - "GET", f"https://api.github.com/repos/{org_name}/{repo_name}" - ).json()["default_branch"] - repo.git.checkout(default_branch) - repo.branches.workbranch.delete(repo, "workbranch", force=True) + push_the_work(session, payload, arguments, local_config=local_config) # Tell the caller we've finished session.post_comment( comment_url, body=dedent( f""" - I've rebased this Pull Request, applied {name} on all the + I've rebased this Pull Request, applied `blackify` on all the individual commits, and pushed. You may have trouble pushing further commits, but feel free to force push and ask me to reformat again. """ @@ -479,21 +558,6 @@ def lpr(*args): ) -@admin -def precommit(*, session, payload, arguments, local_config=None): - cmd = "pre-commit run --all-files --hook-stage=manual" - try: - run_command_and_push("pre-commit", cmd, session, payload, arguments, local_config=local_config) - finally: - # Remove the installed pre-commit files - subprocess.run(["pre-commit run clean"]) - - -@admin -def blackify(*, session, payload, arguments, local_config=None): - run_command_and_push("black", "black --fast .", session, payload, arguments, local_config=local_config) - - @write def safe_backport(session, payload, arguments, local_config=None): """[to] {branch}""" From 9644db4aceb6b2ef7623c9b8db1164bf6d01a46e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 06:17:17 -0500 Subject: [PATCH 027/153] cleanup --- meeseeksdev/meeseeksbox/commands.py | 68 ++++++++++++++++------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 4798fd4..a858b47 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -334,15 +334,6 @@ def prep_for_command(name, session, payload, arguments, local_config=None): org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] comment_url = payload["issue"]["comments_url"] - author_association = payload["issue"]["comment"]["author_association"] - commenter = payload["issue"]["comment"]["user"]["login"] - - # Check if maintainer - if author_association not in ["COLLABORATOR", "MEMBER", "OWNER"]: - session.post_comment( - comment_url, - body=f"Cannot run this command on behalf of {commenter} with association {author_association}.", - ) # collect extended payload on the PR print("== Collecting data on Pull-request...") @@ -450,34 +441,51 @@ def precommit(*, session, payload, arguments, local_config=None): prep_for_command("precommit", session, payload, arguments, local_config=local_config) cmd = "pre-commit run --all-files --hook-stage=manual" + comment_url = payload["issue"]["comments_url"] + # Run the command lpr(cmd) process = subprocess.run(cmd) - # See if the pre-commit failed. - if process.returncode != 0: - # Add any changed files, and try again. - subprocess.run('git add .') - process = subprocess.run(cmd) + # See if the pre-commit succeeded, meaning there was nothing to do + if process.returncode == 0: + # Clean up the pre-commit files + subprocess.run(["pre-commit run clean"]) - # If that fails, then we can't auto-fix. - if process.returncode != 0: - # Clean up the pre-commit files - subprocess.run(["pre-commit run clean"]) + # Alert the caller and bail. + session.post_comment( + comment_url, + body=dedent( + f""" + I was unable to run "pre-commit" because there was nothing to do. + """ + ), + ) + return - # Alert the caller and bail. - comment_url = payload["issue"]["comments_url"] - session.post_comment( - comment_url, - body=dedent( - f""" - I was unable to run "pre-commit" due to an error, changes must be made manually. - """ - ), - ) - return + # Add any changed files. + subprocess.run('git commit -a -m "Apply pre-commit"') + + # Run again to see if we've auto-fixed + process = subprocess.run(cmd) + + # If that fails, then we can't auto-fix + if process.returncode != 0: + # Clean up the pre-commit files + subprocess.run(["pre-commit run clean"]) + + # Alert the caller and bail. + session.post_comment( + comment_url, + body=dedent( + f""" + I was unable to run "pre-commit" due to an error, changes must be made manually. + """ + ), + ) + return - # Clean up the pre-commit files. + # Clean up the pre-commit files subprocess.run(["pre-commit run clean"]) push_the_work(session, payload, arguments, local_config=local_config) From bd2b91a5b570db72146b8305f1e2236e56caed5b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 06:22:42 -0500 Subject: [PATCH 028/153] cleanup --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index a858b47..3b0cd19 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -558,7 +558,7 @@ def blackify(*, session, payload, arguments, local_config=None): comment_url, body=dedent( f""" - I've rebased this Pull Request, applied `blackify` on all the + I've rebased this Pull Request, applied `black` on all the individual commits, and pushed. You may have trouble pushing further commits, but feel free to force push and ask me to reformat again. """ From cccb92a955aec44fd6849c4bfdea9a9933c2073f Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:06:58 -0500 Subject: [PATCH 029/153] update runtime --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index f72c511..30e81e3 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.9.0 +python-3.10.3 From dcd09dd272ddf76bcc1e1cc902d0afaf7e5b52bd Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:09:27 -0500 Subject: [PATCH 030/153] wip --- CONTRIBUTING.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 2 files changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..dd03bc0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contributing + +## Test Deployment + +- Install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli#download-and-install). + +You will need to have an account in both Heroku. + +Log in to Heroku: + +```bash +heroku login +``` + +If creating, run: + +```bash +heroku create meeseeksdev +``` + +Otherwise, run: + +```bash +heroku git:remote -a meeseeksdev +``` + +Then run: + +``` +git push heroku $(git rev-parse --abbrev-ref HEAD):master +heroku open +``` + +Browse to `/hooks/github` and verify page render. + +### Heroku Configuration + +You will need a Github token with access to cancel builds. This + +This needs to be setup on the [Heroku Application settings](https://dashboard.heroku.com/apps/jupyterlab-bot/settings) + +On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of the generated token. + +GITHUB_INTEGRATION_ID +B64KEY +GITHUB_BOT_NAME +WEBHOOK_SECRET +PERSONAL_ACCOUNT_NAME +PERSONAL_ACCOUNT_TOKEN diff --git a/requirements.txt b/requirements.txt index fb6b34e..0965533 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ tornado==6.0.3 requests==2.23.0 pyjwt==1.7.1 gitpython==2.1.12 +gitdb2==2.0.6 there==0.0.9 mock==3.0.5 cryptography==2.8 From 7fef64c2c44a74549a90e8ed62839d00cdd02f07 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:11:47 -0500 Subject: [PATCH 031/153] try another thing --- CONTRIBUTING.md | 4 ++-- requirements.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd03bc0..aba1399 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,13 +15,13 @@ heroku login If creating, run: ```bash -heroku create meeseeksdev +heroku create meeseeksdev-$USER ``` Otherwise, run: ```bash -heroku git:remote -a meeseeksdev +heroku git:remote -a meeseeksdev-$USER ``` Then run: diff --git a/requirements.txt b/requirements.txt index 0965533..1b86f20 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ tornado==6.0.3 requests==2.23.0 pyjwt==1.7.1 gitpython==2.1.12 -gitdb2==2.0.6 +gitdb2==3.0.1 there==0.0.9 mock==3.0.5 cryptography==2.8 From b5315ad4d2b8f756e86da07afef0523ec7eaee02 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:15:42 -0500 Subject: [PATCH 032/153] update reqs --- requirements.txt | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/requirements.txt b/requirements.txt index 1b86f20..3dc7a4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,14 @@ -tornado==6.0.3 -requests==2.23.0 -pyjwt==1.7.1 -gitpython==2.1.12 -gitdb2==3.0.1 +tornado==6.1 +requests==2.27 +pyjwt==2.3 +gitpython==3.1 there==0.0.9 -mock==3.0.5 -cryptography==2.8 +mock==4.0 +cryptography==36.0 yieldbreaker==0.0.1 -black -pyyaml==5.4.1 +black==2.21 +pyyaml==6.0 +keen==0.7 gitdb2==2.0.6 gitdb==0.6.4 -keen -pre-commit +pre-commit==2.17 From faa4b01af9becf318810a63fae9bcd837b203ff1 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:16:35 -0500 Subject: [PATCH 033/153] update reqs --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3dc7a4c..475c2fc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ there==0.0.9 mock==4.0 cryptography==36.0 yieldbreaker==0.0.1 -black==2.21 +black==22.1 pyyaml==6.0 keen==0.7 gitdb2==2.0.6 From 041b30825969269a652b881b483c09292252dc9d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:31:17 -0500 Subject: [PATCH 034/153] make keen optional --- CONTRIBUTING.md | 12 ++++++------ meeseeksdev/__init__.py | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aba1399..f33e8c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,9 +41,9 @@ This needs to be setup on the [Heroku Application settings](https://dashboard.he On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of the generated token. -GITHUB_INTEGRATION_ID -B64KEY -GITHUB_BOT_NAME -WEBHOOK_SECRET -PERSONAL_ACCOUNT_NAME -PERSONAL_ACCOUNT_TOKEN +GITHUB_INTEGRATION_ID="10" +B64KEY="aGVsbG8=" +GITHUB_BOT_NAME="meeseeksdev-test" +WEBHOOK_SECRET="fake" +PERSONAL_ACCOUNT_NAME="fake" +PERSONAL_ACCOUNT_TOKEN="fake" diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 1a45623..20311ae 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -142,7 +142,8 @@ def main(): config = load_config_from_env() app_v = os.environ.get("HEROKU_RELEASE_VERSION", None) - if app_v: + keen_project_id = os.environ.get("KEEN_PROJECT_ID") + if app_v and keen_project_id: import keen keen.add_event("deploy", {"version": int(app_v[1:])}) From b6e93d8af278e25faa826275d12d7804e031290a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:37:50 -0500 Subject: [PATCH 035/153] clean up keen handling --- CONTRIBUTING.md | 1 + meeseeksdev/__init__.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f33e8c0..6b9c41c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,6 +16,7 @@ If creating, run: ```bash heroku create meeseeksdev-$USER +heroku addons:create keen ``` Otherwise, run: diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 20311ae..1a45623 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -142,8 +142,7 @@ def main(): config = load_config_from_env() app_v = os.environ.get("HEROKU_RELEASE_VERSION", None) - keen_project_id = os.environ.get("KEEN_PROJECT_ID") - if app_v and keen_project_id: + if app_v: import keen keen.add_event("deploy", {"version": int(app_v[1:])}) From bef160e4e86cf3b0b9bef477485738e16cb99e52 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:43:43 -0500 Subject: [PATCH 036/153] make webhook_secret optional --- meeseeksdev/meeseeksbox/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 7398883..f8dab47 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -51,11 +51,11 @@ def validate(self): missing = [ attr for attr in dir(self) - if not attr.startswith("_") and getattr(self, attr) is None + if not attr.startswith("_") and getattr(self, attr) is None and attr != "webhook_secret" ] if missing: raise ValueError( - "The followingg configuration options are missing : {}".format(missing) + "The following configuration options are missing : {}".format(missing) ) return self From 304e2e0e5152a2d84c1c9c7588cc2d53796e74b7 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 10:51:26 -0500 Subject: [PATCH 037/153] do not map auth without person token --- CONTRIBUTING.md | 4 +++- meeseeksdev/meeseeksbox/core.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b9c41c..ab75a44 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,9 +42,11 @@ This needs to be setup on the [Heroku Application settings](https://dashboard.he On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of the generated token. +heroku webhooks:add -i api:dyno -l notify -u https://example.com/hooks + GITHUB_INTEGRATION_ID="10" B64KEY="aGVsbG8=" GITHUB_BOT_NAME="meeseeksdev-test" -WEBHOOK_SECRET="fake" +WEBHOOK_SECRET= Date: Fri, 18 Mar 2022 10:52:51 -0500 Subject: [PATCH 038/153] allow for fake name --- meeseeksdev/meeseeksbox/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index dd15f2f..4270aff 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -668,7 +668,7 @@ def __init__(self, commands, config): self.config.personal_account_token, self.config.personal_account_name, ) - if self.config.personal_account_name: + if self.config.personal_account_name != "fake": self.auth._build_auth_id_mapping() def sig_handler(self, sig, frame): From 79e5ac6adc4a0d12acb87f507be5141433392a28 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 11:10:49 -0500 Subject: [PATCH 039/153] make keen optional --- CONTRIBUTING.md | 6 +++++- meeseeksdev/__init__.py | 6 ++++-- meeseeksdev/meeseeksbox/commands.py | 12 ++++++------ meeseeksdev/meeseeksbox/core.py | 21 ++++++++++----------- meeseeksdev/meeseeksbox/utils.py | 11 +++++++++++ 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ab75a44..3af6122 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,6 @@ If creating, run: ```bash heroku create meeseeksdev-$USER -heroku addons:create keen ``` Otherwise, run: @@ -44,6 +43,11 @@ On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of heroku webhooks:add -i api:dyno -l notify -u https://example.com/hooks +Create a webhook: +https://.herokuapp.com/gh_hook +Use: application/json + + GITHUB_INTEGRATION_ID="10" B64KEY="aGVsbG8=" GITHUB_BOT_NAME="meeseeksdev-test" diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 1a45623..5cf502a 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -144,8 +144,10 @@ def main(): app_v = os.environ.get("HEROKU_RELEASE_VERSION", None) if app_v: import keen - - keen.add_event("deploy", {"version": int(app_v[1:])}) + try: + keen.add_event("deploy", {"version": int(app_v[1:])}) + except Exception as e: + print(e) config.org_whitelist = org_whitelist + [o.lower() for o in org_whitelist] config.user_whitelist = usr_whitelist + [u.lower() for u in usr_whitelist] config.user_blacklist = usr_blacklist + [u.lower() for u in usr_blacklist] diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 3b0cd19..13eb694 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -9,7 +9,6 @@ import git import pipes import mock -import keen import time import traceback @@ -19,6 +18,7 @@ # from friendlyautopep8 import run_on_cwd from .utils import Session, fix_issue_body, fix_comment_body +from .utils import add_event from .scopes import admin, everyone, write @@ -588,7 +588,7 @@ def keen_stats(): nonlocal s_fork_time nonlocal s_clean_time nonlocal s_ff_time - keen.add_event( + add_event( "backport_stats", { "slug": s_slug, @@ -674,7 +674,7 @@ def keen_stats(): infered_target_branch = ".".join(parts) print("inferring branch ...", infered_target_branch) target_branch = infered_target_branch - keen.add_event("backport_infering_branch", {"infering_remove_x": 1}) + add_event("backport_infering_branch", {"infering_remove_x": 1}) if milestone_number: milestone_number = int(milestone_number) @@ -698,7 +698,7 @@ def keen_stats(): for i in range(5): ff = session.personal_request("GET", frk["url"], raise_for_status=False) if ff.status_code == 200: - keen.add_event("fork_wait", {"n": i}) + add_event("fork_wait", {"n": i}) break time.sleep(1) s_fork_time = time.time() - fork_epoch @@ -915,7 +915,7 @@ def keen_stats(): ) print("\n" + e.stderr.decode("utf8", "replace"), file=sys.stderr) print("\n" + repo.git.status(), file=sys.stderr) - keen.add_event("error", {"git_crash": 1}) + add_event("error", {"git_crash": 1}) s_reason = "Unknown error line 501" keen_stats() @@ -989,7 +989,7 @@ def keen_stats(): comment_url, "Something went wrong ... Please have a look at my logs." + extra_info, ) - keen.add_event("error", {"unknown_crash": 1}) + add_event("error", {"unknown_crash": 1}) print("Something went wrong") print(e) s_reason = "Remote branch does not exist" diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 4270aff..1563b42 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -7,8 +7,6 @@ import base64 import json -import keen - import tornado.web import tornado.httpserver import tornado.ioloop @@ -19,6 +17,7 @@ from .utils import Authenticator from .utils import ACCEPT_HEADER_SYMMETRA +from .utils import add_event from .scopes import Permission from yieldbreaker import YieldBreaker @@ -162,7 +161,7 @@ def fn(req, url): traceback.print_exc() if "X-Hub-Signature" not in self.request.headers: - keen.add_event("attack", {"type": "no X-Hub-Signature"}) + add_event("attack", {"type": "no X-Hub-Signature"}) return self.error("WebHook not configured with secret") if not verify_signature( @@ -170,7 +169,7 @@ def fn(req, url): self.request.headers["X-Hub-Signature"], self.config.webhook_secret, ): - keen.add_event("attack", {"type": "wrong signature"}) + add_event("attack", {"type": "wrong signature"}) return self.error( "Cannot validate GitHub payload with provided WebHook secret" ) @@ -194,23 +193,23 @@ def fn(req, url): "created", "submitted", ]: - keen.add_event("ignore_org_missing", {"edited": "reason"}) + add_event("ignore_org_missing", {"edited": "reason"}) else: if hasattr(self.config, "org_whitelist") and ( org not in self.config.org_whitelist ): - keen.add_event("post", {"reject_organisation": org}) + add_event("post", {"reject_organisation": org}) sender = payload.get("sender", {}).get("login", {}) if hasattr(self.config, "user_blacklist") and ( sender in self.config.user_blacklist ): - keen.add_event("post", {"blocked_user": sender}) + add_event("post", {"blocked_user": sender}) self.finish("Blocked user.") return action = payload.get("action", None) - keen.add_event("post", {"accepted_action": action}) + add_event("post", {"accepted_action": action}) unknown_repo = red + "" + normal repo = payload.get("repository", {}).get("full_name", unknown_repo) if repo == unknown_repo: @@ -475,7 +474,7 @@ def dispatch_on_mention(self, body, payload, user): command_args = process_mentionning_comment(body, self.mention_bot_re) for (command, arguments) in command_args: print(" :: treating", command, arguments) - keen.add_event( + add_event( "dispatch", { "mention": { @@ -657,7 +656,7 @@ def user_can(user, command, repo, org, session): class MeeseeksBox: def __init__(self, commands, config): - keen.add_event("status", {"state": "starting"}) + add_event("status", {"state": "starting"}) self.commands = commands self.application = None self.config = config @@ -673,7 +672,7 @@ def __init__(self, commands, config): def sig_handler(self, sig, frame): print(yellow, "Caught signal: %s, Shutting down..." % sig, normal) - keen.add_event("status", {"state": "stopping"}) + add_event("status", {"state": "stopping"}) IOLoop.instance().add_callback(self.shutdown) def shutdown(self): diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 711c986..a4c23bf 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -4,6 +4,7 @@ import jwt import datetime import json +import keen import requests import re @@ -31,6 +32,16 @@ RELINK_RE = re.compile("(?:(?<=[:,\s])|(?<=^))(#\d+)\\b") +def add_event(*args, **kwargs): + """Attempt to add an event to keen, print the event otherwise""" + try: + keen.add_event(*args, **kwargs) + except Exception: + print('Failed to log keen event') + print(args) + print(kwargs) + + def fix_issue_body( body, original_poster, From c2cdcfbaf5c1397f8148bd631288088d352610ef Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 11:23:20 -0500 Subject: [PATCH 040/153] another attempt --- CONTRIBUTING.md | 7 ++++--- meeseeksdev/meeseeksbox/core.py | 2 +- meeseeksdev/meeseeksbox/utils.py | 9 ++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3af6122..d9a59c3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,13 +44,14 @@ On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of heroku webhooks:add -i api:dyno -l notify -u https://example.com/hooks Create a webhook: -https://.herokuapp.com/gh_hook -Use: application/json +Payload URL: ttps://.herokuapp.com/webhook +Content Type: application/json +Secret: GITHUB_INTEGRATION_ID="10" B64KEY="aGVsbG8=" GITHUB_BOT_NAME="meeseeksdev-test" -WEBHOOK_SECRET= PERSONAL_ACCOUNT_NAME="fake" PERSONAL_ACCOUNT_TOKEN="fake" diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 1563b42..9eaf9f7 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -448,7 +448,7 @@ def dispatch_on_mention(self, body, payload, user): """ # to dispatch to commands - installation_id = payload["installation"]["id"] + installation_id = payload.get("installation", {}).get("id", "10") org = payload["repository"]["owner"]["login"] repo = payload["repository"]["name"] pull_request = payload.get("issue", payload).get("pull_request") diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index a4c23bf..5a93273 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -32,14 +32,13 @@ RELINK_RE = re.compile("(?:(?<=[:,\s])|(?<=^))(#\d+)\\b") -def add_event(*args, **kwargs): +def add_event(*args): """Attempt to add an event to keen, print the event otherwise""" try: - keen.add_event(*args, **kwargs) + keen.add_event(*args) except Exception: - print('Failed to log keen event') - print(args) - print(kwargs) + print('Failed to log keen event:') + print(f' {args}') def fix_issue_body( From 842e4ac71d6226fcc9ad90a620f7e5183172d77e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Mar 2022 11:27:50 -0500 Subject: [PATCH 041/153] wip --- CONTRIBUTING.md | 4 ++-- meeseeksdev/meeseeksbox/core.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9a59c3..ccdfc93 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,5 +53,5 @@ GITHUB_INTEGRATION_ID="10" B64KEY="aGVsbG8=" GITHUB_BOT_NAME="meeseeksdev-test" WEBHOOK_SECRET= -PERSONAL_ACCOUNT_NAME="fake" -PERSONAL_ACCOUNT_TOKEN="fake" +PERSONAL_ACCOUNT_NAME="" +PERSONAL_ACCOUNT_TOKEN=" Date: Sun, 20 Mar 2022 21:02:29 -0500 Subject: [PATCH 042/153] wip --- CONTRIBUTING.md | 18 ++++++++++-------- meeseeksdev/meeseeksbox/utils.py | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ccdfc93..2933aff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,17 +41,19 @@ This needs to be setup on the [Heroku Application settings](https://dashboard.he On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of the generated token. -heroku webhooks:add -i api:dyno -l notify -u https://example.com/hooks +Create a GitHub App for testing on your account +Homepage URL: https://meeseeksdev-$USER.herokuapp.com/ +Webhook URL: https://meeseeksdev.herokuapp.com/webhook +Webhook Secret: Set and store as WEBHOOK_SECRET env variable +Private Key: Generate and store as B64KEY env variable -Create a webhook: -Payload URL: ttps://.herokuapp.com/webhook -Content Type: application/json -Secret: +Grant write access to content, issues, and users. +Install the application on your user account. -GITHUB_INTEGRATION_ID="10" -B64KEY="aGVsbG8=" -GITHUB_BOT_NAME="meeseeksdev-test" +GITHUB_INTEGRATION_ID="" +B64KEY="<(B64 part of pem file)>" +GITHUB_BOT_NAME="meeseeksdev-$USER" WEBHOOK_SECRET= PERSONAL_ACCOUNT_NAME="" PERSONAL_ACCOUNT_TOKEN=" Date: Sun, 20 Mar 2022 21:03:50 -0500 Subject: [PATCH 043/153] wip --- meeseeksdev/meeseeksbox/utils.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 0c70c65..3d17205 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -4,7 +4,6 @@ import jwt import datetime import json -import keen import requests import re @@ -35,6 +34,7 @@ def add_event(*args): """Attempt to add an event to keen, print the event otherwise""" try: + import keen keen.add_event(*args) except Exception: print('Failed to log keen event:') @@ -285,9 +285,7 @@ def prepare(): else: repo_name = "multiple-matches" - import keen - - keen.add_event( + add_event( "gh-rate", { "limit": int(rate_limit), From 1f1ba7ada8ee39ad7b3e5e32865986a90e53427b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 21 Mar 2022 05:51:26 -0500 Subject: [PATCH 044/153] wip --- CONTRIBUTING.md | 35 ++++++++++++++++------------- meeseeksdev/meeseeksbox/commands.py | 15 ++++++++++++- meeseeksdev/meeseeksbox/core.py | 2 +- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2933aff..103aca3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ - Install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli#download-and-install). -You will need to have an account in both Heroku. +You will need to have an account in Heroku. Log in to Heroku: @@ -31,29 +31,32 @@ git push heroku $(git rev-parse --abbrev-ref HEAD):master heroku open ``` -Browse to `/hooks/github` and verify page render. - -### Heroku Configuration - -You will need a Github token with access to cancel builds. This - -This needs to be setup on the [Heroku Application settings](https://dashboard.heroku.com/apps/jupyterlab-bot/settings) - -On the `Config Vars`. section set a key `GITHUB_ACCESS_TOKEN` with the value of the generated token. +### GitHub App Configuration Create a GitHub App for testing on your account Homepage URL: https://meeseeksdev-$USER.herokuapp.com/ -Webhook URL: https://meeseeksdev.herokuapp.com/webhook +Webhook URL: https://meeseeksdev-$USER.herokuapp.com/webhook Webhook Secret: Set and store as WEBHOOK_SECRET env variable Private Key: Generate and store as B64KEY env variable Grant write access to content, issues, and users. +Subscribe to Issue and Issue Comment Events. + +Install the application on your user account, at least in your MeeseeksDev fork. -Install the application on your user account. +### Heroku Configuration + +You will need a Github token with access to cancel builds. This + +This needs to be setup on the [Heroku Application settings](https://dashboard.heroku.com/apps/jupyterlab-bot/settings) +On the `Config Vars`. section set the following keys:: + +``` GITHUB_INTEGRATION_ID="" -B64KEY="<(B64 part of pem file)>" -GITHUB_BOT_NAME="meeseeksdev-$USER" -WEBHOOK_SECRET= +B64KEY="" +GITHUB_BOT_NAME=">meeseeksdev-$USER>" +WEBHOOK_SECRET=""" PERSONAL_ACCOUNT_NAME="" -PERSONAL_ACCOUNT_TOKEN=" Date: Mon, 21 Mar 2022 05:57:08 -0500 Subject: [PATCH 045/153] wip --- meeseeksdev/meeseeksbox/commands.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 780a8d3..c04d924 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -536,6 +536,10 @@ def blackify(*, session, payload, arguments, local_config=None): # so far we assume that the commit we rebase on is the first. to_rebase_on = commits_data[0]["parents"][0]["sha"] + + # TODO: fatal: not a git repository (or any parent up to mount point /) + # somehthin went wrong with the checkout from prep_for_command + lpr( f'git rebase -x "black --fast . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', to_rebase_on, From da90bcb682e3fa68918f14c783522076df10d328 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 04:27:39 -0500 Subject: [PATCH 046/153] add run command --- meeseeksdev/meeseeksbox/commands.py | 70 +++++++++++------------------ meeseeksdev/meeseeksbox/utils.py | 8 ++++ 2 files changed, 34 insertions(+), 44 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index c04d924..c6abdc2 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -5,7 +5,6 @@ import random import os import re -import subprocess import git import pipes import mock @@ -18,7 +17,7 @@ # from friendlyautopep8 import run_on_cwd from .utils import Session, fix_issue_body, fix_comment_body -from .utils import add_event +from .utils import add_event, run from .scopes import admin, everyone, write @@ -221,13 +220,13 @@ def black_suggest(*, session, payload, arguments, local_config=None): if os.path.exists(repo_name): print("== Cleaning up previous work ... ") - subprocess.run("rm -rf {}".format(repo_name).split(" ")) + run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") print( f"== Cloning repository from {org_name}/{repo_name}, this can take some time ..." ) - process = subprocess.run( + process = run( [ "git", "clone", @@ -239,10 +238,10 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Cloned..") process.check_returncode() - subprocess.run( + run( "git config --global user.email meeseeksmachine@gmail.com".split(" ") ) - subprocess.run("git config --global user.name FriendlyBot".split(" ")) + run("git config --global user.name FriendlyBot".split(" ")) # do the pep8ify on local filesystem repo = git.Repo(repo_name) @@ -317,14 +316,10 @@ def black_suggest(*, session, payload, arguments, local_config=None): pass if os.path.exists(repo_name): print("== Cleaning up repo... ") - subprocess.run("rm -rf {}".format(repo_name).split(" ")) + run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") -def lpr(*args): - print("Should run:", *args) - - def prep_for_command(name, session, payload, arguments, local_config=None): print(f"===== running command {name} =====") print("===== ============ =====") @@ -369,13 +364,13 @@ def prep_for_command(name, session, payload, arguments, local_config=None): if os.path.exists(repo_name): print("== Cleaning up previous work ... ") - subprocess.run("rm -rf {}".format(repo_name).split(" "), check=True) + run("rm -rf {}".format(repo_name).split(" "), check=True) print("== Done cleaning ") print( f"== Cloning repository from {author_login}/{repo_name}, this can take some time ..." ) - process = subprocess.run( + process = run( [ "git", "clone", @@ -387,10 +382,10 @@ def prep_for_command(name, session, payload, arguments, local_config=None): print("== Cloned..") process.check_returncode() - subprocess.run( + run( "git config --global user.email meeseeksmachine@gmail.com".split(" ") ) - subprocess.run("git config --global user.name FriendlyBot".split(" ")) + run("git config --global user.name FriendlyBot".split(" ")) # do the command on local filesystem repo = git.Repo(repo_name) @@ -425,7 +420,7 @@ def push_the_work(session, payload, arguments, local_config=None): # Push the work print("== Pushing work....:") - lpr(f"pushing with workbranch:{branch}") + print(f"pushing with workbranch:{branch}") repo.remotes.origin.push("workbranch:{}".format(branch), force=True) # Clean up @@ -444,13 +439,12 @@ def precommit(*, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] # Run the command - lpr(cmd) - process = subprocess.run(cmd) + process = run(cmd) # See if the pre-commit succeeded, meaning there was nothing to do if process.returncode == 0: # Clean up the pre-commit files - subprocess.run(["pre-commit run clean"]) + run(["pre-commit run clean"]) # Alert the caller and bail. session.post_comment( @@ -464,15 +458,15 @@ def precommit(*, session, payload, arguments, local_config=None): return # Add any changed files. - subprocess.run('git commit -a -m "Apply pre-commit"') + run('git commit -a -m "Apply pre-commit"') # Run again to see if we've auto-fixed - process = subprocess.run(cmd) + process = run(cmd) # If that fails, then we can't auto-fix if process.returncode != 0: # Clean up the pre-commit files - subprocess.run(["pre-commit run clean"]) + run(["pre-commit run clean"]) # Alert the caller and bail. session.post_comment( @@ -486,7 +480,7 @@ def precommit(*, session, payload, arguments, local_config=None): return # Clean up the pre-commit files - subprocess.run(["pre-commit run clean"]) + run(["pre-commit run clean"]) push_the_work(session, payload, arguments, local_config=local_config) @@ -536,16 +530,7 @@ def blackify(*, session, payload, arguments, local_config=None): # so far we assume that the commit we rebase on is the first. to_rebase_on = commits_data[0]["parents"][0]["sha"] - - # TODO: fatal: not a git repository (or any parent up to mount point /) - # somehthin went wrong with the checkout from prep_for_command - - lpr( - f'git rebase -x "black --fast . && git commit -a --amend --no-edit" --strategy-option=theirs --autosquash', - to_rebase_on, - ) - - process = subprocess.run( + process = run( [ "git", "rebase", @@ -725,8 +710,7 @@ def keen_stats(): if os.path.exists(repo_name): try: re_fetch_epoch = time.time() - print("FF: Git set-url origin") - subprocess.run( + run( [ "git", "remote", @@ -741,13 +725,11 @@ def keen_stats(): print(f"FF: Git fetch {default_branch}") repo.remotes.origin.fetch(default_branch) repo.git.checkout(default_branch) - print(f"FF: Reset hard origin/{default_branch}") - subprocess.run( + run( ["git", "reset", "--hard", f"origin/{default_branch}"], cwd=repo_name, ).check_returncode() - print("FF: Git describe tags....") - subprocess.run(["git", "describe", "--tag"], cwd=repo_name) + run(["git", "describe", "--tag"], cwd=repo_name) re_fetch_delta = time.time() - re_fetch_epoch print(blue + f"FF took {re_fetch_delta}s") s_ff_time = re_fetch_delta @@ -757,7 +739,7 @@ def keen_stats(): clean_epoch = time.time() if os.path.exists(repo_name): print("== Cleaning up previous work... ") - subprocess.run("rm -rf {}".format(repo_name).split(" ")) + run("rm -rf {}".format(repo_name).split(" ")) print("== Done cleaning ") s_clean_time = time.time() - clean_epoch import traceback @@ -770,7 +752,7 @@ def keen_stats(): what_was_done = "Fast-Forwarded" if not os.path.exists(repo_name): print("== Cloning current repository, this can take some time..") - process = subprocess.run( + process = run( [ "git", "clone", @@ -785,7 +767,7 @@ def keen_stats(): s_clone_time = time.time() - clone_epoch - process = subprocess.run( + process = .run( [ "git", "remote", @@ -798,10 +780,10 @@ def keen_stats(): print("==", what_was_done) process.check_returncode() - subprocess.run( + run( "git config --global user.email meeseeksmachine@gmail.com".split(" ") ) - subprocess.run("git config --global user.name MeeseeksDev[bot]".split(" ")) + run("git config --global user.name MeeseeksDev[bot]".split(" ")) # do the backport on local filesystem repo = git.Repo(repo_name) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 3d17205..e090f1b 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -4,8 +4,10 @@ import jwt import datetime import json +import pipes import requests import re +import subprocess green = "\033[0;32m" yellow = "\033[0;33m" @@ -41,6 +43,12 @@ def add_event(*args): print(f' {args}') +def run(*args, **kwargs): + """Print a command and then run it.""" + print(" ".join(map(pipes.quote, args))) + return subprocess.run(*args, **kwargs) + + def fix_issue_body( body, original_poster, From 4281e00ac802bd1518214d7058d44c3c300a3d7d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 08:57:20 -0500 Subject: [PATCH 047/153] fix typo --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index c6abdc2..b65c0cf 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -767,7 +767,7 @@ def keen_stats(): s_clone_time = time.time() - clone_epoch - process = .run( + process = run( [ "git", "remote", From 80b2e4d831989575cb3142f58db1b12f91deaa8b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:00:31 -0500 Subject: [PATCH 048/153] fix run command --- meeseeksdev/meeseeksbox/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index e090f1b..0e83a82 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -43,10 +43,10 @@ def add_event(*args): print(f' {args}') -def run(*args, **kwargs): +def run(cmd, **kwargs): """Print a command and then run it.""" - print(" ".join(map(pipes.quote, args))) - return subprocess.run(*args, **kwargs) + print(" ".join(map(pipes.quote, cmd))) + return subprocess.run(cmd, **kwargs) def fix_issue_body( From 79ac5a973c4f9da6417b4274a3e8c0fc5486edfa Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:05:25 -0500 Subject: [PATCH 049/153] more debug --- meeseeksdev/meeseeksbox/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index b65c0cf..9d1c81d 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -499,8 +499,9 @@ def precommit(*, session, payload, arguments, local_config=None): @admin def blackify(*, session, payload, arguments, local_config=None): - + print("***in blackify") prep_for_command("blackify", session, payload, arguments, local_config=local_config) + print("should have called pre_for_command") comment_url = payload["issue"]["comments_url"] From 61282cd53425145118c47c1bae102061dbc11026 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:11:09 -0500 Subject: [PATCH 050/153] use generator --- meeseeksdev/meeseeksbox/commands.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 9d1c81d..6551e28 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -433,7 +433,7 @@ def push_the_work(session, payload, arguments, local_config=None): @admin def precommit(*, session, payload, arguments, local_config=None): - prep_for_command("precommit", session, payload, arguments, local_config=local_config) + yield prep_for_command("precommit", session, payload, arguments, local_config=local_config) cmd = "pre-commit run --all-files --hook-stage=manual" comment_url = payload["issue"]["comments_url"] @@ -499,9 +499,7 @@ def precommit(*, session, payload, arguments, local_config=None): @admin def blackify(*, session, payload, arguments, local_config=None): - print("***in blackify") - prep_for_command("blackify", session, payload, arguments, local_config=local_config) - print("should have called pre_for_command") + yield prep_for_command("blackify", session, payload, arguments, local_config=local_config) comment_url = payload["issue"]["comments_url"] From 373a0588d92a4a7d9e592806d0373b28f27fe97a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:13:59 -0500 Subject: [PATCH 051/153] use generator --- meeseeksdev/meeseeksbox/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 6551e28..7c4d4ae 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -433,7 +433,7 @@ def push_the_work(session, payload, arguments, local_config=None): @admin def precommit(*, session, payload, arguments, local_config=None): - yield prep_for_command("precommit", session, payload, arguments, local_config=local_config) + yield from prep_for_command("precommit", session, payload, arguments, local_config=local_config) cmd = "pre-commit run --all-files --hook-stage=manual" comment_url = payload["issue"]["comments_url"] @@ -499,7 +499,7 @@ def precommit(*, session, payload, arguments, local_config=None): @admin def blackify(*, session, payload, arguments, local_config=None): - yield prep_for_command("blackify", session, payload, arguments, local_config=local_config) + yield from prep_for_command("blackify", session, payload, arguments, local_config=local_config) comment_url = payload["issue"]["comments_url"] From 322177a423a5d054bd8e9196460b2237dc7a9d08 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:19:18 -0500 Subject: [PATCH 052/153] fix final repo cmd --- meeseeksdev/meeseeksbox/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 7c4d4ae..fbaa7ee 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -416,7 +416,9 @@ def push_the_work(session, payload, arguments, local_config=None): pr_data = r.json() branch = pr_data["head"]["ref"] repo_name = pr_data["head"]["repo"]["name"] - repo = git.Repo(repo_name) + + # Open the repo in the cwd + repo = git.Repo('.') # Push the work print("== Pushing work....:") From fe287e8732a5526de7c317834317c38c68e5fae8 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:21:35 -0500 Subject: [PATCH 053/153] fix pre-commit command --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index fbaa7ee..c527c44 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -441,7 +441,7 @@ def precommit(*, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] # Run the command - process = run(cmd) + process = run(cmd.split(" ")) # See if the pre-commit succeeded, meaning there was nothing to do if process.returncode == 0: From daf23f4634aa9b765e6dde7ef94ac9674e24528d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:29:33 -0500 Subject: [PATCH 054/153] more cleanup --- meeseeksdev/meeseeksbox/commands.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index c527c44..dcfb855 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -446,7 +446,7 @@ def precommit(*, session, payload, arguments, local_config=None): # See if the pre-commit succeeded, meaning there was nothing to do if process.returncode == 0: # Clean up the pre-commit files - run(["pre-commit run clean"]) + run("pre-commit run clean".split(" ")) # Alert the caller and bail. session.post_comment( @@ -460,7 +460,7 @@ def precommit(*, session, payload, arguments, local_config=None): return # Add any changed files. - run('git commit -a -m "Apply pre-commit"') + run('git commit -a -m "Apply pre-commit"'.split(" ")) # Run again to see if we've auto-fixed process = run(cmd) @@ -468,7 +468,7 @@ def precommit(*, session, payload, arguments, local_config=None): # If that fails, then we can't auto-fix if process.returncode != 0: # Clean up the pre-commit files - run(["pre-commit run clean"]) + run("pre-commit run clean".split(" ")) # Alert the caller and bail. session.post_comment( @@ -482,7 +482,7 @@ def precommit(*, session, payload, arguments, local_config=None): return # Clean up the pre-commit files - run(["pre-commit run clean"]) + run("pre-commit run clean".split(" ")) push_the_work(session, payload, arguments, local_config=local_config) From e733d7b4b77f9e9554eb7571ba631f5c96e553be Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:34:23 -0500 Subject: [PATCH 055/153] clean up command handling --- meeseeksdev/meeseeksbox/commands.py | 30 ++++++++++++++--------------- meeseeksdev/meeseeksbox/utils.py | 3 +++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index dcfb855..34f7e0e 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -220,7 +220,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): if os.path.exists(repo_name): print("== Cleaning up previous work ... ") - run("rm -rf {}".format(repo_name).split(" ")) + run("rm -rf {}".format(repo_name)) print("== Done cleaning ") print( @@ -239,9 +239,9 @@ def black_suggest(*, session, payload, arguments, local_config=None): process.check_returncode() run( - "git config --global user.email meeseeksmachine@gmail.com".split(" ") + "git config --global user.email meeseeksmachine@gmail.com" ) - run("git config --global user.name FriendlyBot".split(" ")) + run("git config --global user.name FriendlyBot") # do the pep8ify on local filesystem repo = git.Repo(repo_name) @@ -316,7 +316,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): pass if os.path.exists(repo_name): print("== Cleaning up repo... ") - run("rm -rf {}".format(repo_name).split(" ")) + run("rm -rf {}".format(repo_name)) print("== Done cleaning ") @@ -364,7 +364,7 @@ def prep_for_command(name, session, payload, arguments, local_config=None): if os.path.exists(repo_name): print("== Cleaning up previous work ... ") - run("rm -rf {}".format(repo_name).split(" "), check=True) + run("rm -rf {}".format(repo_name), check=True) print("== Done cleaning ") print( @@ -383,9 +383,9 @@ def prep_for_command(name, session, payload, arguments, local_config=None): process.check_returncode() run( - "git config --global user.email meeseeksmachine@gmail.com".split(" ") + "git config --global user.email meeseeksmachine@gmail.com" ) - run("git config --global user.name FriendlyBot".split(" ")) + run("git config --global user.name FriendlyBot") # do the command on local filesystem repo = git.Repo(repo_name) @@ -441,12 +441,12 @@ def precommit(*, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] # Run the command - process = run(cmd.split(" ")) + process = run(cmd) # See if the pre-commit succeeded, meaning there was nothing to do if process.returncode == 0: # Clean up the pre-commit files - run("pre-commit run clean".split(" ")) + run("pre-commit run clean") # Alert the caller and bail. session.post_comment( @@ -460,7 +460,7 @@ def precommit(*, session, payload, arguments, local_config=None): return # Add any changed files. - run('git commit -a -m "Apply pre-commit"'.split(" ")) + run('git commit -a -m "Apply pre-commit"') # Run again to see if we've auto-fixed process = run(cmd) @@ -468,7 +468,7 @@ def precommit(*, session, payload, arguments, local_config=None): # If that fails, then we can't auto-fix if process.returncode != 0: # Clean up the pre-commit files - run("pre-commit run clean".split(" ")) + run("pre-commit run clean") # Alert the caller and bail. session.post_comment( @@ -482,7 +482,7 @@ def precommit(*, session, payload, arguments, local_config=None): return # Clean up the pre-commit files - run("pre-commit run clean".split(" ")) + run("pre-commit run clean") push_the_work(session, payload, arguments, local_config=local_config) @@ -740,7 +740,7 @@ def keen_stats(): clean_epoch = time.time() if os.path.exists(repo_name): print("== Cleaning up previous work... ") - run("rm -rf {}".format(repo_name).split(" ")) + run("rm -rf {}".format(repo_name)) print("== Done cleaning ") s_clean_time = time.time() - clean_epoch import traceback @@ -782,9 +782,9 @@ def keen_stats(): process.check_returncode() run( - "git config --global user.email meeseeksmachine@gmail.com".split(" ") + "git config --global user.email meeseeksmachine@gmail.com" ) - run("git config --global user.name MeeseeksDev[bot]".split(" ")) + run("git config --global user.name MeeseeksDev[bot]") # do the backport on local filesystem repo = git.Repo(repo_name) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 0e83a82..f14d8b7 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -7,6 +7,7 @@ import pipes import requests import re +import shlex import subprocess green = "\033[0;32m" @@ -45,6 +46,8 @@ def add_event(*args): def run(cmd, **kwargs): """Print a command and then run it.""" + if isinstance(cmd, str): + cmd = shlex.split(cmd) print(" ".join(map(pipes.quote, cmd))) return subprocess.run(cmd, **kwargs) From 0f22cd885ec80bcc49c51c87f7705fa9cac0dd92 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:36:25 -0500 Subject: [PATCH 056/153] add minimal precommit file --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..bf04076 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.4.0 + hooks: + - id: debug-statements From 873bc9feb0321995701dd29a00220f917ebe7b97 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:41:03 -0500 Subject: [PATCH 057/153] fix use of clean command --- meeseeksdev/meeseeksbox/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 34f7e0e..4aa71eb 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -446,7 +446,7 @@ def precommit(*, session, payload, arguments, local_config=None): # See if the pre-commit succeeded, meaning there was nothing to do if process.returncode == 0: # Clean up the pre-commit files - run("pre-commit run clean") + run("pre-commit clean") # Alert the caller and bail. session.post_comment( @@ -468,7 +468,7 @@ def precommit(*, session, payload, arguments, local_config=None): # If that fails, then we can't auto-fix if process.returncode != 0: # Clean up the pre-commit files - run("pre-commit run clean") + run("pre-commit clean") # Alert the caller and bail. session.post_comment( From 70dce6da8682b3892960f341f056eabb552044db Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 22 Mar 2022 09:50:24 -0500 Subject: [PATCH 058/153] allow dash --- meeseeksdev/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 5cf502a..aa418e3 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -165,6 +165,7 @@ def main(): "reformat": blackify, "black": blackify, "suggestions": black_suggest, + "pre-commit": precommit, "precommit": precommit, "ready": ready, "merge": merge, From 7b52cbee870f810877cdf61979e2151b1a68bd7f Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:25:45 -0500 Subject: [PATCH 059/153] add pre-commit, ci, and clean up --- .pre-commit-config.yaml | 26 ++++++++++- CONTRIBUTING.md | 4 +- Makefile | 2 +- Readme.md | 69 ++++++++++++++++++----------- meeseeksdev/__init__.py | 35 ++++----------- meeseeksdev/commands.py | 20 +++------ meeseeksdev/meeseeksbox/__init__.py | 5 ++- meeseeksdev/meeseeksbox/commands.py | 37 ++++++++-------- meeseeksdev/meeseeksbox/core.py | 48 ++++++++------------ meeseeksdev/meeseeksbox/utils.py | 18 +++++--- meeseeksdev/tests/test_misc.py | 9 ++-- 11 files changed, 144 insertions(+), 129 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bf04076..d799314 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,4 +2,28 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.4.0 hooks: - - id: debug-statements + - id: check-builtin-literals + - id: check-added-large-files + - id: check-case-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: forbid-new-submodules + - id: trailing-whitespace + +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.4 + hooks: + - id: flake8 + additional_dependencies: [ + 'flake8-bugbear==20.1.4', + 'flake8-logging-format==0.6.0', + 'flake8-implicit-str-concat==0.2.0', + ] + +- repo: https://github.com/PyCQA/isort + rev: 5.7.0 + hooks: + - id: isort + files: \.py$ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 103aca3..ff15a8d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,8 +55,8 @@ On the `Config Vars`. section set the following keys:: ``` GITHUB_INTEGRATION_ID="" B64KEY="" -GITHUB_BOT_NAME=">meeseeksdev-$USER>" -WEBHOOK_SECRET=""" +GITHUB_BOT_NAME="" +WEBHOOK_SECRET="" PERSONAL_ACCOUNT_NAME="" PERSONAL_ACCOUNT_TOKEN="" ``` diff --git a/Makefile b/Makefile index 5d68d5e..c898ad2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: clean - + clean: find . -name '*.pyc' -delete diff --git a/Readme.md b/Readme.md index 676dc63..ccb6fec 100644 --- a/Readme.md +++ b/Readme.md @@ -8,17 +8,17 @@ See what is a [Meeseeks and a MeeseeksBox](https://www.youtube.com/watch?v=qUYvI We host MeeseeksBox(es) and will expose them as GitHub Integrations so you don't have to host and run your own. You can if you want, it should be pretty -simple. +simple. The advantage of having one and only one box, is to do cross repository -operations (and fix security bugs). +operations (and fix security bugs). The drawback is if there is a security issue, then we're screwed. -## Activate on your Repo +## Activate on your Repo 1) Head [there](https://github.com/apps/meeseeksdev/) and activate -MeeseeksDev on repos you have access to. +MeeseeksDev on repos you have access to. 2) On a repository with MeeseeksDev installed say: `@MeeseeksDev Hello` to be sure MeeseeksDev is correctly installed. @@ -26,9 +26,9 @@ sure MeeseeksDev is correctly installed. 3) Enjoy Beta Phase: During Beta phase repository/users need to be vetted/whitelisted -open an issue if you wish to participate. +open an issue if you wish to participate. -You might also want to tell your CI-integration (like travis-ci) **not** to test the **push** __and__ **the merge**. +You might also want to tell your CI-integration (like travis-ci) **not** to test the **push** __and__ **the merge**. To do so use: ``` branches: @@ -54,7 +54,7 @@ users: - ... ``` -This will allow `` to ask `@meeseeksdev` to perform above commands. +This will allow `` to ask `@meeseeksdev` to perform above commands. The conf file is the one that sits on the repository default branch (usually `master`). @@ -65,9 +65,9 @@ The conf file is the one that sits on the repository default branch (usually Comment on a Pr or issue. -You _may_ put multiple commands, one per line. +You _may_ put multiple commands, one per line. -MrMeeseeks _may_ not like what you ask, and just ignore you. +MrMeeseeks _may_ not like what you ask, and just ignore you. ### @MeeseeksDev hello @@ -82,9 +82,9 @@ To test whether a Meeseeks understand you. If issued from a PR which is merged, attempt to backport (cherry-pick the merge commit) on an older branch and submit a PR with this backport (on said branch) -Apply origin-pr labels and milestone to backport. +Apply origin-pr labels and milestone to backport. -- No option to push directly (yet), if implemented should apply only with clean backport. +- No option to push directly (yet), if implemented should apply only with clean backport. - Investigate what to do in case of conflict - likely commit with conflict, and let maintainers resolve conflict @@ -92,30 +92,51 @@ Repo admins only Note: Cloning can take a long-time. So expect MrMeeseeks to be busy while this happen. Also heroku has a 2min deadline and other limitations, so MrMeeseeks can -likely be killed. I haven't implemented a queue yet. +likely be killed. I haven't implemented a queue yet. + +### @MeeseeksDev black + +If issued from a PR, will apply black to commits made in this PR and push +the updated commits. + +Repo admins only, we plan to make it available to PR authors as well. + +MeeseeksDev Bot needs to be installed on the PR source repository for this to work. +If it's not it will ask you to do so. + +### @MeeseeksDev pre-commit + +If issued from a PR, will apply pre-commit to this PR and push +a commit with the changes made. If no changes are made, or the changes +cannot be automatically fixed, it will show a comment in the PR and bail. + +Repo admins only, we plan to make it available to PR authors as well. + +MeeseeksDev Bot needs to be installed on the PR source repository for this to work. +If it's not it will ask you to do so. ### @MeeseeksDev pep8ify (in progress) If issued from a PR, will apply autopep8 to the current lines changed by this -PR, and push an extra commit to it that fixes pep8. +PR, and push an extra commit to it that fixes pep8. Code in progress and due to GitHub API limitation only works if MeeseeksDev -also available on Source repo of the PR. +also available on Source repo of the PR. -Repo admins only, plan to make it available to PR author as well. +Repo admins only, plan to make it available to PR author as well. MeeseeksDev Bot need to be installed on the PR source repository for this to work. -If it's not it will ask you to do so. +If it's not it will ask you to do so. ### @MeeseeksDev migrate [to] {target org/repo} Needs MeeseeksBox to be installed on both current and target repo. Command -issuer to be admin on both. +issuer to be admin on both. MeeseeksDev will open a similar issue, replicate all comments with links to -first, migrate labels (if possible). +first, migrate labels (if possible). ### @MeeseeksDev close @@ -136,7 +157,7 @@ Remove said tags if present (comma separated, need to be exact match) ### @MeeseeksDev merge [merge|squash|rebase] -Issuer needs at least write permission. +Issuer needs at least write permission. If Mergeable, Merge current PR using said methods (`merge` if no arguments) @@ -188,19 +209,13 @@ def foo(*, session, payload, argument): GitHub API does not allow to change permissions once given (yet). We don't want you to go though the process of reinstalling all integrations. -We would like to request less permission if necessary. +We would like to request less permission if necessary. # Setup. -These are the environment variable that need to be set. - - - `INTEGRATION_ID` The integration ID given to you by GitHub when you create - an integration - - `BOTNAME` Name of the integration on GitHub, should be without the leading - `@`, and with the `[bot]`. This is used for the bot to react to his own name, and not reply to itself... +See CONTIBUTING.md for for information. - TODO # Warnings diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index aa418e3..dc6e789 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -1,10 +1,18 @@ """ Meeseeksbox main app module """ -import os import base64 +import os import signal +from .commands import close, help_make, merge, migrate_issue_request +from .commands import open as _open +from .commands import ready +from .meeseeksbox.commands import (black_suggest, blackify, debug, party, + precommit, replyuser, safe_backport, say, + tag, untag, zen) +from .meeseeksbox.core import Config, MeeseeksBox + org_whitelist = [ "MeeseeksBox", "Jupyter", @@ -105,31 +113,6 @@ def load_config_from_env(): return Config(**config).validate() -from .meeseeksbox.core import MeeseeksBox -from .meeseeksbox.core import Config -from .meeseeksbox.commands import ( - replyuser, - zen, - tag, - untag, - blackify, - black_suggest, - precommit, - quote, - say, - debug, - party, - safe_backport, -) -from .commands import ( - close, - open as _open, - migrate_issue_request, - ready, - merge, - help_make, -) - green = "\x1b[0;32m" yellow = "\x1b[0;33m" blue = "\x1b[0;34m" diff --git a/meeseeksdev/commands.py b/meeseeksdev/commands.py index d1357b3..a6e2ac1 100644 --- a/meeseeksdev/commands.py +++ b/meeseeksdev/commands.py @@ -2,12 +2,12 @@ Define a few commands """ -from .meeseeksbox.utils import Session, fix_issue_body, fix_comment_body - -from .meeseeksbox.scopes import admin, write, everyone - from textwrap import dedent +from .meeseeksbox.commands import tag, untag +from .meeseeksbox.scopes import everyone, pr_author, write +from .meeseeksbox.utils import Session, fix_comment_body, fix_issue_body + def _format_doc(function, name): if not function.__doc__: @@ -52,7 +52,7 @@ def open(*, session, payload, arguments, local_config=None): def migrate_issue_request( *, session: Session, payload: dict, arguments: str, local_config=None ): - """[to] {org}/{repo} + """[to] {org}/{repo} Need to be admin on target repo. Replicate all comments on target repo and close current on. """ @@ -75,9 +75,7 @@ def migrate_issue_request( session.post_comment( payload["issue"]["comments_url"], body="I'm afraid I can't do that. Maybe I need to be installed on target repository ?\n" - "Click [here](https://github.com/integrations/meeseeksdev/installations/new) to do that.".format( - botname="meeseeksdev" - ), + "Click [here](https://github.com/integrations/meeseeksdev/installations/new) to do that.", ) return @@ -151,17 +149,13 @@ def migrate_issue_request( session.ghrequest("PATCH", payload["issue"]["url"], json={"state": "closed"}) -from .meeseeksbox.scopes import pr_author, write -from .meeseeksbox.commands import tag, untag - - @pr_author @write def ready(*, session, payload, arguments, local_config=None): """{no arguments} Remove "waiting for author" tag, adds "need review" tag. Can also be issued - if you are the current PR author even if you are not admin. + if you are the current PR author even if you are not admin. """ tag(session, payload, "need review") untag(session, payload, "waiting for author") diff --git a/meeseeksdev/meeseeksbox/__init__.py b/meeseeksdev/meeseeksbox/__init__.py index dee3012..e5d5026 100644 --- a/meeseeksdev/meeseeksbox/__init__.py +++ b/meeseeksdev/meeseeksbox/__init__.py @@ -7,10 +7,11 @@ handle authencation of user. """ -import os import base64 +import os + +from .core import MeeseeksBox # noqa from .core import Config -from .core import MeeseeksBox version_info = (0, 0, 2) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 4aa71eb..693efe0 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -2,24 +2,20 @@ Define a few commands """ -import random import os -import re -import git import pipes -import mock +import random +import re +import sys import time import traceback - -import sys from textwrap import dedent -# from friendlyautopep8 import run_on_cwd - -from .utils import Session, fix_issue_body, fix_comment_body -from .utils import add_event, run +import git +import mock from .scopes import admin, everyone, write +from .utils import Session, add_event, fix_comment_body, fix_issue_body, run green = "\033[0;32m" yellow = "\033[0;33m" @@ -111,10 +107,11 @@ def replyadmin(*, session, payload, arguments, local_config=None): def _compute_pwd_changes(whitelist): - import black + import glob from difflib import SequenceMatcher from pathlib import Path - import glob + + import black post_changes = [] import os @@ -321,6 +318,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): def prep_for_command(name, session, payload, arguments, local_config=None): + """Prepare to run a command against a local checkout of a repo.""" print(f"===== running command {name} =====") print("===== ============ =====") # collect initial payload @@ -400,6 +398,7 @@ def prep_for_command(name, session, payload, arguments, local_config=None): def push_the_work(session, payload, arguments, local_config=None): + """Push the work down in a local repo to the remote repo.""" prnumber = payload["issue"]["number"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] @@ -435,6 +434,7 @@ def push_the_work(session, payload, arguments, local_config=None): @admin def precommit(*, session, payload, arguments, local_config=None): + """Run pre-commit against a PR and push the changes.""" yield from prep_for_command("precommit", session, payload, arguments, local_config=local_config) cmd = "pre-commit run --all-files --hook-stage=manual" @@ -452,7 +452,7 @@ def precommit(*, session, payload, arguments, local_config=None): session.post_comment( comment_url, body=dedent( - f""" + """ I was unable to run "pre-commit" because there was nothing to do. """ ), @@ -474,7 +474,7 @@ def precommit(*, session, payload, arguments, local_config=None): session.post_comment( comment_url, body=dedent( - f""" + """ I was unable to run "pre-commit" due to an error, changes must be made manually. """ ), @@ -491,7 +491,7 @@ def precommit(*, session, payload, arguments, local_config=None): session.post_comment( comment_url, body=dedent( - f""" + """ I've applied "pre-commit" and pushed. You may have trouble pushing further commits, but feel free to force push and ask me to run again. """ @@ -501,6 +501,7 @@ def precommit(*, session, payload, arguments, local_config=None): @admin def blackify(*, session, payload, arguments, local_config=None): + """Run black against all commits of on a PR and push the new commits.""" yield from prep_for_command("blackify", session, payload, arguments, local_config=local_config) comment_url = payload["issue"]["comments_url"] @@ -536,7 +537,7 @@ def blackify(*, session, payload, arguments, local_config=None): "git", "rebase", "-x", - f"black --fast . && git commit -a --amend --no-edit", + "black --fast . && git commit -a --amend --no-edit", "--strategy-option=theirs", "--autosquash", to_rebase_on, @@ -547,7 +548,7 @@ def blackify(*, session, payload, arguments, local_config=None): session.post_comment( comment_url, body=dedent( - f""" + """ I was unable to run "blackify" due to an error. """ ), @@ -560,7 +561,7 @@ def blackify(*, session, payload, arguments, local_config=None): session.post_comment( comment_url, body=dedent( - f""" + """ I've rebased this Pull Request, applied `black` on all the individual commits, and pushed. You may have trouble pushing further commits, but feel free to force push and ask me to reformat again. diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 741d95c..effe33b 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -1,26 +1,20 @@ -import re +import base64 import hmac -import time import inspect - -import yaml -import base64 import json +import re +import time +from concurrent.futures import ThreadPoolExecutor as Pool -import tornado.web import tornado.httpserver import tornado.ioloop +import tornado.web +import yaml from tornado.ioloop import IOLoop +from yieldbreaker import YieldBreaker -from concurrent.futures import ThreadPoolExecutor as Pool - - -from .utils import Authenticator -from .utils import ACCEPT_HEADER_SYMMETRA -from .utils import add_event from .scopes import Permission - -from yieldbreaker import YieldBreaker +from .utils import ACCEPT_HEADER_SYMMETRA, Authenticator, add_event green = "\033[0;32m" yellow = "\033[0;33m" @@ -29,8 +23,6 @@ pool = Pool(6) -import time - class Config: botname = None @@ -72,8 +64,8 @@ def error(self, message): self.set_status(500) self.write({"status": "error", "message": message}) - def success(self, message="", payload={}): - self.write({"status": "success", "message": message, "data": payload}) + def success(self, message="", payload=None): + self.write({"status": "success", "message": message, "data": payload or {}}) class MainHandler(BaseHandler): @@ -149,13 +141,13 @@ def fn(req, url): with requests.Session() as s: res = s.send(prepared) return res - except: + except Exception: import traceback traceback.print_exc() pool.submit(fn, self.request, self.config.forward_staging_url) - except: + except Exception: print(red + "failure to forward") import traceback @@ -255,7 +247,7 @@ def fn(req, url): @property def mention_bot_re(self): botname = self.config.botname - return re.compile("@?" + re.escape(botname) + "(?:\[bot\])?", re.IGNORECASE) + return re.compile("@?" + re.escape(botname) + r"(?:\[bot\])?", re.IGNORECASE) def dispatch_action(self, type_, payload): botname = self.config.botname @@ -368,7 +360,7 @@ def dispatch_action(self, type_, payload): # apparently can still be none-like ? label_desc = label.get("description", "") or "" description.append(label_desc.replace("&", "\n")) - except: + except Exception: import traceback traceback.print_exc() @@ -384,7 +376,7 @@ def dispatch_action(self, type_, payload): for description_line in description.splitlines(): line = description_line.strip() if line.startswith("on-merge:"): - todo = line[len("on-merge:") :].strip() + todo = line[len("on-merge:"):].strip() self.dispatch_on_mention( "@meeseeksdev " + todo, payload, @@ -655,7 +647,6 @@ def user_can(user, command, repo, org, session): class MeeseeksBox: def __init__(self, commands, config): - add_event("status", {"state": "starting"}) self.commands = commands self.application = None @@ -672,15 +663,14 @@ def __init__(self, commands, config): def sig_handler(self, sig, frame): print(yellow, "Caught signal: %s, Shutting down..." % sig, normal) add_event("status", {"state": "stopping"}) - IOLoop.instance().add_callback(self.shutdown) + IOLoop.instance().add_callback_from_signal(self.shutdown) def shutdown(self): + print('in shutdown') self.server.stop() io_loop = IOLoop.instance() - deadline = time.time() + 10 - def stop_loop(): print(red, "stopping now...", normal) io_loop.stop() @@ -705,6 +695,6 @@ def start(self): ) self.server = tornado.httpserver.HTTPServer(self.application) - self.server.listen(self.port) - tornado.ioloop.IOLoop.instance().start() + + IOLoop.instance().start() diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index f14d8b7..f785a96 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -1,21 +1,23 @@ """ Utility functions to work with github. """ -import jwt import datetime import json import pipes -import requests import re import shlex import subprocess +import jwt +import requests + +from .scopes import Permission + green = "\033[0;32m" yellow = "\033[0;33m" red = "\033[0;31m" normal = "\033[0m" -from .scopes import Permission API_COLLABORATORS_TEMPLATE = ( "https://api.github.com/repos/{org}/{repo}/collaborators/{username}/permission" @@ -31,7 +33,7 @@ Pay attention to not relink things like foo#23 as they already point to a specific repository. """ -RELINK_RE = re.compile("(?:(?<=[:,\s])|(?<=^))(#\d+)\\b") +RELINK_RE = re.compile(r"(?:(?<=[:,\s])|(?<=^))(#\d+)\\b") def add_event(*args): @@ -70,7 +72,9 @@ def fix_issue_body( "{org}/{repo}\\1".format(org=original_org, repo=original_repo), body ) - return body + """\n\n---- + return ( + body + + """\n\n---- \nOriginally opened as {org}/{repo}#{number} by @{reporter}, migration requested by @{requester} """.format( org=original_org, @@ -165,6 +169,8 @@ def _build_auth_id_mapping(self): except Forbidden: print("Forbidden for", iid) continue + for repo in repositories["repositories"]: + self.idmap[repo["full_name"]] = iid def _integration_authenticated_request(self, method, url): self.since = int(datetime.datetime.now().timestamp()) @@ -223,7 +229,7 @@ def regen_token(self): try: self._token = json.loads(resp.content.decode())["token"] - except: + except Exception: raise ValueError(resp.content, url) def personal_request(self, method, url, json=None, raise_for_status=True): diff --git a/meeseeksdev/tests/test_misc.py b/meeseeksdev/tests/test_misc.py index efbdd32..925caf3 100644 --- a/meeseeksdev/tests/test_misc.py +++ b/meeseeksdev/tests/test_misc.py @@ -1,11 +1,12 @@ -from ..meeseeksbox.core import process_mentionning_comment -import textwrap import re +import textwrap + +from ..meeseeksbox.core import process_mentionning_comment def test1(): botname = "meeseeksdev" - reg = re.compile("@?" + re.escape(botname) + "(?:\[bot\])?", re.IGNORECASE) + reg = re.compile("@?" + re.escape(botname) + r"(?:\[bot\])?", re.IGNORECASE) assert ( process_mentionning_comment( @@ -15,7 +16,7 @@ def test1(): @meeseeksdev[bot] do nothing meeseeksdev[bot] do something - + """ ), reg, From dba4c18ebc650103d792d5a7556821ce41841616 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:26:35 -0500 Subject: [PATCH 060/153] add gha and flake8 --- .flake8 | 14 ++++++++ .github/workflows/build.yml | 68 ++++++++++++++++++++++++++++++++++++ .github/workflows/connect.py | 23 ++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 .flake8 create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/connect.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..b5b675f --- /dev/null +++ b/.flake8 @@ -0,0 +1,14 @@ +[flake8] +max-line-length = 88 +enable-extensions = G +extend-ignore = + G200, G202, + # E501 line too long + E501 + # E741 ambiguous variable name + E741 + # E266 too many leading '#' for block commen + E266 + # E731 do not assign a lambda expression, use a def + E731 +per-file-ignores = diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..fec4a15 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,68 @@ +name: Tests +on: + push: + branches: ["master"] + pull_request: + +jobs: + # Run "pre-commit run --all-files" + pre-commit: + runs-on: ubuntu-20.04 + timeout-minutes: 2 + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + + # ref: https://github.com/pre-commit/action + - uses: pre-commit/action@v2.0.0 + - name: Help message if pre-commit fail + if: ${{ failure() }} + run: | + echo "You can install pre-commit hooks to automatically run formatting" + echo "on each commit with:" + echo " pre-commit install" + echo "or you can run by hand on staged files with" + echo " pre-commit run" + echo "or after-the-fact on already committed files with" + echo " pre-commit run --all-files" + + build: + runs-on: ubuntu-latest + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + python-version: ["3.10"] + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Base Setup + uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - name: Install the Python dependencies + run: | + pip install -r requirements.txt + pip install pytest + - name: Run the tests + python -m pytest -vv -raXs || python -m pytest -vv -raXs --lf + - name: Start the App + env: + GITHUB_INTEGRATION_ID=812 + B64KEY=${{ secrets.B64KEY }} + GITHUB_BOT_NAME="meeseeksdev-$USER" + WEBHOOK_SECRET="foo" + PERSONAL_ACCOUNT_NAME="snuffy" + PERSONAL_ACCOUNT_TOKEN="token" + run: | + set -eux + python -m meeseeksdev & + TASK_PID=$! + # Make sure the task is running + ps -p $TASK_PID + # Connect to the task + python .github/workflows/connect.py + # Kill the task + kill $TASK_PID + wait $TASK_PID diff --git a/.github/workflows/connect.py b/.github/workflows/connect.py new file mode 100644 index 0000000..26ced54 --- /dev/null +++ b/.github/workflows/connect.py @@ -0,0 +1,23 @@ +import errno +import time +from urllib import request +from urllib.error import URLError + +t0 = time.time() +found = False +url = 'http://localhost:9874' + +while (time.time() - t0) < 60: + try: + request.urlopen(url) + found = True + break + except URLError as e: + if e.reason.errno == errno.ECONNREFUSED: + time.sleep(1) + continue + raise + + +if not found: + raise ValueError(f'Could not connect to {url}') From b05daf9dbb6ffe1f5e47c276b3e400821078ea10 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:32:31 -0500 Subject: [PATCH 061/153] fix step --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fec4a15..f44695a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: pip install -r requirements.txt pip install pytest - name: Run the tests - python -m pytest -vv -raXs || python -m pytest -vv -raXs --lf + run: python -m pytest -vv -raXs || python -m pytest -vv -raXs --lf - name: Start the App env: GITHUB_INTEGRATION_ID=812 From 3ff1fb2eaff4a3e0c6caef6487560951e1bcff2e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:34:04 -0500 Subject: [PATCH 062/153] fix install --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 475c2fc..bbfa3c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,4 @@ yieldbreaker==0.0.1 black==22.1 pyyaml==6.0 keen==0.7 -gitdb2==2.0.6 -gitdb==0.6.4 pre-commit==2.17 From 607178e603240e5a4b9607a2971238ff347a4e15 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:36:32 -0500 Subject: [PATCH 063/153] fix env variables --- .github/workflows/build.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f44695a..dc13194 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,12 +49,12 @@ jobs: run: python -m pytest -vv -raXs || python -m pytest -vv -raXs --lf - name: Start the App env: - GITHUB_INTEGRATION_ID=812 - B64KEY=${{ secrets.B64KEY }} - GITHUB_BOT_NAME="meeseeksdev-$USER" - WEBHOOK_SECRET="foo" - PERSONAL_ACCOUNT_NAME="snuffy" - PERSONAL_ACCOUNT_TOKEN="token" + GITHUB_INTEGRATION_ID: 812 + B64KEY: ${{ secrets.B64KEY }} + GITHUB_BOT_NAME: meeseeksdev-test + WEBHOOK_SECRET: foo + PERSONAL_ACCOUNT_NAME: snuffy + PERSONAL_ACCOUNT_TOKEN: token run: | set -eux python -m meeseeksdev & From 1af8aed08998a4cb52f79829690ad33f8b3636c4 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:37:15 -0500 Subject: [PATCH 064/153] fix syntax --- meeseeksdev/meeseeksbox/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index f785a96..4d4de38 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -76,7 +76,7 @@ def fix_issue_body( body + """\n\n---- \nOriginally opened as {org}/{repo}#{number} by @{reporter}, migration requested by @{requester} - """.format( + """).format( org=original_org, repo=original_repo, number=original_number, From 87a4eb31c471b9dc2bcb7fbb4b497629421f2bfe Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:39:21 -0500 Subject: [PATCH 065/153] connect on 5000 --- .github/workflows/build.yml | 4 ++++ .github/workflows/connect.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc13194..8f227fc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,10 @@ on: branches: ["master"] pull_request: +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + jobs: # Run "pre-commit run --all-files" pre-commit: diff --git a/.github/workflows/connect.py b/.github/workflows/connect.py index 26ced54..754945f 100644 --- a/.github/workflows/connect.py +++ b/.github/workflows/connect.py @@ -5,7 +5,7 @@ t0 = time.time() found = False -url = 'http://localhost:9874' +url = 'http://localhost:5000' while (time.time() - t0) < 60: try: From 76bf8002ca30f2badd9797a5e42e79ddd6c3c5c6 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 05:40:42 -0500 Subject: [PATCH 066/153] fix use of token --- meeseeksdev/meeseeksbox/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 4d4de38..5557b0e 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -185,7 +185,7 @@ def _integration_authenticated_request(self, method, url): tok = jwt.encode(payload, key=self.rsadata, algorithm="RS256") headers = { - "Authorization": f"Bearer {tok.decode()}", + "Authorization": f"Bearer {tok}", "Accept": ACCEPT_HEADER_V3, "Host": "api.github.com", "User-Agent": "python/requests", From 63292c15893511b01e8cf5a774b3847f44bc3d95 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 11:09:34 -0500 Subject: [PATCH 067/153] Add black and check-jsonschema --- .pre-commit-config.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d799314..7f2dc57 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,8 +22,23 @@ repos: 'flake8-implicit-str-concat==0.2.0', ] +- repo: https://github.com/psf/black + rev: 22.1.0 + hooks: + - id: black + args: ["--line-length", "100"] + - repo: https://github.com/PyCQA/isort rev: 5.7.0 hooks: - id: isort files: \.py$ + +- repo: https://github.com/sirosen/check-jsonschema + rev: 0.10.2 + hooks: + - id: check-jsonschema + name: "Check GitHub Workflows" + files: ^\.github/workflows/ + types: [yaml] + args: ["--schemafile", "https://json.schemastore.org/github-workflow"] From a7dbae90cf965d331800a96de25dc76d3109381d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 11:11:22 -0500 Subject: [PATCH 068/153] run black --- .flake8 | 2 + .github/workflows/connect.py | 4 +- .pre-commit-config.yaml | 1 + meeseeksdev/__init__.py | 17 ++++- meeseeksdev/commands.py | 22 ++---- meeseeksdev/meeseeksbox/commands.py | 110 ++++++++-------------------- meeseeksdev/meeseeksbox/core.py | 58 ++++----------- meeseeksdev/meeseeksbox/utils.py | 34 +++------ 8 files changed, 81 insertions(+), 167 deletions(-) diff --git a/.flake8 b/.flake8 index b5b675f..fac3add 100644 --- a/.flake8 +++ b/.flake8 @@ -11,4 +11,6 @@ extend-ignore = E266 # E731 do not assign a lambda expression, use a def E731 + # E203 whitespace before ':' + E203 per-file-ignores = diff --git a/.github/workflows/connect.py b/.github/workflows/connect.py index 754945f..7ccf815 100644 --- a/.github/workflows/connect.py +++ b/.github/workflows/connect.py @@ -5,7 +5,7 @@ t0 = time.time() found = False -url = 'http://localhost:5000' +url = "http://localhost:5000" while (time.time() - t0) < 60: try: @@ -20,4 +20,4 @@ if not found: - raise ValueError(f'Could not connect to {url}') + raise ValueError(f"Could not connect to {url}") diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7f2dc57..15245f4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,6 +33,7 @@ repos: hooks: - id: isort files: \.py$ + args: [--profile=black] - repo: https://github.com/sirosen/check-jsonschema rev: 0.10.2 diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index dc6e789..00ab3c0 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -8,9 +8,19 @@ from .commands import close, help_make, merge, migrate_issue_request from .commands import open as _open from .commands import ready -from .meeseeksbox.commands import (black_suggest, blackify, debug, party, - precommit, replyuser, safe_backport, say, - tag, untag, zen) +from .meeseeksbox.commands import ( + black_suggest, + blackify, + debug, + party, + precommit, + replyuser, + safe_backport, + say, + tag, + untag, + zen, +) from .meeseeksbox.core import Config, MeeseeksBox org_whitelist = [ @@ -127,6 +137,7 @@ def main(): app_v = os.environ.get("HEROKU_RELEASE_VERSION", None) if app_v: import keen + try: keen.add_event("deploy", {"version": int(app_v[1:])}) except Exception as e: diff --git a/meeseeksdev/commands.py b/meeseeksdev/commands.py index a6e2ac1..d04d0e5 100644 --- a/meeseeksdev/commands.py +++ b/meeseeksdev/commands.py @@ -49,12 +49,10 @@ def open(*, session, payload, arguments, local_config=None): @write -def migrate_issue_request( - *, session: Session, payload: dict, arguments: str, local_config=None -): +def migrate_issue_request(*, session: Session, payload: dict, arguments: str, local_config=None): """[to] {org}/{repo} -Need to be admin on target repo. Replicate all comments on target repo and close current on. + Need to be admin on target repo. Replicate all comments on target repo and close current on. """ """Todo: @@ -92,9 +90,7 @@ def migrate_issue_request( if original_labels: available_labels = target_session.ghrequest( "GET", - "https://api.github.com/repos/{org}/{repo}/labels".format( - org=org, repo=repo - ), + "https://api.github.com/repos/{org}/{repo}/labels".format(org=org, repo=repo), None, ).json() @@ -121,9 +117,7 @@ def migrate_issue_request( new_issue = new_response.json() new_comment_url = new_issue["comments_url"] - original_comments = session.ghrequest( - "GET", payload["issue"]["comments_url"], None - ).json() + original_comments = session.ghrequest("GET", payload["issue"]["comments_url"], None).json() for comment in original_comments: if comment["id"] == request_id: @@ -137,9 +131,7 @@ def migrate_issue_request( ) if not_set_labels: - body = "I was not able to apply the following label(s): %s " % ",".join( - not_set_labels - ) + body = "I was not able to apply the following label(s): %s " % ",".join(not_set_labels) target_session.post_comment(new_comment_url, body=body) session.post_comment( @@ -178,9 +170,7 @@ def merge(*, session, payload, arguments, method="merge", local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format( - org_name, repo_name, prnumber - ), + "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), json=None, ) pr_data = r.json() diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 693efe0..5c52dc3 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -101,9 +101,7 @@ def zen(*, session, payload, arguments, local_config=None): def replyadmin(*, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] user = payload["issue"]["user"]["login"] - session.post_comment( - comment_url, "Hello @{user}. Waiting for your orders.".format(user=user) - ) + session.post_comment(comment_url, "Hello @{user}. Waiting for your orders.".format(user=user)) def _compute_pwd_changes(whitelist): @@ -159,9 +157,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format( - org_name, repo_name, prnumber - ), + "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), json=None, ) pr_data = r.json() @@ -220,9 +216,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): run("rm -rf {}".format(repo_name)) print("== Done cleaning ") - print( - f"== Cloning repository from {org_name}/{repo_name}, this can take some time ..." - ) + print(f"== Cloning repository from {org_name}/{repo_name}, this can take some time ...") process = run( [ "git", @@ -235,9 +229,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Cloned..") process.check_returncode() - run( - "git config --global user.email meeseeksmachine@gmail.com" - ) + run("git config --global user.email meeseeksmachine@gmail.com") run("git config --global user.name FriendlyBot") # do the pep8ify on local filesystem @@ -332,9 +324,7 @@ def prep_for_command(name, session, payload, arguments, local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format( - org_name, repo_name, prnumber - ), + "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), json=None, ) pr_data = r.json() @@ -365,24 +355,18 @@ def prep_for_command(name, session, payload, arguments, local_config=None): run("rm -rf {}".format(repo_name), check=True) print("== Done cleaning ") - print( - f"== Cloning repository from {author_login}/{repo_name}, this can take some time ..." - ) + print(f"== Cloning repository from {author_login}/{repo_name}, this can take some time ...") process = run( [ "git", "clone", - "https://x-access-token:{}@github.com/{}/{}".format( - atk, author_login, repo_name - ), + "https://x-access-token:{}@github.com/{}/{}".format(atk, author_login, repo_name), ] ) print("== Cloned..") process.check_returncode() - run( - "git config --global user.email meeseeksmachine@gmail.com" - ) + run("git config --global user.email meeseeksmachine@gmail.com") run("git config --global user.name FriendlyBot") # do the command on local filesystem @@ -407,9 +391,7 @@ def push_the_work(session, payload, arguments, local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format( - org_name, repo_name, prnumber - ), + "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), json=None, ) pr_data = r.json() @@ -417,7 +399,7 @@ def push_the_work(session, payload, arguments, local_config=None): repo_name = pr_data["head"]["repo"]["name"] # Open the repo in the cwd - repo = git.Repo('.') + repo = git.Repo(".") # Push the work print("== Pushing work....:") @@ -512,9 +494,7 @@ def blackify(*, session, payload, arguments, local_config=None): r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format( - org_name, repo_name, prnumber - ), + "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), json=None, ) pr_data = r.json() @@ -655,9 +635,7 @@ def keen_stats(): print("== Collecting data on Pull-request ...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format( - org_name, repo_name, prnumber - ), + "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), json=None, ) pr_data = r.json() @@ -758,9 +736,7 @@ def keen_stats(): [ "git", "clone", - "https://x-access-token:{}@github.com/{}/{}".format( - atk, org_name, repo_name - ), + "https://x-access-token:{}@github.com/{}/{}".format(atk, org_name, repo_name), ] ) process.check_returncode() @@ -782,9 +758,7 @@ def keen_stats(): print("==", what_was_done) process.check_returncode() - run( - "git config --global user.email meeseeksmachine@gmail.com" - ) + run("git config --global user.email meeseeksmachine@gmail.com") run("git config --global user.name MeeseeksDev[bot]") # do the backport on local filesystem @@ -792,9 +766,7 @@ def keen_stats(): print("== Fetching branch to backport on ... {}".format(target_branch)) repo.remotes.origin.fetch("refs/heads/{}:workbranch".format(target_branch)) repo.git.checkout("workbranch") - print( - "== Fetching Commits to {mergesha} backport...".format(mergesha=merge_sha) - ) + print("== Fetching Commits to {mergesha} backport...".format(mergesha=merge_sha)) repo.remotes.origin.fetch("{mergesha}".format(mergesha=merge_sha)) print("== All has been fetched correctly") @@ -810,18 +782,14 @@ def keen_stats(): repo.git.cherry_pick(*args) except git.GitCommandError as e: if "is not a merge." in e.stderr: - print( - "Likely not a merge PR...Attempting squash and merge picking." - ) + print("Likely not a merge PR...Attempting squash and merge picking.") args = (merge_sha,) repo.git.cherry_pick(*args) else: raise except git.GitCommandError as e: - if ("git commit --allow-empty" in e.stderr) or ( - "git commit --allow-empty" in e.stdout - ): + if ("git commit --allow-empty" in e.stderr) or ("git commit --allow-empty" in e.stdout): session.post_comment( comment_url, "Can't Dooooo.... It seem like this is already backported (commit is empty)." @@ -891,9 +859,7 @@ def keen_stats(): num = payload.get("issue", payload).get("number") url = f"https://api.github.com/repos/{org}/{repo}/issues/{num}/labels" print("trying to apply still needs manual backport") - reply = session.ghrequest( - "POST", url, json=["Still Needs Manual Backport"] - ) + reply = session.ghrequest("POST", url, json=["Still Needs Manual Backport"]) print("Should be applied:", reply) s_reason = "conflicts" keen_stats() @@ -933,9 +899,7 @@ def keen_stats(): # Push the backported work print("== Pushing work....:") try: - print( - f"Tryign to push to {remote_submit_branch} of {session.personal_account_name}" - ) + print(f"Tryign to push to {remote_submit_branch} of {session.personal_account_name}") repo.remotes[session.personal_account_name].push( "workbranch:{}".format(remote_submit_branch) ) @@ -966,9 +930,7 @@ def keen_stats(): json={ "title": f"Backport PR #{prnumber} on branch {target_branch} ({prtitle})", "body": msg, - "head": "{}:{}".format( - session.personal_account_name, remote_submit_branch - ), + "head": "{}:{}".format(session.personal_account_name, remote_submit_branch), "base": target_branch, }, ).json() @@ -976,16 +938,16 @@ def keen_stats(): new_number = new_pr["number"] resp = session.ghrequest( "PATCH", - "https://api.github.com/repos/{}/{}/issues/{}".format( - org_name, repo_name, new_number - ), + "https://api.github.com/repos/{}/{}/issues/{}".format(org_name, repo_name, new_number), json={"milestone": milestone_number, "labels": labels_names}, ) # print(resp.json()) except Exception as e: extra_info = "" if maybe_wrong_named_branch: - extra_info = "\n\n It seems that the branch you are trying to backport to does not exist." + extra_info = ( + "\n\n It seems that the branch you are trying to backport to does not exist." + ) session.post_comment( comment_url, "Something went wrong ... Please have a look at my logs." + extra_info, @@ -1115,9 +1077,7 @@ def untag(session, payload, arguments, local_config=None): num = payload.get("issue", payload.get("pull_request")).get("number") tags = [arg.strip() for arg in arguments.split(",")] name = "{name}" - url = "https://api.github.com/repos/{org}/{repo}/issues/{num}/labels/{name}".format( - **locals() - ) + url = "https://api.github.com/repos/{org}/{repo}/issues/{num}/labels/{name}".format(**locals()) no_untag = [] for tag in tags: try: @@ -1128,9 +1088,7 @@ def untag(session, payload, arguments, local_config=None): @write -def migrate_issue_request( - *, session: Session, payload: dict, arguments: str, local_config=None -): +def migrate_issue_request(*, session: Session, payload: dict, arguments: str, local_config=None): """Todo: - Works through pagination of comments @@ -1146,9 +1104,7 @@ def migrate_issue_request( target_session = yield org_repo if not target_session: - session.post_comment( - payload["issue"]["comments_url"], "It appears that I can't do that" - ) + session.post_comment(payload["issue"]["comments_url"], "It appears that I can't do that") return issue_title = payload["issue"]["title"] @@ -1164,9 +1120,7 @@ def migrate_issue_request( if original_labels: available_labels = target_session.ghrequest( "GET", - "https://api.github.com/repos/{org}/{repo}/labels".format( - org=org, repo=repo - ), + "https://api.github.com/repos/{org}/{repo}/labels".format(org=org, repo=repo), None, ).json() @@ -1193,9 +1147,7 @@ def migrate_issue_request( new_issue = new_response.json() new_comment_url = new_issue["comments_url"] - original_comments = session.ghrequest( - "GET", payload["issue"]["comments_url"], None - ).json() + original_comments = session.ghrequest("GET", payload["issue"]["comments_url"], None).json() for comment in original_comments: if comment["id"] == request_id: @@ -1209,9 +1161,7 @@ def migrate_issue_request( ) if not_set_labels: - body = "I was not able to apply the following label(s): %s " % ",".join( - not_set_labels - ) + body = "I was not able to apply the following label(s): %s " % ",".join(not_set_labels) target_session.post_comment(new_comment_url, body=body) session.post_comment( diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index effe33b..5e2bfef 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -45,9 +45,7 @@ def validate(self): if not attr.startswith("_") and getattr(self, attr) is None and attr != "webhook_secret" ] if missing: - raise ValueError( - "The following configuration options are missing : {}".format(missing) - ) + raise ValueError("The following configuration options are missing : {}".format(missing)) return self @@ -134,9 +132,7 @@ def fn(req, url): "X-Hub-Signature", ) } - req = requests.Request( - "POST", url, headers=headers, data=req.body - ) + req = requests.Request("POST", url, headers=headers, data=req.body) prepared = req.prepare() with requests.Session() as s: res = s.send(prepared) @@ -162,19 +158,12 @@ def fn(req, url): self.config.webhook_secret, ): add_event("attack", {"type": "wrong signature"}) - return self.error( - "Cannot validate GitHub payload with provided WebHook secret" - ) + return self.error("Cannot validate GitHub payload with provided WebHook secret") payload = tornado.escape.json_decode(self.request.body) org = payload.get("repository", {}).get("owner", {}).get("login") if not org: - org = ( - payload.get("issue", {}) - .get("repository", {}) - .get("owner", {}) - .get("login") - ) + org = payload.get("issue", {}).get("repository", {}).get("owner", {}).get("login") print("org in issue", org) if payload.get("action", None) in [ @@ -187,15 +176,11 @@ def fn(req, url): ]: add_event("ignore_org_missing", {"edited": "reason"}) else: - if hasattr(self.config, "org_whitelist") and ( - org not in self.config.org_whitelist - ): + if hasattr(self.config, "org_whitelist") and (org not in self.config.org_whitelist): add_event("post", {"reject_organisation": org}) sender = payload.get("sender", {}).get("login", {}) - if hasattr(self.config, "user_blacklist") and ( - sender in self.config.user_blacklist - ): + if hasattr(self.config, "user_blacklist") and (sender in self.config.user_blacklist): add_event("post", {"blocked_user": sender}) self.finish("Blocked user.") return @@ -237,9 +222,7 @@ def fn(req, url): "push", "create", }: - print( - f"(https://github.com/{repo}) Not handling event type `{event_type}` yet." - ) + print(f"(https://github.com/{repo}) Not handling event type `{event_type}` yet.") return self.finish() print(f"({repo}) No action available for the webhook :", event_type) @@ -251,9 +234,7 @@ def mention_bot_re(self): def dispatch_action(self, type_, payload): botname = self.config.botname - repo = payload.get("repository", {}).get( - "full_name", red + "" + normal - ) + repo = payload.get("repository", {}).get("full_name", red + "" + normal) # new issue/PR opened if type_ == "opened": issue = payload.get("issue", None) @@ -376,7 +357,7 @@ def dispatch_action(self, type_, payload): for description_line in description.splitlines(): line = description_line.strip() if line.startswith("on-merge:"): - todo = line[len("on-merge:"):].strip() + todo = line[len("on-merge:") :].strip() self.dispatch_on_mention( "@meeseeksdev " + todo, payload, @@ -492,11 +473,7 @@ def user_can(user, command, repo, org, session): raise_for_status=False, ) except Exception: - print( - red - + "An error occurred getting repository config file." - + normal - ) + print(red + "An error occurred getting repository config file." + normal) import traceback traceback.print_exc() @@ -508,14 +485,8 @@ def user_can(user, command, repo, org, session): print(red + f"unknown status code {resp.status_code}" + normal) resp.raise_for_status() else: - conf = yaml.safe_load( - base64.decodebytes(resp.json()["content"].encode()) - ) - print( - green - + f"should test if {user} can {command} on {repo}/{org}" - + normal - ) + conf = yaml.safe_load(base64.decodebytes(resp.json()["content"].encode())) + print(green + f"should test if {user} can {command} on {repo}/{org}" + normal) # print(green + json.dumps(conf, indent=2) + normal) if user in conf.get("blacklisted_users", []): @@ -612,8 +583,7 @@ def user_can(user, command, repo, org, session): if target_session.has_permission( torg, trepo, user, Permission.write ) or ( - pr_origin_org_repo == org_repo - and allow_edit_from_maintainer + pr_origin_org_repo == org_repo and allow_edit_from_maintainer ): gen.send(target_session) else: @@ -666,7 +636,7 @@ def sig_handler(self, sig, frame): IOLoop.instance().add_callback_from_signal(self.shutdown) def shutdown(self): - print('in shutdown') + print("in shutdown") self.server.stop() io_loop = IOLoop.instance() diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 5557b0e..18ce9ba 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -40,10 +40,11 @@ def add_event(*args): """Attempt to add an event to keen, print the event otherwise""" try: import keen + keen.add_event(*args) except Exception: - print('Failed to log keen event:') - print(f' {args}') + print("Failed to log keen event:") + print(f" {args}") def run(cmd, **kwargs): @@ -68,15 +69,14 @@ def fix_issue_body( This should be improved to quote mention of people """ - body = RELINK_RE.sub( - "{org}/{repo}\\1".format(org=original_org, repo=original_repo), body - ) + body = RELINK_RE.sub("{org}/{repo}\\1".format(org=original_org, repo=original_repo), body) return ( body + """\n\n---- \nOriginally opened as {org}/{repo}#{number} by @{reporter}, migration requested by @{requester} - """).format( + """ + ).format( org=original_org, repo=original_repo, number=original_number, @@ -92,9 +92,7 @@ def fix_comment_body(body, original_poster, original_url, original_org, original This should be improved to quote mention of people """ - body = RELINK_RE.sub( - "{org}/{repo}\\1".format(org=original_org, repo=original_repo), body - ) + body = RELINK_RE.sub("{org}/{repo}\\1".format(org=original_org, repo=original_repo), body) return """[`@{op}` commented]({original_url}): {body}""".format( op=original_poster, original_url=original_url, body=body @@ -102,9 +100,7 @@ def fix_comment_body(body, original_poster, original_url, original_org, original class Authenticator: - def __init__( - self, integration_id, rsadata, personal_account_token, personal_account_name - ): + def __init__(self, integration_id, rsadata, personal_account_token, personal_account_name): self.since = int(datetime.datetime.now().timestamp()) self.duration = 60 * 10 self._token = None @@ -209,9 +205,7 @@ def __init__( personal_account_token, personal_account_name, ): - super().__init__( - integration_id, rsadata, personal_account_token, personal_account_name - ) + super().__init__(integration_id, rsadata, personal_account_token, personal_account_name) self.installation_id = installation_id def token(self): @@ -291,9 +285,7 @@ def prepare(): rate_limit = response.headers.get("X-RateLimit-Limit", -1) rate_remaining = response.headers.get("X-RateLimit-Limit", -1) if rate_limit: - repo_name_list = [ - k for k, v in self.idmap.items() if v == self.installation_id - ] + repo_name_list = [k for k, v in self.idmap.items() if v == self.installation_id] repo_name = "no-repo" if len(repo_name_list) == 1: repo_name = repo_name_list[0] @@ -338,10 +330,8 @@ def post_comment(self, comment_url, body): self.ghrequest("POST", comment_url, json={"body": body}) def get_collaborator_list(self, org, repo): - get_collaborators_query = ( - "https://api.github.com/repos/{org}/{repo}/collaborators".format( - org=org, repo=repo - ) + get_collaborators_query = "https://api.github.com/repos/{org}/{repo}/collaborators".format( + org=org, repo=repo ) resp = self.ghrequest("GET", get_collaborators_query, None) if resp.status_code == 200: From da524c058c7337f0d6d74680288bc6d18fd2e7ff Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 19:46:06 -0500 Subject: [PATCH 069/153] rename readme --- Readme.md => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Readme.md => README.md (100%) diff --git a/Readme.md b/README.md similarity index 100% rename from Readme.md rename to README.md From b2a4fec2fb544735033ad58f5fb57f5872349176 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 20:15:04 -0500 Subject: [PATCH 070/153] make B64KEY optional --- .github/workflows/build.yml | 1 - meeseeksdev/__init__.py | 3 ++- meeseeksdev/meeseeksbox/__init__.py | 3 ++- meeseeksdev/meeseeksbox/core.py | 2 +- meeseeksdev/meeseeksbox/utils.py | 5 ++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8f227fc..c336828 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,6 @@ jobs: - name: Start the App env: GITHUB_INTEGRATION_ID: 812 - B64KEY: ${{ secrets.B64KEY }} GITHUB_BOT_NAME: meeseeksdev-test WEBHOOK_SECRET: foo PERSONAL_ACCOUNT_NAME: snuffy diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 00ab3c0..23e751d 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -103,7 +103,8 @@ def load_config_from_env(): at_botname = "@" + botname integration_id = int(integration_id) - config["key"] = base64.b64decode(bytes(os.environ.get("B64KEY"), "ASCII")) + if "B64KEY" in os.environ: + config["key"] = base64.b64decode(bytes(os.environ["B64KEY"], "ASCII")) config["botname"] = botname config["at_botname"] = at_botname config["integration_id"] = integration_id diff --git a/meeseeksdev/meeseeksbox/__init__.py b/meeseeksdev/meeseeksbox/__init__.py index e5d5026..1cd765f 100644 --- a/meeseeksdev/meeseeksbox/__init__.py +++ b/meeseeksdev/meeseeksbox/__init__.py @@ -39,7 +39,8 @@ def load_config_from_env(): at_botname = "@" + botname integration_id = int(integration_id) - config["key"] = base64.b64decode(bytes(os.environ.get("B64KEY"), "ASCII")) + if "B64KEY" in os.environ: + config["key"] = base64.b64decode(bytes(os.environ["B64KEY"], "ASCII")) config["botname"] = botname config["at_botname"] = at_botname config["integration_id"] = integration_id diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 5e2bfef..b7fef62 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -42,7 +42,7 @@ def validate(self): missing = [ attr for attr in dir(self) - if not attr.startswith("_") and getattr(self, attr) is None and attr != "webhook_secret" + if not attr.startswith("_") and getattr(self, attr) is None and attr != "key" ] if missing: raise ValueError("The following configuration options are missing : {}".format(missing)) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 18ce9ba..78d5dcf 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -151,7 +151,8 @@ def _build_auth_id_mapping(self): Build an organisation/repo -> installation_id mappingg in order to be able to do cross repository operations. """ - + if not self.rsadata: + return installations = self.list_installations() for installation in installations: iid = installation["id"] @@ -165,8 +166,6 @@ def _build_auth_id_mapping(self): except Forbidden: print("Forbidden for", iid) continue - for repo in repositories["repositories"]: - self.idmap[repo["full_name"]] = iid def _integration_authenticated_request(self, method, url): self.since = int(datetime.datetime.now().timestamp()) From 3cb1310ee0380810093e48392e27246835c426c9 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 20:20:17 -0500 Subject: [PATCH 071/153] print a notice --- meeseeksdev/meeseeksbox/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 78d5dcf..dcc4eef 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -152,6 +152,7 @@ def _build_auth_id_mapping(self): to do cross repository operations. """ if not self.rsadata: + print("Skipping auth_id_mapping build since there is no B64KEY set") return installations = self.list_installations() for installation in installations: From 3ec9c5d4ed6d8aab28509a81f06918f9b453d75a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 23 Mar 2022 20:27:12 -0500 Subject: [PATCH 072/153] cleanup --- .github/workflows/build.yml | 1 + meeseeksdev/__init__.py | 2 ++ meeseeksdev/meeseeksbox/__init__.py | 36 +---------------------------- 3 files changed, 4 insertions(+), 35 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c336828..ed0123b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,6 +58,7 @@ jobs: WEBHOOK_SECRET: foo PERSONAL_ACCOUNT_NAME: snuffy PERSONAL_ACCOUNT_TOKEN: token + TESTING: true run: | set -eux python -m meeseeksdev & diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 23e751d..8540e91 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -105,6 +105,8 @@ def load_config_from_env(): if "B64KEY" in os.environ: config["key"] = base64.b64decode(bytes(os.environ["B64KEY"], "ASCII")) + elif "TESTING" not in os.environ: + raise ValueError("Missing B64KEY environment variable") config["botname"] = botname config["at_botname"] = at_botname config["integration_id"] = integration_id diff --git a/meeseeksdev/meeseeksbox/__init__.py b/meeseeksdev/meeseeksbox/__init__.py index 1cd765f..067b45c 100644 --- a/meeseeksdev/meeseeksbox/__init__.py +++ b/meeseeksdev/meeseeksbox/__init__.py @@ -7,43 +7,9 @@ handle authencation of user. """ -import base64 -import os - +from .core import Config # noqa from .core import MeeseeksBox # noqa -from .core import Config version_info = (0, 0, 2) __version__ = ".".join(map(str, version_info)) - - -def load_config_from_env(): - """ - Load the configuration, for now stored in the environment - """ - config = {} - - integration_id = os.environ.get("GITHUB_INTEGRATION_ID") - botname = os.environ.get("GITHUB_BOT_NAME", None) - - if not integration_id: - raise ValueError("Please set GITHUB_INTEGRATION_ID") - - if not botname: - raise ValueError("Need to set a botname") - if "@" in botname: - print("Don't include @ in the botname !") - - botname = botname.replace("@", "") - at_botname = "@" + botname - integration_id = int(integration_id) - - if "B64KEY" in os.environ: - config["key"] = base64.b64decode(bytes(os.environ["B64KEY"], "ASCII")) - config["botname"] = botname - config["at_botname"] = at_botname - config["integration_id"] = integration_id - config["webhook_secret"] = os.environ.get("WEBHOOK_SECRET") - - return Config(**config).validate() From 5b3149e63526185210867a726a84b1f8bbec38fc Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:17:28 -0500 Subject: [PATCH 073/153] Pre-commit improvements --- meeseeksdev/meeseeksbox/commands.py | 33 +++++++++++------ meeseeksdev/meeseeksbox/core.py | 13 ++++--- meeseeksdev/tests/test_misc.py | 10 ++++- meeseeksdev/tests/test_webhook.py | 57 +++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 18 deletions(-) create mode 100644 meeseeksdev/tests/test_webhook.py diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 5c52dc3..1108c46 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -339,6 +339,7 @@ def prep_for_command(name, session, payload, arguments, local_config=None): if target_session: print("installed on target repository") atk = target_session.token() + session.post_comment(comment_url, body=f"Running {name} on this Pull Request...") else: print("use allow edit as maintainer") atk = session.token() @@ -442,29 +443,39 @@ def precommit(*, session, payload, arguments, local_config=None): return # Add any changed files. - run('git commit -a -m "Apply pre-commit"') + process = run('git commit -a -m "Apply pre-commit"') + made_changes = process.returncode == 0 # Run again to see if we've auto-fixed process = run(cmd) - # If that fails, then we can't auto-fix + # Clean up the pre-commit files + run("pre-commit clean") + + # If second run fails, then we can't auto-fix if process.returncode != 0: - # Clean up the pre-commit files - run("pre-commit clean") - # Alert the caller and bail. + if not made_changes: + # Alert the caller and bail. + session.post_comment( + comment_url, + body=dedent( + """ + I was unable to fix pre-commit errors automatically. + Try running `pre-commit run --all-files` locally. + """ + ), + ) + return + session.post_comment( comment_url, body=dedent( """ - I was unable to run "pre-commit" due to an error, changes must be made manually. - """ + I was unable to fix all of the pre-commit errors automatically. Try running `pre-commit run --all-files` locally. + """ ), ) - return - - # Clean up the pre-commit files - run("pre-commit run clean") push_the_work(session, payload, arguments, local_config=local_config) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index b7fef62..cc2e56b 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -71,11 +71,12 @@ def get(self): self.finish("No") -def _strip_please(c): +def _strip_extras(c): if c.startswith("please "): - return c[6:].lstrip() - else: - return c + c = c[6:].lstrip() + if c.startswith("run "): + c = c[4:].lstrip() + return c def process_mentionning_comment(body, bot_re): @@ -99,7 +100,7 @@ def process_mentionning_comment(body, bot_re): else: nl.append(bot_re.split(l)[-1].strip()) - command_args = [_strip_please(l).split(" ", 1) for l in nl] + command_args = [_strip_extras(l).split(" ", 1) for l in nl] command_args = [c if len(c) > 1 else [c[0], None] for c in command_args] return command_args @@ -112,7 +113,7 @@ def initialize(self, actions, config, auth, *args, **kwargs): super().initialize(*args, **kwargs) def get(self): - self.getfinish("Webhook alive and listening") + self.finish("Webhook alive and listening") def post(self): if self.config.forward_staging_url: diff --git a/meeseeksdev/tests/test_misc.py b/meeseeksdev/tests/test_misc.py index 925caf3..bc6c7f6 100644 --- a/meeseeksdev/tests/test_misc.py +++ b/meeseeksdev/tests/test_misc.py @@ -15,11 +15,19 @@ def test1(): @meeseeksdev nothing @meeseeksdev[bot] do nothing meeseeksdev[bot] do something + @meeseeksdev please nothing + @meeseeksdev run something """ ), reg, ) - == [["nothing", None], ["do", "nothing"], ["do", "something"]] + == [ + ["nothing", None], + ["do", "nothing"], + ["do", "something"], + ["nothing", None], + ["something", None], + ] ) diff --git a/meeseeksdev/tests/test_webhook.py b/meeseeksdev/tests/test_webhook.py new file mode 100644 index 0000000..970c81c --- /dev/null +++ b/meeseeksdev/tests/test_webhook.py @@ -0,0 +1,57 @@ +import hmac + +import pytest +import tornado.web + +from ..meeseeksbox.core import Authenticator, Config, WebHookHandler + +commands = {} + +config = Config( + integration_id=100, + key=None, + personal_account_token="foo", + personal_account_name="bar", + forward_staging_url="", + webhook_secret="foo", +) + +auth = Authenticator( + config.integration_id, config.key, config.personal_account_token, config.personal_account_name +) + +application = tornado.web.Application( + [ + ( + r"/", + WebHookHandler, + { + "actions": commands, + "config": config, + "auth": auth, + }, + ), + ] +) + + +@pytest.fixture +def app(): + return application + + +@pytest.mark.gen_test +def test_get(http_client, base_url): + response = yield http_client.fetch(base_url) + assert response.code == 200 + + +@pytest.mark.gen_test +def test_post(http_client, base_url): + body = "{}" + secret = config.webhook_secret + assert secret is not None + sig = "sha1=" + hmac.new(secret.encode("utf8"), body.encode("utf8"), "sha1").hexdigest() + headers = {"X-Hub-Signature": sig} + response = yield http_client.fetch(base_url, method="POST", body=body, headers=headers) + assert response.code == 200 From f63a27dba4934b3006d8e8966eab3df65942aa9a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:17:57 -0500 Subject: [PATCH 074/153] fix pre-commit ordering --- .pre-commit-config.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 15245f4..0fa8b58 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,16 +12,6 @@ repos: - id: forbid-new-submodules - id: trailing-whitespace -- repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 - hooks: - - id: flake8 - additional_dependencies: [ - 'flake8-bugbear==20.1.4', - 'flake8-logging-format==0.6.0', - 'flake8-implicit-str-concat==0.2.0', - ] - - repo: https://github.com/psf/black rev: 22.1.0 hooks: @@ -35,6 +25,16 @@ repos: files: \.py$ args: [--profile=black] +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.4 + hooks: + - id: flake8 + additional_dependencies: [ + 'flake8-bugbear==20.1.4', + 'flake8-logging-format==0.6.0', + 'flake8-implicit-str-concat==0.2.0', + ] + - repo: https://github.com/sirosen/check-jsonschema rev: 0.10.2 hooks: From e9bb170e67c813d6e7a94df011050cb41a317abf Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:23:02 -0500 Subject: [PATCH 075/153] add test reqs --- requirements-test.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 requirements-test.txt diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000..e347c37 --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,3 @@ +-r ./requirements.txt +pytest +pytest-tornado From 720d5f432994021231bc16653ddfc3307add2b7f Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:25:02 -0500 Subject: [PATCH 076/153] update test reqs --- .github/workflows/build.yml | 3 +-- requirements-test.txt | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ed0123b..74aff2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,8 +47,7 @@ jobs: uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install the Python dependencies run: | - pip install -r requirements.txt - pip install pytest + pip install -r requirements-test.txt - name: Run the tests run: python -m pytest -vv -raXs || python -m pytest -vv -raXs --lf - name: Start the App diff --git a/requirements-test.txt b/requirements-test.txt index e347c37..f410c11 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,3 +1,3 @@ -r ./requirements.txt -pytest -pytest-tornado +pytest>=6.0 +pytest-tornasync From 9c99dcc64f5587c4cd54b85d4044ab15d5063b37 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:27:48 -0500 Subject: [PATCH 077/153] fix tests --- meeseeksdev/tests/test_webhook.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/meeseeksdev/tests/test_webhook.py b/meeseeksdev/tests/test_webhook.py index 970c81c..29edab3 100644 --- a/meeseeksdev/tests/test_webhook.py +++ b/meeseeksdev/tests/test_webhook.py @@ -40,18 +40,16 @@ def app(): return application -@pytest.mark.gen_test -def test_get(http_client, base_url): - response = yield http_client.fetch(base_url) +async def test_get(http_server_client): + response = await http_server_client.fetch("/") assert response.code == 200 -@pytest.mark.gen_test -def test_post(http_client, base_url): +async def test_post(http_server_client): body = "{}" secret = config.webhook_secret assert secret is not None sig = "sha1=" + hmac.new(secret.encode("utf8"), body.encode("utf8"), "sha1").hexdigest() headers = {"X-Hub-Signature": sig} - response = yield http_client.fetch(base_url, method="POST", body=body, headers=headers) + response = await http_server_client.fetch("/", method="POST", body=body, headers=headers) assert response.code == 200 From 0e63f70870b80f0c79705717b5581a546d3f0279 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:44:51 -0500 Subject: [PATCH 078/153] add blackify alias --- meeseeksdev/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 8540e91..60a80d7 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -161,6 +161,7 @@ def main(): "autopep8": blackify, "reformat": blackify, "black": blackify, + "blackify": blackify, "suggestions": black_suggest, "pre-commit": precommit, "precommit": precommit, From 62f501a6ef7c1feb36e1940304cb3d2c18c69757 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 24 Mar 2022 04:48:16 -0500 Subject: [PATCH 079/153] update readme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index ccb6fec..6b2a786 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ likely be killed. I haven't implemented a queue yet. If issued from a PR, will apply black to commits made in this PR and push the updated commits. +You can also use "blackify" as an alias. + Repo admins only, we plan to make it available to PR authors as well. MeeseeksDev Bot needs to be installed on the PR source repository for this to work. @@ -110,6 +112,8 @@ If issued from a PR, will apply pre-commit to this PR and push a commit with the changes made. If no changes are made, or the changes cannot be automatically fixed, it will show a comment in the PR and bail. +You can also use "precommit" as an alias. + Repo admins only, we plan to make it available to PR authors as well. MeeseeksDev Bot needs to be installed on the PR source repository for this to work. @@ -161,6 +165,11 @@ Issuer needs at least write permission. If Mergeable, Merge current PR using said methods (`merge` if no arguments) +## Command Extras + +You can be polite and use "please" with any of the commands, e.g. "@Meeseeksdev please close". + +You can optionally use the word "run" in the command, e.g. "@Meeseeksdev please run pre-commit". ## Simple extension. From fc741b140c0175ceda1df495a6aad2712b425c9d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 27 Mar 2022 06:44:06 -0500 Subject: [PATCH 080/153] Include original sha in cherry-pick commit message --- meeseeksdev/meeseeksbox/commands.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 1108c46..8617f51 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -346,7 +346,7 @@ def prep_for_command(name, session, payload, arguments, local_config=None): session.post_comment( comment_url, body="Would you mind installing me on your fork so that I can update your branch? \n" - "Click [here](https://github.com/apps/meeseeksdev/installations/new)" + "Click [here](https://github.com/apps/meeseeksdev/installations/new) " "to do that, and follow the instructions to add your fork." "I'm going to try to push as a maintainer but this may not work.", ) @@ -782,7 +782,7 @@ def keen_stats(): print("== All has been fetched correctly") print("Cherry-picking %s" % merge_sha) - args = ("-m", "1", merge_sha) + args = ("-x", "-m", "1", merge_sha) msg = "Backport PR #%i: %s" % (prnumber, prtitle) remote_submit_branch = f"auto-backport-of-pr-{prnumber}-on-{target_branch}" @@ -910,7 +910,7 @@ def keen_stats(): # Push the backported work print("== Pushing work....:") try: - print(f"Tryign to push to {remote_submit_branch} of {session.personal_account_name}") + print(f"Trying to push to {remote_submit_branch} of {session.personal_account_name}") repo.remotes[session.personal_account_name].push( "workbranch:{}".format(remote_submit_branch) ) From b657ea4e8ace4472862883a08af48005a94ddc06 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 03:48:56 -0500 Subject: [PATCH 081/153] include -x in the manual backport message --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 8617f51..db39a3e 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -837,7 +837,7 @@ def keen_stats(): 2. Cherry pick the first parent branch of the this PR on top of the older branch: ``` -git cherry-pick -m1 {merge_sha} +git cherry-pick -x -m1 {merge_sha} ``` 3. You will likely have some merge/cherry-pick conflict here, fix them and commit: From f044b634ac56e700b59e978c4cce3f1bddf38500 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 05:15:06 -0500 Subject: [PATCH 082/153] clean up precommit --- meeseeksdev/meeseeksbox/commands.py | 28 +++++++++++++++++++++++++--- requirements.txt | 1 + 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index db39a3e..46a97f2 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -10,6 +10,7 @@ import time import traceback from textwrap import dedent +from pathlib import Path import git import mock @@ -107,7 +108,6 @@ def replyadmin(*, session, payload, arguments, local_config=None): def _compute_pwd_changes(whitelist): import glob from difflib import SequenceMatcher - from pathlib import Path import black @@ -417,11 +417,31 @@ def push_the_work(session, payload, arguments, local_config=None): @admin def precommit(*, session, payload, arguments, local_config=None): + comment_url = payload["issue"]["comments_url"] + """Run pre-commit against a PR and push the changes.""" yield from prep_for_command("precommit", session, payload, arguments, local_config=local_config) - cmd = "pre-commit run --all-files --hook-stage=manual" - comment_url = payload["issue"]["comments_url"] + # Install the package in if there are local hooks + config = Path("./.pre-commit-config.yaml") + if not config.exists(): + # Alert the caller and bail. + session.post_comment( + comment_url, + body=dedent( + """ + I was unable to fix pre-commit errors because there is no + ".pre-commit-config.yaml" file. + """ + ), + ) + return + + if "repo: local" in config.read_text(): + run("pip install --user -e .") + + + cmd = "pre_commit run --all-files --hook-stage=manual" # Run the command process = run(cmd) @@ -491,6 +511,8 @@ def precommit(*, session, payload, arguments, local_config=None): ), ) + run("pip cache purge") + @admin def blackify(*, session, payload, arguments, local_config=None): diff --git a/requirements.txt b/requirements.txt index bbfa3c4..9afa358 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ black==22.1 pyyaml==6.0 keen==0.7 pre-commit==2.17 +pip==22.0.4 From e1cabfc302d8f3a21c456bdb2cc19f4aa960bed2 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 05:16:56 -0500 Subject: [PATCH 083/153] lint --- meeseeksdev/meeseeksbox/commands.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 46a97f2..80de02f 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -9,8 +9,8 @@ import sys import time import traceback -from textwrap import dedent from pathlib import Path +from textwrap import dedent import git import mock @@ -440,7 +440,6 @@ def precommit(*, session, payload, arguments, local_config=None): if "repo: local" in config.read_text(): run("pip install --user -e .") - cmd = "pre_commit run --all-files --hook-stage=manual" # Run the command From 475851680293ccfb2ac1a6e5e577d5188e545b3d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 05:34:28 -0500 Subject: [PATCH 084/153] clean up comments --- meeseeksdev/meeseeksbox/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 80de02f..c2cb47c 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -422,7 +422,7 @@ def precommit(*, session, payload, arguments, local_config=None): """Run pre-commit against a PR and push the changes.""" yield from prep_for_command("precommit", session, payload, arguments, local_config=local_config) - # Install the package in if there are local hooks + # Make sure there is a pre-commit file. config = Path("./.pre-commit-config.yaml") if not config.exists(): # Alert the caller and bail. @@ -437,6 +437,7 @@ def precommit(*, session, payload, arguments, local_config=None): ) return + # Install the package in editable mode if there are local hooks. if "repo: local" in config.read_text(): run("pip install --user -e .") From 2796225346523de2bb68d04e4dc8f7df515bb6cb Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 09:05:35 -0500 Subject: [PATCH 085/153] clear caches once per day --- meeseeksdev/meeseeksbox/commands.py | 7 ------- meeseeksdev/meeseeksbox/core.py | 7 ++++++- meeseeksdev/meeseeksbox/utils.py | 8 ++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index c2cb47c..7de0044 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -448,8 +448,6 @@ def precommit(*, session, payload, arguments, local_config=None): # See if the pre-commit succeeded, meaning there was nothing to do if process.returncode == 0: - # Clean up the pre-commit files - run("pre-commit clean") # Alert the caller and bail. session.post_comment( @@ -469,9 +467,6 @@ def precommit(*, session, payload, arguments, local_config=None): # Run again to see if we've auto-fixed process = run(cmd) - # Clean up the pre-commit files - run("pre-commit clean") - # If second run fails, then we can't auto-fix if process.returncode != 0: @@ -511,8 +506,6 @@ def precommit(*, session, payload, arguments, local_config=None): ), ) - run("pip cache purge") - @admin def blackify(*, session, payload, arguments, local_config=None): diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index cc2e56b..25a05c7 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -14,7 +14,7 @@ from yieldbreaker import YieldBreaker from .scopes import Permission -from .utils import ACCEPT_HEADER_SYMMETRA, Authenticator, add_event +from .utils import ACCEPT_HEADER_SYMMETRA, Authenticator, add_event, clear_caches green = "\033[0;32m" yellow = "\033[0;33m" @@ -668,4 +668,9 @@ def start(self): self.server = tornado.httpserver.HTTPServer(self.application) self.server.listen(self.port) + # Clear caches once per day. + callback_time_ms = 1000 * 60 * 60 * 24 + clear_cache_callback = tornado.ioloop.PeriodicCallback(clear_caches, callback_time_ms) + clear_cache_callback.start() + IOLoop.instance().start() diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index dcc4eef..b0ea707 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -361,3 +361,11 @@ def create_issue( "https://api.github.com/repos/{}/{}/issues".format(org, repo), json=arguments, ) + + +def clear_caches(): + """Clear local caches""" + print("\n\n====Clearing all caches===") + run("pip cache purge") + run("pre-commit clean") + print("====Finished clearing caches===\n\n") From 93b5122cee33b4044699a42394842b778a9b1b79 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 12:05:01 -0500 Subject: [PATCH 086/153] update allowlist --- README.md | 4 ++-- meeseeksdev/__init__.py | 17 +++++++++++------ meeseeksdev/meeseeksbox/commands.py | 6 +++--- meeseeksdev/meeseeksbox/core.py | 6 +++--- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 6b2a786..5b1e247 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ sure MeeseeksDev is correctly installed. 3) Enjoy -Beta Phase: During Beta phase repository/users need to be vetted/whitelisted +Beta Phase: During Beta phase repository/users need to be vetted/allowlisted open an issue if you wish to participate. You might also want to tell your CI-integration (like travis-ci) **not** to test the **push** __and__ **the merge**. @@ -229,7 +229,7 @@ See CONTIBUTING.md for for information. # Warnings This is still alpha software, user and org that can use it are still hardcoded. -If you want access open an issue for me to whitelist your org and users. +If you want access open an issue for me to allowlist your org and users. Because of GitHub API limitation, MeeseeksBox can not yet make the distinction between read-only and read-write collaborators. diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 60a80d7..6f1534a 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -23,11 +23,15 @@ ) from .meeseeksbox.core import Config, MeeseeksBox -org_whitelist = [ +org_allowlist = [ "MeeseeksBox", "Jupyter", "IPython", "JupyterLab", + "jupyter-server", + "jupyter-widgets", + "voila-dashboards", + "jupyter-xeus", "Carreau", "matplotlib", "scikit-learn", @@ -35,9 +39,9 @@ "scikit-image", ] -usr_blacklist = [] +usr_denylist = [] -usr_whitelist = [ +usr_allowlist = [ "Carreau", "gnestor", "ivanov", @@ -57,6 +61,7 @@ "lgpage", "jasongrout", "ian-r-rose", + "kevin-bates", # matplotlib people "tacaswell", "QuLogic", @@ -145,9 +150,9 @@ def main(): keen.add_event("deploy", {"version": int(app_v[1:])}) except Exception as e: print(e) - config.org_whitelist = org_whitelist + [o.lower() for o in org_whitelist] - config.user_whitelist = usr_whitelist + [u.lower() for u in usr_whitelist] - config.user_blacklist = usr_blacklist + [u.lower() for u in usr_blacklist] + config.org_allowlist = org_allowlist + [o.lower() for o in org_allowlist] + config.user_allowlist = usr_allowlist + [u.lower() for u in usr_allowlist] + config.user_denylist = usr_denylist + [u.lower() for u in usr_denylist] commands = { "hello": replyuser, "zen": zen, diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 7de0044..0c8e04c 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -105,7 +105,7 @@ def replyadmin(*, session, payload, arguments, local_config=None): session.post_comment(comment_url, "Hello @{user}. Waiting for your orders.".format(user=user)) -def _compute_pwd_changes(whitelist): +def _compute_pwd_changes(allowlist): import glob from difflib import SequenceMatcher @@ -118,8 +118,8 @@ def _compute_pwd_changes(whitelist): print("== listdir", os.listdir()) for p in glob.glob("**/*.py", recursive=True): - print("=== scanning", p, p in whitelist) - if p not in whitelist: + print("=== scanning", p, p in allowlist) + if p not in allowlist: # we don't touch files not in this PR. continue p = Path(p) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 25a05c7..a1e7de1 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -177,11 +177,11 @@ def fn(req, url): ]: add_event("ignore_org_missing", {"edited": "reason"}) else: - if hasattr(self.config, "org_whitelist") and (org not in self.config.org_whitelist): + if hasattr(self.config, "org_allowlist") and (org not in self.config.org_allowlist): add_event("post", {"reject_organisation": org}) sender = payload.get("sender", {}).get("login", {}) - if hasattr(self.config, "user_blacklist") and (sender in self.config.user_blacklist): + if hasattr(self.config, "user_denylist") and (sender in self.config.user_denylist): add_event("post", {"blocked_user": sender}) self.finish("Blocked user.") return @@ -490,7 +490,7 @@ def user_can(user, command, repo, org, session): print(green + f"should test if {user} can {command} on {repo}/{org}" + normal) # print(green + json.dumps(conf, indent=2) + normal) - if user in conf.get("blacklisted_users", []): + if user in conf.get("denied_users", []): return False, {} user_section = conf.get("users", {}).get(user, {}) From d981cdc1af71f1e40fc6baa924c915e7ca0a248d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 28 Mar 2022 12:07:23 -0500 Subject: [PATCH 087/153] fix user denylist usage --- meeseeksdev/meeseeksbox/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index a1e7de1..681835b 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -490,7 +490,7 @@ def user_can(user, command, repo, org, session): print(green + f"should test if {user} can {command} on {repo}/{org}" + normal) # print(green + json.dumps(conf, indent=2) + normal) - if user in conf.get("denied_users", []): + if user in conf.get("usr_denylist", []): return False, {} user_section = conf.get("users", {}).get(user, {}) From 51f1549188c3d2f2fc7f3f063cd8b4de3577c36b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 29 Mar 2022 09:51:38 -0500 Subject: [PATCH 088/153] fix fix_issue_body --- meeseeksdev/meeseeksbox/utils.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index b0ea707..0f5230a 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -65,24 +65,14 @@ def fix_issue_body( ): """ This, for now does only simple fixes, like link to the original issue. - This should be improved to quote mention of people """ - body = RELINK_RE.sub("{org}/{repo}\\1".format(org=original_org, repo=original_repo), body) + body = RELINK_RE.sub(f"{original_org}/{original_repo}\\1", body) - return ( - body - + """\n\n---- - \nOriginally opened as {org}/{repo}#{number} by @{reporter}, migration requested by @{requester} + return f"""{body}\n\n---- + \nOriginally opened as {original_org}/{original_repo}#{original_number} by @{original_poster}, migration requested by @{migration_requester} """ - ).format( - org=original_org, - repo=original_repo, - number=original_number, - reporter=original_poster, - requester=migration_requester, - ) def fix_comment_body(body, original_poster, original_url, original_org, original_repo): From eaf757834a1070b7af0c02ca7a91ab6a3e1e0d45 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 29 Mar 2022 10:00:12 -0500 Subject: [PATCH 089/153] add stub for node.js buildpack --- package.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..40f0e07 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "name": "meeseeksdev", + "version": "1.0.0", + "description": "stub file for node.js buildpack", + "private": true +} From 13667cd9b546a04bb57ae50b28fdc03d88367d78 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 5 Apr 2022 04:22:52 -0500 Subject: [PATCH 090/153] fix spelling --- meeseeksdev/meeseeksbox/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 0c8e04c..647896f 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -441,7 +441,7 @@ def precommit(*, session, payload, arguments, local_config=None): if "repo: local" in config.read_text(): run("pip install --user -e .") - cmd = "pre_commit run --all-files --hook-stage=manual" + cmd = "pre-commit run --all-files --hook-stage=manual" # Run the command process = run(cmd) From 9037fe3b2d83affbf81c11c333e16a5fa6d71eb0 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 5 Apr 2022 04:36:25 -0500 Subject: [PATCH 091/153] UX fixes --- meeseeksdev/meeseeksbox/commands.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 647896f..fa30e98 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -345,9 +345,9 @@ def prep_for_command(name, session, payload, arguments, local_config=None): atk = session.token() session.post_comment( comment_url, - body="Would you mind installing me on your fork so that I can update your branch? \n" + body=f"@{author_login}, would you mind installing me on your fork so that I can update your branch? \n" "Click [here](https://github.com/apps/meeseeksdev/installations/new) " - "to do that, and follow the instructions to add your fork." + "to do that, and follow the instructions to add your fork. " "I'm going to try to push as a maintainer but this may not work.", ) @@ -387,6 +387,7 @@ def push_the_work(session, payload, arguments, local_config=None): prnumber = payload["issue"]["number"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] + comment_url = payload["issue"]["comments_url"] # collect extended payload on the PR print("== Collecting data on Pull-request...") @@ -405,7 +406,11 @@ def push_the_work(session, payload, arguments, local_config=None): # Push the work print("== Pushing work....:") print(f"pushing with workbranch:{branch}") - repo.remotes.origin.push("workbranch:{}".format(branch), force=True) + try: + repo.remotes.origin.push("workbranch:{}".format(branch), force=True) + except Exception: + session.post_comment(comment_url, body="I was unable to push due to errors") + return # Clean up default_branch = session.ghrequest( From 632e040c79e05459561edd7ea7b4c4b748188862 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 5 Apr 2022 07:43:41 -0500 Subject: [PATCH 092/153] fix handling of push failure --- meeseeksdev/meeseeksbox/commands.py | 50 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index fa30e98..2d4ecfa 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -387,7 +387,6 @@ def push_the_work(session, payload, arguments, local_config=None): prnumber = payload["issue"]["number"] org_name = payload["repository"]["owner"]["login"] repo_name = payload["repository"]["name"] - comment_url = payload["issue"]["comments_url"] # collect extended payload on the PR print("== Collecting data on Pull-request...") @@ -406,11 +405,11 @@ def push_the_work(session, payload, arguments, local_config=None): # Push the work print("== Pushing work....:") print(f"pushing with workbranch:{branch}") + succeeded = True try: repo.remotes.origin.push("workbranch:{}".format(branch), force=True) except Exception: - session.post_comment(comment_url, body="I was unable to push due to errors") - return + succeeded = False # Clean up default_branch = session.ghrequest( @@ -418,6 +417,7 @@ def push_the_work(session, payload, arguments, local_config=None): ).json()["default_branch"] repo.git.checkout(default_branch) repo.branches.workbranch.delete(repo, "workbranch", force=True) + return succeeded @admin @@ -497,19 +497,22 @@ def precommit(*, session, payload, arguments, local_config=None): ), ) - push_the_work(session, payload, arguments, local_config=local_config) + succeeded = push_the_work(session, payload, arguments, local_config=local_config) # Tell the caller we've finished comment_url = payload["issue"]["comments_url"] - session.post_comment( - comment_url, - body=dedent( + if succeeded: + session.post_comment( + comment_url, + body=dedent( + """ + I've applied "pre-commit" and pushed. You may have trouble pushing further + commits, but feel free to force push and ask me to run again. """ - I've applied "pre-commit" and pushed. You may have trouble pushing further - commits, but feel free to force push and ask me to run again. - """ - ), - ) + ), + ) + else: + session.post_comment(comment_url, body="I was unable to push due to errors") @admin @@ -566,19 +569,22 @@ def blackify(*, session, payload, arguments, local_config=None): ) return - push_the_work(session, payload, arguments, local_config=local_config) + succeeded = push_the_work(session, payload, arguments, local_config=local_config) # Tell the caller we've finished - session.post_comment( - comment_url, - body=dedent( + if succeeded: + session.post_comment( + comment_url, + body=dedent( + """ + I've rebased this Pull Request, applied `black` on all the + individual commits, and pushed. You may have trouble pushing further + commits, but feel free to force push and ask me to reformat again. """ - I've rebased this Pull Request, applied `black` on all the - individual commits, and pushed. You may have trouble pushing further - commits, but feel free to force push and ask me to reformat again. - """ - ), - ) + ), + ) + else: + session.post_comment(comment_url, body="I was unable to push due to errors") @write From 3d7f02b381f050aabf19463851495368f54c3178 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 5 Apr 2022 09:25:17 -0500 Subject: [PATCH 093/153] add handling of maintainer_can_modify --- meeseeksdev/meeseeksbox/commands.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 2d4ecfa..0589478 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -321,6 +321,7 @@ def prep_for_command(name, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] # collect extended payload on the PR + # https://docs.github.com/en/rest/reference/pulls#get-a-pull-request print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", @@ -332,9 +333,9 @@ def prep_for_command(name, session, payload, arguments, local_config=None): branch = pr_data["head"]["ref"] author_login = pr_data["head"]["repo"]["owner"]["login"] repo_name = pr_data["head"]["repo"]["name"] + maintainer_can_modify = pr_data["maintainer_can_modify"] - # that will likely fail, as if PR, we need to bypass the fact that the - # requester has technically no access to committer repo. + # Check to see if we can successfully push changees to the PR. target_session = yield "{}/{}".format(author_login, repo_name) if target_session: print("installed on target repository") @@ -342,14 +343,21 @@ def prep_for_command(name, session, payload, arguments, local_config=None): session.post_comment(comment_url, body=f"Running {name} on this Pull Request...") else: print("use allow edit as maintainer") + if maintainer_can_modify: + msg = "For now I will push as a maintainer since it is enabled." + else: + msg = 'I would push as a maintainer but I cannot unless "Allow edits from maintainers" is enabled for this Pull Request.' atk = session.token() session.post_comment( comment_url, - body=f"@{author_login}, would you mind installing me on your fork so that I can update your branch? \n" + body=f"@{author_login}, would you mind installing me on your fork so that I can update your branch?\n" "Click [here](https://github.com/apps/meeseeksdev/installations/new) " - "to do that, and follow the instructions to add your fork. " - "I'm going to try to push as a maintainer but this may not work.", + "to do that, and follow the instructions to add your fork.\n\n" + f"{msg}", ) + if not maintainer_can_modify: + print("=== Bailing since we do not have permissions") + return if os.path.exists(repo_name): print("== Cleaning up previous work ... ") From 77784ec69032912386b78a51bc1f88823a50d101 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 8 Apr 2022 03:44:48 -0500 Subject: [PATCH 094/153] make some hooks manual --- .github/workflows/build.yml | 9 ++------- .pre-commit-config.yaml | 2 ++ CONTRIBUTING.md | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 74aff2a..93f8841 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,15 +12,10 @@ jobs: # Run "pre-commit run --all-files" pre-commit: runs-on: ubuntu-20.04 - timeout-minutes: 2 - + timeout-minutes: 5 steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - # ref: https://github.com/pre-commit/action - uses: pre-commit/action@v2.0.0 - name: Help message if pre-commit fail if: ${{ failure() }} @@ -31,7 +26,7 @@ jobs: echo "or you can run by hand on staged files with" echo " pre-commit run" echo "or after-the-fact on already committed files with" - echo " pre-commit run --all-files" + echo " pre-commit run --all-files --hook-stage=manual" build: runs-on: ubuntu-latest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0fa8b58..cfbff1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,6 +34,7 @@ repos: 'flake8-logging-format==0.6.0', 'flake8-implicit-str-concat==0.2.0', ] + stages: [manual] - repo: https://github.com/sirosen/check-jsonschema rev: 0.10.2 @@ -43,3 +44,4 @@ repos: files: ^\.github/workflows/ types: [yaml] args: ["--schemafile", "https://json.schemastore.org/github-workflow"] + stages: [manual] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff15a8d..6c6cad1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,3 +60,38 @@ WEBHOOK_SECRET="" PERSONAL_ACCOUNT_NAME="" PERSONAL_ACCOUNT_TOKEN="" ``` + +### Code Styling + +`MeeseeksDev` has adopted automatic code formatting so you shouldn't +need to worry too much about your code style. +As long as your code is valid, +the pre-commit hook should take care of how it should look. +`pre-commit` and its associated hooks will automatically be installed when +you run `pip install -e ".[test]"` + +To install `pre-commit` manually, run the following:: + +```shell +pip install pre-commit +pre-commit install +``` + +You can invoke the pre-commit hook by hand at any time with: + +```shell +pre-commit run +``` + +which should run any autoformatting on your code +and tell you about any errors it couldn't fix automatically. +You may also install [black integration](https://github.com/psf/black#editor-integration) +into your text editor to format code automatically. + +If you have already committed files before setting up the pre-commit +hook with `pre-commit install`, you can fix everything up using +`pre-commit run --all-files`. You need to make the fixing commit +yourself after that. + +Some of the hooks only run on CI by default, but you can invoke them by +running with the `--hook-stage manual` argument. From ad33184e5359f9cd3a8aac35263fd18d63a0908e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 8 Apr 2022 03:47:25 -0500 Subject: [PATCH 095/153] update hooks --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cfbff1c..9de6e68 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.2.0 hooks: - id: check-builtin-literals - id: check-added-large-files @@ -13,20 +13,20 @@ repos: - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 22.1.0 + rev: 22.3.0 hooks: - id: black args: ["--line-length", "100"] - repo: https://github.com/PyCQA/isort - rev: 5.7.0 + rev: 5.10.1 hooks: - id: isort files: \.py$ args: [--profile=black] - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + rev: 3.9.2 hooks: - id: flake8 additional_dependencies: [ @@ -37,7 +37,7 @@ repos: stages: [manual] - repo: https://github.com/sirosen/check-jsonschema - rev: 0.10.2 + rev: 0.14.2 hooks: - id: check-jsonschema name: "Check GitHub Workflows" From 0fe47d87d5f815ea7c1a7e19950ce0e896e72389 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 8 Apr 2022 03:55:14 -0500 Subject: [PATCH 096/153] run manual checks in ci --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 93f8841..4919062 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,7 +9,7 @@ concurrency: cancel-in-progress: true jobs: - # Run "pre-commit run --all-files" + # Run "pre-commit run --all-files --hook-stage=manual" pre-commit: runs-on: ubuntu-20.04 timeout-minutes: 5 @@ -17,6 +17,8 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - uses: pre-commit/action@v2.0.0 + with: + extra_args: --all-files --hook-stage=manual - name: Help message if pre-commit fail if: ${{ failure() }} run: | From 0a2ac6ee050a1466409732b52c160bf634bc9d51 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sat, 9 Apr 2022 09:18:59 -0500 Subject: [PATCH 097/153] add mypy support --- .github/workflows/connect.py | 2 +- .mypy.ini | 35 ++++++++++++++++ .pre-commit-config.yaml | 8 ++++ meeseeksdev/__init__.py | 10 ++--- meeseeksdev/commands.py | 5 ++- meeseeksdev/meeseeksbox/commands.py | 40 +++++++++++++------ meeseeksdev/meeseeksbox/core.py | 17 ++++---- meeseeksdev/meeseeksbox/utils.py | 62 +++++++++++++++++++---------- meeseeksdev/tests/test_misc.py | 4 +- meeseeksdev/tests/test_webhook.py | 2 +- 10 files changed, 134 insertions(+), 51 deletions(-) create mode 100644 .mypy.ini diff --git a/.github/workflows/connect.py b/.github/workflows/connect.py index 7ccf815..392efe6 100644 --- a/.github/workflows/connect.py +++ b/.github/workflows/connect.py @@ -13,7 +13,7 @@ found = True break except URLError as e: - if e.reason.errno == errno.ECONNREFUSED: + if e.reason.errno == errno.ECONNREFUSED: # type:ignore time.sleep(1) continue raise diff --git a/.mypy.ini b/.mypy.ini new file mode 100644 index 0000000..a473347 --- /dev/null +++ b/.mypy.ini @@ -0,0 +1,35 @@ +[mypy] +check_untyped_defs = true +disallow_incomplete_defs = true +no_implicit_optional = true +pretty = true +show_error_context = true +show_error_codes = true +strict_equality = true +strict_optional = true +warn_no_return = true +warn_return_any = true +warn_unused_configs = true +warn_unused_ignores = true +warn_redundant_casts = true + +[mypy-black] +ignore_missing_imports = True + +[mypy-jwt] +ignore_missing_imports = True + +[mypy-git] +ignore_missing_imports = True + +[mypy-keen] +ignore_missing_imports = True + +[mypy-pytest] +ignore_missing_imports = True + +[mypy-there] +ignore_missing_imports = True + +[mypy-yieldbreaker] +ignore_missing_imports = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9de6e68..66bef1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,14 @@ repos: ] stages: [manual] +- repo: https://github.com/pre-commit/mirrors-mypy + rev: "v0.942" + hooks: + - id: mypy + args: ["--config-file", ".mypy.ini"] + additional_dependencies: [types-requests, types-PyYAML, types-mock, tornado] + stages: [manual] + - repo: https://github.com/sirosen/check-jsonschema rev: 0.14.2 hooks: diff --git a/meeseeksdev/__init__.py b/meeseeksdev/__init__.py index 6f1534a..d8ee694 100644 --- a/meeseeksdev/__init__.py +++ b/meeseeksdev/__init__.py @@ -39,7 +39,7 @@ "scikit-image", ] -usr_denylist = [] +usr_denylist: list = [] usr_allowlist = [ "Carreau", @@ -91,12 +91,12 @@ def load_config_from_env(): """ Load the configuration, for now stored in the environment """ - config = {} + config: dict = {} - integration_id = os.environ.get("GITHUB_INTEGRATION_ID") + integration_id_str = os.environ.get("GITHUB_INTEGRATION_ID") botname = os.environ.get("GITHUB_BOT_NAME", None) - if not integration_id: + if not integration_id_str: raise ValueError("Please set GITHUB_INTEGRATION_ID") if not botname: @@ -106,7 +106,7 @@ def load_config_from_env(): botname = botname.replace("@", "") at_botname = "@" + botname - integration_id = int(integration_id) + integration_id = int(integration_id_str) if "B64KEY" in os.environ: config["key"] = base64.b64decode(bytes(os.environ["B64KEY"], "ASCII")) diff --git a/meeseeksdev/commands.py b/meeseeksdev/commands.py index d04d0e5..babc56c 100644 --- a/meeseeksdev/commands.py +++ b/meeseeksdev/commands.py @@ -3,6 +3,7 @@ """ from textwrap import dedent +from typing import Generator, Optional from .meeseeksbox.commands import tag, untag from .meeseeksbox.scopes import everyone, pr_author, write @@ -49,7 +50,9 @@ def open(*, session, payload, arguments, local_config=None): @write -def migrate_issue_request(*, session: Session, payload: dict, arguments: str, local_config=None): +def migrate_issue_request( + *, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None +) -> Generator: """[to] {org}/{repo} Need to be admin on target repo. Replicate all comments on target repo and close current on. diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 0589478..3a4cf44 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -11,6 +11,7 @@ import traceback from pathlib import Path from textwrap import dedent +from typing import Generator, Optional import git import mock @@ -117,12 +118,12 @@ def _compute_pwd_changes(allowlist): print("== pwd", os.getcwd()) print("== listdir", os.listdir()) - for p in glob.glob("**/*.py", recursive=True): - print("=== scanning", p, p in allowlist) - if p not in allowlist: + for path in glob.glob("**/*.py", recursive=True): + print("=== scanning", path, path in allowlist) + if path not in allowlist: # we don't touch files not in this PR. continue - p = Path(p) + p = Path(path) old = p.read_text() new = black.format_str(old, mode=black.FileMode()) if new != old: @@ -309,7 +310,9 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Done cleaning ") -def prep_for_command(name, session, payload, arguments, local_config=None): +def prep_for_command( + name: str, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None +) -> Generator: """Prepare to run a command against a local checkout of a repo.""" print(f"===== running command {name} =====") print("===== ============ =====") @@ -335,8 +338,11 @@ def prep_for_command(name, session, payload, arguments, local_config=None): repo_name = pr_data["head"]["repo"]["name"] maintainer_can_modify = pr_data["maintainer_can_modify"] + print(f"Got author login {author_login}") + # Check to see if we can successfully push changees to the PR. target_session = yield "{}/{}".format(author_login, repo_name) + if target_session: print("installed on target repository") atk = target_session.token() @@ -429,7 +435,9 @@ def push_the_work(session, payload, arguments, local_config=None): @admin -def precommit(*, session, payload, arguments, local_config=None): +def precommit( + *, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None +) -> Generator: comment_url = payload["issue"]["comments_url"] """Run pre-commit against a PR and push the changes.""" @@ -602,12 +610,13 @@ def safe_backport(session, payload, arguments, local_config=None): print = lambda *args, **kwargs: builtins.print(" [backport]", *args, **kwargs) - s_clone_time = 0 + s_clone_time = 0.0 s_success = False s_reason = "unknown" - s_fork_time = 0 - s_clean_time = 0 - s_ff_time = 0 + s_fork_time = 0.0 + s_clean_time = 0.0 + s_ff_time = 0.0 + s_slug = "" def keen_stats(): nonlocal s_slug @@ -816,7 +825,7 @@ def keen_stats(): print("== All has been fetched correctly") print("Cherry-picking %s" % merge_sha) - args = ("-x", "-m", "1", merge_sha) + args: tuple = ("-x", "-m", "1", merge_sha) msg = "Backport PR #%i: %s" % (prnumber, prtitle) remote_submit_branch = f"auto-backport-of-pr-{prnumber}-on-{target_branch}" @@ -925,7 +934,10 @@ def keen_stats(): session.post_comment( comment_url, "Hum, I actually crashed, that should not have happened." ) - print("\n" + e.stderr.decode("utf8", "replace"), file=sys.stderr) + if hasattr(e, "stderr"): + print( + "\n" + e.stderr.decode("utf8", "replace"), file=sys.stderr + ) # type:ignore[attr-defined] print("\n" + repo.git.status(), file=sys.stderr) add_event("error", {"git_crash": 1}) s_reason = "Unknown error line 501" @@ -1133,7 +1145,9 @@ def untag(session, payload, arguments, local_config=None): @write -def migrate_issue_request(*, session: Session, payload: dict, arguments: str, local_config=None): +def migrate_issue_request( + *, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None +) -> Generator: """Todo: - Works through pagination of comments diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 681835b..c8bbd03 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -4,7 +4,9 @@ import json import re import time +from asyncio import Future from concurrent.futures import ThreadPoolExecutor as Pool +from typing import Optional import tornado.httpserver import tornado.ioloop @@ -26,7 +28,7 @@ class Config: botname = None - integration_id = None + integration_id = -1 key = None botname = None at_botname = None @@ -79,7 +81,7 @@ def _strip_extras(c): return c -def process_mentionning_comment(body, bot_re): +def process_mentioning_comment(body: str, bot_re: re.Pattern) -> list: """ Given a comment body and a bot name parse this into a tuple of (command, arguments) """ @@ -233,7 +235,7 @@ def mention_bot_re(self): botname = self.config.botname return re.compile("@?" + re.escape(botname) + r"(?:\[bot\])?", re.IGNORECASE) - def dispatch_action(self, type_, payload): + def dispatch_action(self, type_: str, payload: dict) -> Future: botname = self.config.botname repo = payload.get("repository", {}).get("full_name", red + "" + normal) # new issue/PR opened @@ -349,13 +351,13 @@ def dispatch_action(self, type_, payload): milestone = is_pr.get("milestone", {}) if milestone: description.append(milestone.get("description", "") or "") - description = "\n".join(description) + description_str = "\n".join(description) if "on-merge:" in description and is_pr["base"]["ref"] in ( "master", "main", ): did_backport = False - for description_line in description.splitlines(): + for description_line in description_str.splitlines(): line = description_line.strip() if line.startswith("on-merge:"): todo = line[len("on-merge:") :].strip() @@ -381,6 +383,7 @@ def dispatch_action(self, type_, payload): else: pass # print(f"({repo}) can't deal with `{type_}` yet") + return self.finish() # def _action_allowed(args): # """ @@ -393,7 +396,7 @@ def dispatch_action(self, type_, payload): # - If pull-request, the requester is the author. # """ - def dispatch_on_mention(self, body, payload, user): + def dispatch_on_mention(self, body: str, payload: dict, user: str) -> None: """ Core of the logic that let people require actions from the bot. @@ -445,7 +448,7 @@ def dispatch_on_mention(self, body, payload, user): print(user, "is legitimate author of this PR, letting commands go through") permission_level = session._get_permission(org, repo, user) - command_args = process_mentionning_comment(body, self.mention_bot_re) + command_args = process_mentioning_comment(body, self.mention_bot_re) for (command, arguments) in command_args: print(" :: treating", command, arguments) add_event( diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 0f5230a..54895d4 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -7,6 +7,7 @@ import re import shlex import subprocess +from typing import Any, Dict, Optional, cast import jwt import requests @@ -90,7 +91,13 @@ def fix_comment_body(body, original_poster, original_url, original_org, original class Authenticator: - def __init__(self, integration_id, rsadata, personal_account_token, personal_account_name): + def __init__( + self, + integration_id: int, + rsadata: Optional[str], + personal_account_token: Optional[str], + personal_account_name: Optional[str], + ): self.since = int(datetime.datetime.now().timestamp()) self.duration = 60 * 10 self._token = None @@ -100,10 +107,10 @@ def __init__(self, integration_id, rsadata, personal_account_token, personal_acc self.personal_account_name = personal_account_name # TODO: this mapping is built at startup, we should update it when we # have new / deleted installations - self.idmap = {} + self.idmap: Dict[str, str] = {} self._session_class = Session - def session(self, installation_id): + def session(self, installation_id: str) -> "Session": """ Given and installation id, return a session with the right credentials """ @@ -117,7 +124,7 @@ def session(self, installation_id): self.personal_account_name, ) - def list_installations(self): + def list_installations(self) -> Any: """ Todo: Pagination """ @@ -198,13 +205,14 @@ def __init__( super().__init__(integration_id, rsadata, personal_account_token, personal_account_name) self.installation_id = installation_id - def token(self): + def token(self) -> str: now = datetime.datetime.now().timestamp() if (now > self.since + self.duration - 60) or (self._token is None): self.regen_token() + assert self._token is not None return self._token - def regen_token(self): + def regen_token(self) -> None: method = "POST" url = f"https://api.github.com/app/installations/{self.installation_id}/access_tokens" resp = self._integration_authenticated_request(method, url) @@ -216,7 +224,9 @@ def regen_token(self): except Exception: raise ValueError(resp.content, url) - def personal_request(self, method, url, json=None, raise_for_status=True): + def personal_request( + self, method: str, url: str, json: Optional[dict] = None, raise_for_status: bool = True + ) -> requests.Response: """ Does a request but using the personal account name and token """ @@ -243,13 +253,13 @@ def prepare(): def ghrequest( self, - method, - url, - json=None, + method: str, + url: str, + json: Optional[dict] = None, *, - override_accept_header=None, - raise_for_status=True, - ): + override_accept_header: Optional[str] = None, + raise_for_status: Optional[bool] = True, + ) -> requests.Response: accept = ACCEPT_HEADER if override_accept_header: accept = override_accept_header @@ -294,7 +304,7 @@ def prepare(): ) return response - def _get_permission(self, org, repo, username): + def _get_permission(self, org: str, repo: str, username: str) -> Permission: get_collaborators_query = API_COLLABORATORS_TEMPLATE.format( org=org, repo=repo, username=username ) @@ -307,19 +317,21 @@ def _get_permission(self, org, repo, username): resp.raise_for_status() permission = resp.json()["permission"] print("found permission", permission, "for user ", username, "on ", org, repo) - return getattr(Permission, permission) + return cast(Permission, getattr(Permission, permission)) - def has_permission(self, org, repo, username, level=None): + def has_permission( + self, org: str, repo: str, username: str, level: Optional[Permission] = None + ) -> bool: """ """ if not level: level = Permission.none return self._get_permission(org, repo, username).value >= level.value - def post_comment(self, comment_url, body): + def post_comment(self, comment_url: str, body: str) -> None: self.ghrequest("POST", comment_url, json={"body": body}) - def get_collaborator_list(self, org, repo): + def get_collaborator_list(self, org: str, repo: str) -> Optional[Any]: get_collaborators_query = "https://api.github.com/repos/{org}/{repo}/collaborators".format( org=org, repo=repo ) @@ -328,11 +340,19 @@ def get_collaborator_list(self, org, repo): return resp.json() else: resp.raise_for_status() + return None def create_issue( - self, org: str, repo: str, title: str, body: str, *, labels=None, assignees=None - ): - arguments = {"title": title, "body": body} + self, + org: str, + repo: str, + title: str, + body: str, + *, + labels: Optional[list] = None, + assignees: Optional[list] = None, + ) -> requests.Response: + arguments: dict = {"title": title, "body": body} if labels: if type(labels) in (list, tuple): diff --git a/meeseeksdev/tests/test_misc.py b/meeseeksdev/tests/test_misc.py index bc6c7f6..b474cf3 100644 --- a/meeseeksdev/tests/test_misc.py +++ b/meeseeksdev/tests/test_misc.py @@ -1,7 +1,7 @@ import re import textwrap -from ..meeseeksbox.core import process_mentionning_comment +from ..meeseeksbox.core import process_mentioning_comment def test1(): @@ -9,7 +9,7 @@ def test1(): reg = re.compile("@?" + re.escape(botname) + r"(?:\[bot\])?", re.IGNORECASE) assert ( - process_mentionning_comment( + process_mentioning_comment( textwrap.dedent( """ @meeseeksdev nothing diff --git a/meeseeksdev/tests/test_webhook.py b/meeseeksdev/tests/test_webhook.py index 29edab3..2639136 100644 --- a/meeseeksdev/tests/test_webhook.py +++ b/meeseeksdev/tests/test_webhook.py @@ -5,7 +5,7 @@ from ..meeseeksbox.core import Authenticator, Config, WebHookHandler -commands = {} +commands: dict = {} config = Config( integration_id=100, From e5d445ea163dde80c5544a225d9655812d237ea9 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sat, 9 Apr 2022 09:25:16 -0500 Subject: [PATCH 098/153] pre-commit --- meeseeksdev/meeseeksbox/commands.py | 5 +++-- meeseeksdev/meeseeksbox/core.py | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 3a4cf44..8b261da 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -936,8 +936,9 @@ def keen_stats(): ) if hasattr(e, "stderr"): print( - "\n" + e.stderr.decode("utf8", "replace"), file=sys.stderr - ) # type:ignore[attr-defined] + "\n" + e.stderr.decode("utf8", "replace"), # type:ignore[attr-defined] + file=sys.stderr, + ) print("\n" + repo.git.status(), file=sys.stderr) add_event("error", {"git_crash": 1}) s_reason = "Unknown error line 501" diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index c8bbd03..3629603 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -6,7 +6,6 @@ import time from asyncio import Future from concurrent.futures import ThreadPoolExecutor as Pool -from typing import Optional import tornado.httpserver import tornado.ioloop From 69bac99d6665147cd9e9f90bbd280c42e8f8b2b7 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sat, 9 Apr 2022 09:36:05 -0500 Subject: [PATCH 099/153] improve support --- .mypy.ini | 12 ------------ .pre-commit-config.yaml | 2 +- meeseeksdev/meeseeksbox/commands.py | 4 ++-- meeseeksdev/meeseeksbox/utils.py | 1 + 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/.mypy.ini b/.mypy.ini index a473347..3767677 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -13,21 +13,9 @@ warn_unused_configs = true warn_unused_ignores = true warn_redundant_casts = true -[mypy-black] -ignore_missing_imports = True - -[mypy-jwt] -ignore_missing_imports = True - -[mypy-git] -ignore_missing_imports = True - [mypy-keen] ignore_missing_imports = True -[mypy-pytest] -ignore_missing_imports = True - [mypy-there] ignore_missing_imports = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66bef1c..e5ba856 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: hooks: - id: mypy args: ["--config-file", ".mypy.ini"] - additional_dependencies: [types-requests, types-PyYAML, types-mock, tornado] + additional_dependencies: [types-requests, types-PyYAML, types-mock, tornado, black, pytest, gitpython, pyjwt] stages: [manual] - repo: https://github.com/sirosen/check-jsonschema diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 8b261da..cf2f369 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -430,7 +430,7 @@ def push_the_work(session, payload, arguments, local_config=None): "GET", f"https://api.github.com/repos/{org_name}/{repo_name}" ).json()["default_branch"] repo.git.checkout(default_branch) - repo.branches.workbranch.delete(repo, "workbranch", force=True) + repo.branches.workbranch.delete(repo, "workbranch", force=True) # type:ignore[attr-defined] return succeeded @@ -971,7 +971,7 @@ def keen_stats(): # TODO comment on issue print(e) repo.git.checkout(default_branch) - repo.branches.workbranch.delete(repo, "workbranch", force=True) + repo.branches.workbranch.delete(repo, "workbranch", force=True) # type:ignore[attr-defined] # TODO checkout the default_branch and get rid of branch diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 54895d4..a108c63 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -175,6 +175,7 @@ def _integration_authenticated_request(self, method, url): } ) + assert self.rsadata is not None tok = jwt.encode(payload, key=self.rsadata, algorithm="RS256") headers = { From 7cc8f8faeddf543ace875b4f038eae4310f6b810 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sat, 9 Apr 2022 09:37:55 -0500 Subject: [PATCH 100/153] remove extra comment --- meeseeksdev/meeseeksbox/commands.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index cf2f369..e801494 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -338,8 +338,6 @@ def prep_for_command( repo_name = pr_data["head"]["repo"]["name"] maintainer_can_modify = pr_data["maintainer_can_modify"] - print(f"Got author login {author_login}") - # Check to see if we can successfully push changees to the PR. target_session = yield "{}/{}".format(author_login, repo_name) From e49adacd8126a13fca4538d952cfbb8e0278cbce Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sat, 9 Apr 2022 10:27:10 -0500 Subject: [PATCH 101/153] handle push errors --- meeseeksdev/meeseeksbox/commands.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 0589478..3e8421e 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -415,7 +415,7 @@ def push_the_work(session, payload, arguments, local_config=None): print(f"pushing with workbranch:{branch}") succeeded = True try: - repo.remotes.origin.push("workbranch:{}".format(branch), force=True) + repo.remotes.origin.push("workbranch:{}".format(branch), force=True).raise_if_error() except Exception: succeeded = False @@ -943,11 +943,12 @@ def keen_stats(): # Push the backported work print("== Pushing work....:") + succeeded = True try: print(f"Trying to push to {remote_submit_branch} of {session.personal_account_name}") repo.remotes[session.personal_account_name].push( "workbranch:{}".format(remote_submit_branch) - ) + ).raise_if_error() except Exception as e: import traceback @@ -955,13 +956,21 @@ def keen_stats(): print("could not push to self remote") s_reason = "Could not push" keen_stats() - # TODO comment on issue + + session.post_comment( + comment_url, f"Could not push to {remote_submit_branch} due to error, aborting." + ) print(e) + succeeded = False + repo.git.checkout(default_branch) repo.branches.workbranch.delete(repo, "workbranch", force=True) # TODO checkout the default_branch and get rid of branch + if not succeeded: + return + # Make the PR on GitHub print( "try to create PR with milestone", From 48ceb388ca10ee48c15fceb76a70e5b783e6b457 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sat, 9 Apr 2022 11:02:16 -0500 Subject: [PATCH 102/153] better auth handling add debug fix index try again try again fix index try again try again try again try again cleanup clean up startup one more cleanup update contrib doc finish --- CONTRIBUTING.md | 8 ++- meeseeksdev/meeseeksbox/commands.py | 6 +- meeseeksdev/meeseeksbox/core.py | 11 ++-- meeseeksdev/meeseeksbox/utils.py | 88 +++++++++++++++++++---------- 4 files changed, 74 insertions(+), 39 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6c6cad1..deda0a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,11 +26,17 @@ heroku git:remote -a meeseeksdev-$USER Then run: -``` +```bash git push heroku $(git rev-parse --abbrev-ref HEAD):master heroku open ``` +To view the logs in a terminal window, use: + +```bash +heroku logs --app meeseeksdev=$USER -t +``` + ### GitHub App Configuration Create a GitHub App for testing on your account diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 787fdd3..4810a74 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -419,7 +419,9 @@ def push_the_work(session, payload, arguments, local_config=None): print(f"pushing with workbranch:{branch}") succeeded = True try: - repo.remotes.origin.push("workbranch:{}".format(branch), force=True).raise_if_error() + repo.remotes.origin.push( + "workbranch:{}".format(branch), force=True + ).raise_if_error() # type:ignore[operator] except Exception: succeeded = False @@ -957,7 +959,7 @@ def keen_stats(): succeeded = True try: print(f"Trying to push to {remote_submit_branch} of {session.personal_account_name}") - repo.remotes[session.personal_account_name].push( + repo.remotes[session.personal_account_name].push( # type:ignore[operator] "workbranch:{}".format(remote_submit_branch) ).raise_if_error() except Exception as e: diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 3629603..3d9ef47 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -575,9 +575,9 @@ def user_can(user, command, repo, org, session): gen = YieldBreaker(maybe_gen) for org_repo in gen: torg, trepo = org_repo.split("/") - session_id = self.auth.idmap.get(org_repo) - if session_id: - target_session = self.auth.session(session_id) + target_session = self.auth.get_session(org_repo) + + if target_session: # TODO, if PR, admin and request is on source repo, allows anyway. # we may need to also check allow edit from maintainer and provide # another decorator for safety. @@ -631,7 +631,6 @@ def __init__(self, commands, config): self.config.personal_account_token, self.config.personal_account_name, ) - self.auth._build_auth_id_mapping() def sig_handler(self, sig, frame): print(yellow, "Caught signal: %s, Shutting down..." % sig, normal) @@ -675,4 +674,6 @@ def start(self): clear_cache_callback = tornado.ioloop.PeriodicCallback(clear_caches, callback_time_ms) clear_cache_callback.start() - IOLoop.instance().start() + loop = IOLoop.instance() + loop.add_callback(self.auth._build_auth_id_mapping) + loop.start() diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index a108c63..866ec11 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -105,9 +105,8 @@ def __init__( self.rsadata = rsadata self.personal_account_token = personal_account_token self.personal_account_name = personal_account_name - # TODO: this mapping is built at startup, we should update it when we - # have new / deleted installations self.idmap: Dict[str, str] = {} + self._org_idmap: Dict[str, str] = {} self._session_class = Session def session(self, installation_id: str) -> "Session": @@ -124,24 +123,38 @@ def session(self, installation_id: str) -> "Session": self.personal_account_name, ) + def get_session(self, org_repo): + """Given an org and repo, return a session with the right credentials.""" + # First try - see if we already have the auth. + if org_repo in self.idmap: + return self.session(self.idmap[org_repo]) + + # Next try - see if this is a newly authorized repo in an + # org that we've seen. + org, _ = org_repo.split("/") + if org in self._org_idmap: + self._update_installation(self._org_idmap[org]) + if org_repo in self.idmap: + return self.session(self.idmap[org_repo]) + + # TODO: if we decide to allow any org without an allowlist, + # we should make the org list dynamic. We would re-scan + # the list of installations here and update our mappings. + def list_installations(self) -> Any: - """ - Todo: Pagination - """ - # import json - # response = self._integration_authenticated_request( - # 'GET', "https://api.github.com/integration/installations") - # print(yellow+'list installation') - # print('HEADER', response.headers) - - response2 = self._integration_authenticated_request( - "GET", "https://api.github.com/app/installations" - ) + """List the installations for the app.""" + installations = [] + + url = "https://api.github.com/app/installations" + while True: + response = self._integration_authenticated_request("GET", url) + installations.extend(response.json()) + if "next" in response.links: + url = response.links["next"]["url"] + continue + break - # print(yellow+'list app installation') - # print('HEADER II', response2.headers) - # print('Content II', response2.json()) - return response2.json() + return installations def _build_auth_id_mapping(self): """ @@ -151,21 +164,33 @@ def _build_auth_id_mapping(self): if not self.rsadata: print("Skipping auth_id_mapping build since there is no B64KEY set") return - installations = self.list_installations() - for installation in installations: - iid = installation["id"] - session = self.session(iid) - try: - repositories = session.ghrequest( - "GET", installation["repositories_url"], json=None - ).json() + + self._installations = self.list_installations() + for installation in self._installations: + self._update_installation(installation) + + def _update_installation(self, installation): + iid = installation["id"] + session = self.session(iid) + try: + # Make sure we get all pages. + url = installation["repositories_url"] + while True: + res = session.ghrequest("GET", url) + repositories = res.json() for repo in repositories["repositories"]: self.idmap[repo["full_name"]] = iid - except Forbidden: - print("Forbidden for", iid) - continue + self._org_idmap[repo["owner"]["login"]] = iid + if "next" in res.links: + url = res.links["next"]["url"] + continue + break + + except Forbidden: + print("Forbidden for", iid) + return - def _integration_authenticated_request(self, method, url): + def _integration_authenticated_request(self, method, url, json=None): self.since = int(datetime.datetime.now().timestamp()) payload = dict( { @@ -184,7 +209,7 @@ def _integration_authenticated_request(self, method, url): "Host": "api.github.com", "User-Agent": "python/requests", } - req = requests.Request(method, url, headers=headers) + req = requests.Request(method, url, headers=headers, json=json) prepared = req.prepare() with requests.Session() as s: return s.send(prepared) @@ -273,6 +298,7 @@ def prepare(): "Host": "api.github.com", "User-Agent": "python/requests", } + print(f"Making a {method} call to {url}") req = requests.Request(method, url, headers=headers, json=json) return req.prepare() From dfde8fa6a59a30e57d7fdc9f9f3951c013299cec Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 12 Apr 2022 07:24:17 +0200 Subject: [PATCH 103/153] bump git python version, only recent version have raise_if_error --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9afa358..48f6241 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ tornado==6.1 requests==2.27 pyjwt==2.3 -gitpython==3.1 +gitpython==3.1.27 there==0.0.9 mock==4.0 cryptography==36.0 From 7555f965a9bf1d997e24721c0a6bd27dcd2cae96 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 24 Apr 2022 12:17:39 -0500 Subject: [PATCH 104/153] avoid printing the token --- meeseeksdev/meeseeksbox/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 4810a74..5b6b360 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -965,7 +965,9 @@ def keen_stats(): except Exception as e: import traceback - traceback.print_exc() + content = traceback.format_exc() + print(content.replace(session.personal_account_token, "...")) + print("could not push to self remote") s_reason = "Could not push" keen_stats() From 9d35c80e22bbd7f4daf51b5ab0930ab808e673de Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 26 Apr 2022 02:14:26 -0400 Subject: [PATCH 105/153] Debug non-backporting PRs --- meeseeksdev/meeseeksbox/core.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 3d9ef47..b42d5c3 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -372,6 +372,10 @@ def dispatch_action(self, type_: str, payload: dict) -> Future: 'Is "on-merge:" on a separate line?', ) print(description) + else: + print(f'PR is not targeting main/master branch ({is_pr["base"]["ref"]}),' + 'or "on-merge:" not in milestone (or label) description:') + print(description) else: print(f"({repo}) Hum, closed, PR but not merged") else: From dd4467b4cade69b12728f8ca13fa8c8823f6a601 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 26 Apr 2022 02:32:45 -0400 Subject: [PATCH 106/153] Fix formatting --- meeseeksdev/meeseeksbox/core.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index b42d5c3..00ead70 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -373,8 +373,10 @@ def dispatch_action(self, type_: str, payload: dict) -> Future: ) print(description) else: - print(f'PR is not targeting main/master branch ({is_pr["base"]["ref"]}),' - 'or "on-merge:" not in milestone (or label) description:') + print( + f'PR is not targeting main/master branch ({is_pr["base"]["ref"]}),' + 'or "on-merge:" not in milestone (or label) description:' + ) print(description) else: print(f"({repo}) Hum, closed, PR but not merged") From cc39a7787a7e231458d4674da07b8f4f03cbac85 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Fri, 6 May 2022 18:17:11 -0400 Subject: [PATCH 107/153] FIX: missed renames from mypy adoption need to search for "on-merge:" in description_str (which is a string) not in description (which is still a list that contains strings that may contain "on-merge:") --- meeseeksdev/meeseeksbox/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 00ead70..ba266f6 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -351,7 +351,7 @@ def dispatch_action(self, type_: str, payload: dict) -> Future: if milestone: description.append(milestone.get("description", "") or "") description_str = "\n".join(description) - if "on-merge:" in description and is_pr["base"]["ref"] in ( + if "on-merge:" in description_str and is_pr["base"]["ref"] in ( "master", "main", ): @@ -371,13 +371,13 @@ def dispatch_action(self, type_: str, payload: dict) -> Future: '"on-merge:" found in milestone description, but unable to parse command.', 'Is "on-merge:" on a separate line?', ) - print(description) + print(description_str) else: print( f'PR is not targeting main/master branch ({is_pr["base"]["ref"]}),' 'or "on-merge:" not in milestone (or label) description:' ) - print(description) + print(description_str) else: print(f"({repo}) Hum, closed, PR but not merged") else: From 490df2ca95062ad296d6046c58517fa5a635dc19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 May 2022 05:56:07 +0000 Subject: [PATCH 108/153] Bump pyjwt from 2.3 to 2.4.0 Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.3 to 2.4.0. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.3.0...2.4.0) --- updated-dependencies: - dependency-name: pyjwt dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 48f6241..4c20e62 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ tornado==6.1 requests==2.27 -pyjwt==2.3 +pyjwt==2.4.0 gitpython==3.1.27 there==0.0.9 mock==4.0 From 2dfdb4ac70cfa0cd6b9f2b17f592ae7d3d1a22da Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Wed, 19 Oct 2022 15:41:50 -0400 Subject: [PATCH 109/153] README: Stats link, change log date --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b1e247..c075725 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A base for stateless GitHub Bot,and one hosted implementation thereof. See what is a [Meeseeks and a MeeseeksBox](https://www.youtube.com/watch?v=qUYvIAP3qQk). +See [usage statistics](https://meeseeksbox.github.io/). + ## Hosted for you We host MeeseeksBox(es) and will expose them as GitHub Integrations so you don't @@ -242,4 +244,4 @@ heroku addons:create keen ## Changelog - Oct 31st, Backport now support squash-merge +* 2017-10-31: Backport now support squash-merge From 0b06c72ad16a89d2d7e78e0fe0073b1e2edf3e2a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 7 Nov 2022 09:45:59 -0600 Subject: [PATCH 110/153] Bump tornado version (#90) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4c20e62..7e129f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -tornado==6.1 +tornado==6.2 requests==2.27 pyjwt==2.4.0 gitpython==3.1.27 From 8e1e20256d9ada25d8f9b0f248fb3d9e30e8b5f8 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 7 Nov 2022 09:50:39 -0600 Subject: [PATCH 111/153] update runtime version --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 30e81e3..2fef004 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.10.3 +python-3.10.8 \ No newline at end of file From 6f7d4aa8c89be79cf1f25ec6f53e712f635e2e93 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 25 Nov 2022 06:41:01 -0600 Subject: [PATCH 112/153] Fix handling of backport merge conflicts (#91) --- .pre-commit-config.yaml | 130 ++++++++++++++++------------ README.md | 32 +++---- meeseeksdev/commands.py | 12 ++- meeseeksdev/meeseeksbox/commands.py | 85 ++++++++++-------- meeseeksdev/meeseeksbox/core.py | 4 +- meeseeksdev/meeseeksbox/utils.py | 14 +-- meeseeksdev/tests/test_webhook.py | 5 +- requirements.txt | 20 ++--- runtime.txt | 2 +- 9 files changed, 173 insertions(+), 131 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e5ba856..6e48e90 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,55 +1,77 @@ +default_language_version: + node: system + repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 - hooks: - - id: check-builtin-literals - - id: check-added-large-files - - id: check-case-conflict - - id: check-toml - - id: check-yaml - - id: debug-statements - - id: end-of-file-fixer - - id: forbid-new-submodules - - id: trailing-whitespace - -- repo: https://github.com/psf/black - rev: 22.3.0 - hooks: - - id: black - args: ["--line-length", "100"] - -- repo: https://github.com/PyCQA/isort - rev: 5.10.1 - hooks: - - id: isort - files: \.py$ - args: [--profile=black] - -- repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.2 - hooks: - - id: flake8 - additional_dependencies: [ - 'flake8-bugbear==20.1.4', - 'flake8-logging-format==0.6.0', - 'flake8-implicit-str-concat==0.2.0', - ] - stages: [manual] - -- repo: https://github.com/pre-commit/mirrors-mypy - rev: "v0.942" - hooks: - - id: mypy - args: ["--config-file", ".mypy.ini"] - additional_dependencies: [types-requests, types-PyYAML, types-mock, tornado, black, pytest, gitpython, pyjwt] - stages: [manual] - -- repo: https://github.com/sirosen/check-jsonschema - rev: 0.14.2 - hooks: - - id: check-jsonschema - name: "Check GitHub Workflows" - files: ^\.github/workflows/ - types: [yaml] - args: ["--schemafile", "https://json.schemastore.org/github-workflow"] - stages: [manual] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: end-of-file-fixer + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: requirements-txt-fixer + - id: check-added-large-files + - id: check-case-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: forbid-new-submodules + - id: check-builtin-literals + - id: trailing-whitespace + + - repo: https://github.com/psf/black + rev: 22.10.0 + hooks: + - id: black + args: ["--line-length", "100"] + + - repo: https://github.com/PyCQA/isort + rev: 5.10.1 + hooks: + - id: isort + files: \.py$ + args: [--profile=black] + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.991 + hooks: + - id: mypy + args: ["--config-file", ".mypy.ini"] + additional_dependencies: [types-requests, types-PyYAML, types-mock, tornado, black, pytest, gitpython, pyjwt] + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.10.1 + hooks: + - id: validate-pyproject + stages: [manual] + + - repo: https://github.com/executablebooks/mdformat + rev: 0.7.16 + hooks: + - id: mdformat + + - repo: https://github.com/asottile/pyupgrade + rev: v3.2.2 + hooks: + - id: pyupgrade + args: [--py38-plus] + + - repo: https://github.com/PyCQA/doc8 + rev: v1.0.0 + hooks: + - id: doc8 + args: [--max-line-length=200] + exclude: docs/source/other/full-config.rst + stages: [manual] + + - repo: https://github.com/PyCQA/flake8 + rev: 6.0.0 + hooks: + - id: flake8 + additional_dependencies: + ["flake8-bugbear==22.6.22", "flake8-implicit-str-concat==0.2.0"] + stages: [manual] + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.19.2 + hooks: + - id: check-github-workflows diff --git a/README.md b/README.md index c075725..9ac7d66 100644 --- a/README.md +++ b/README.md @@ -19,19 +19,20 @@ The drawback is if there is a security issue, then we're screwed. ## Activate on your Repo -1) Head [there](https://github.com/apps/meeseeksdev/) and activate -MeeseeksDev on repos you have access to. +1. Head [there](https://github.com/apps/meeseeksdev/) and activate + MeeseeksDev on repos you have access to. -2) On a repository with MeeseeksDev installed say: `@MeeseeksDev Hello` to be -sure MeeseeksDev is correctly installed. +1. On a repository with MeeseeksDev installed say: `@MeeseeksDev Hello` to be + sure MeeseeksDev is correctly installed. -3) Enjoy +1. Enjoy Beta Phase: During Beta phase repository/users need to be vetted/allowlisted open an issue if you wish to participate. You might also want to tell your CI-integration (like travis-ci) **not** to test the **push** __and__ **the merge**. To do so use: + ``` branches: except: @@ -60,9 +61,6 @@ This will allow `` to ask `@meeseeksdev` to perform above commands. The conf file is the one that sits on the repository default branch (usually `master`). - - - ## What can a MeeseeksBox do ? Comment on a Pr or issue. @@ -79,7 +77,7 @@ Respond with To test whether a Meeseeks understand you. -### @MeeseeksDev backport [to] {branch} +### @MeeseeksDev backport \[to\] {branch} If issued from a PR which is merged, attempt to backport (cherry-pick the merge commit) on an older branch and submit a PR with this backport (on said branch) @@ -88,7 +86,7 @@ Apply origin-pr labels and milestone to backport. - No option to push directly (yet), if implemented should apply only with clean backport. - Investigate what to do in case of conflict - - likely commit with conflict, and let maintainers resolve conflict + - likely commit with conflict, and let maintainers resolve conflict Repo admins only @@ -136,7 +134,7 @@ Repo admins only, plan to make it available to PR author as well. MeeseeksDev Bot need to be installed on the PR source repository for this to work. If it's not it will ask you to do so. -### @MeeseeksDev migrate [to] {target org/repo} +### @MeeseeksDev migrate \[to\] {target org/repo} Needs MeeseeksBox to be installed on both current and target repo. Command issuer to be admin on both. @@ -144,7 +142,6 @@ issuer to be admin on both. MeeseeksDev will open a similar issue, replicate all comments with links to first, migrate labels (if possible). - ### @MeeseeksDev close Close the issue. Useful when replying by mail @@ -161,7 +158,7 @@ Tag with said tags if availlable (comma separated, need to be exact match) Remove said tags if present (comma separated, need to be exact match) -### @MeeseeksDev merge [merge|squash|rebase] +### @MeeseeksDev merge \[merge|squash|rebase\] Issuer needs at least write permission. @@ -178,7 +175,7 @@ You can optionally use the word "run" in the command, e.g. "@Meeseeksdev please Most extension and new command for the MeeseeksBox are only one function, for example here is how to let everyone request the zen of Python: -```python +````python from textwrap import dedent @everyone @@ -198,7 +195,7 @@ def zen(*, session, payload, arguments): ``` """ )) -``` +```` The `session` object is authenticated with the repository the command came from. If you need to authenticate with another repository with MeeseeksBox installed `yield` the `org/repo` slug. @@ -214,7 +211,6 @@ def foo(*, session, payload, argument): session.post_comment("Sorry Jerry you are not allowed to do that.") ``` - # Why do you request so much permission ? GitHub API does not allow to change permissions once given (yet). We don't want @@ -222,12 +218,10 @@ you to go though the process of reinstalling all integrations. We would like to request less permission if necessary. - # Setup. See CONTIBUTING.md for for information. - # Warnings This is still alpha software, user and org that can use it are still hardcoded. @@ -244,4 +238,4 @@ heroku addons:create keen ## Changelog -* 2017-10-31: Backport now support squash-merge +- 2017-10-31: Backport now support squash-merge diff --git a/meeseeksdev/commands.py b/meeseeksdev/commands.py index babc56c..1440381 100644 --- a/meeseeksdev/commands.py +++ b/meeseeksdev/commands.py @@ -16,7 +16,7 @@ def _format_doc(function, name): else: doc = function.__doc__.splitlines() first, other = doc[0], "\n".join(doc[1:]) - return "`@meeseeksdev {} {}` ({}) \n{} ".format(name, first, function.scope, other) + return f"`@meeseeksdev {name} {first}` ({function.scope}) \n{other} " def help_make(commands): @@ -51,7 +51,11 @@ def open(*, session, payload, arguments, local_config=None): @write def migrate_issue_request( - *, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None + *, + session: Session, + payload: dict, + arguments: str, + local_config: Optional[dict] = None, ) -> Generator: """[to] {org}/{repo} @@ -93,7 +97,7 @@ def migrate_issue_request( if original_labels: available_labels = target_session.ghrequest( "GET", - "https://api.github.com/repos/{org}/{repo}/labels".format(org=org, repo=repo), + f"https://api.github.com/repos/{org}/{repo}/labels", None, ).json() @@ -173,7 +177,7 @@ def merge(*, session, payload, arguments, method="merge", local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}", json=None, ) pr_data = r.json() diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 5b6b360..e1af5c7 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -12,9 +12,9 @@ from pathlib import Path from textwrap import dedent from typing import Generator, Optional +from unittest import mock import git -import mock from .scopes import admin, everyone, write from .utils import Session, add_event, fix_comment_body, fix_issue_body, run @@ -103,7 +103,7 @@ def zen(*, session, payload, arguments, local_config=None): def replyadmin(*, session, payload, arguments, local_config=None): comment_url = payload["issue"]["comments_url"] user = payload["issue"]["user"]["login"] - session.post_comment(comment_url, "Hello @{user}. Waiting for your orders.".format(user=user)) + session.post_comment(comment_url, f"Hello @{user}. Waiting for your orders.") def _compute_pwd_changes(allowlist): @@ -158,7 +158,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}", json=None, ) pr_data = r.json() @@ -214,7 +214,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): if os.path.exists(repo_name): print("== Cleaning up previous work ... ") - run("rm -rf {}".format(repo_name)) + run(f"rm -rf {repo_name}") print("== Done cleaning ") print(f"== Cloning repository from {org_name}/{repo_name}, this can take some time ...") @@ -240,7 +240,7 @@ def black_suggest(*, session, payload, arguments, local_config=None): # repo.remotes.origin.fetch("{}:workbranch".format(branch)) # repo.git.checkout("workbranch") print("== Fetching Commits to reformat ...") - repo.remotes.origin.fetch("{head_sha}".format(head_sha=head_sha)) + repo.remotes.origin.fetch(f"{head_sha}") print("== All have been fetched correctly") repo.git.checkout(head_sha) print(f"== checked PR head {head_sha}") @@ -306,12 +306,16 @@ def black_suggest(*, session, payload, arguments, local_config=None): pass if os.path.exists(repo_name): print("== Cleaning up repo... ") - run("rm -rf {}".format(repo_name)) + run(f"rm -rf {repo_name}") print("== Done cleaning ") def prep_for_command( - name: str, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None + name: str, + session: Session, + payload: dict, + arguments: str, + local_config: Optional[dict] = None, ) -> Generator: """Prepare to run a command against a local checkout of a repo.""" print(f"===== running command {name} =====") @@ -328,7 +332,7 @@ def prep_for_command( print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}", json=None, ) pr_data = r.json() @@ -339,7 +343,7 @@ def prep_for_command( maintainer_can_modify = pr_data["maintainer_can_modify"] # Check to see if we can successfully push changees to the PR. - target_session = yield "{}/{}".format(author_login, repo_name) + target_session = yield f"{author_login}/{repo_name}" if target_session: print("installed on target repository") @@ -365,7 +369,7 @@ def prep_for_command( if os.path.exists(repo_name): print("== Cleaning up previous work ... ") - run("rm -rf {}".format(repo_name), check=True) + run(f"rm -rf {repo_name}", check=True) print("== Done cleaning ") print(f"== Cloning repository from {author_login}/{repo_name}, this can take some time ...") @@ -373,7 +377,7 @@ def prep_for_command( [ "git", "clone", - "https://x-access-token:{}@github.com/{}/{}".format(atk, author_login, repo_name), + f"https://x-access-token:{atk}@github.com/{author_login}/{repo_name}", ] ) print("== Cloned..") @@ -385,10 +389,10 @@ def prep_for_command( # do the command on local filesystem repo = git.Repo(repo_name) print(f"== Fetching branch `{branch}` to run {name} on ...") - repo.remotes.origin.fetch("{}:workbranch".format(branch)) + repo.remotes.origin.fetch(f"{branch}:workbranch") repo.git.checkout("workbranch") print(f"== Fetching Commits to run {name} on ...") - repo.remotes.origin.fetch("{head_sha}".format(head_sha=head_sha)) + repo.remotes.origin.fetch(f"{head_sha}") print("== All have been fetched correctly") os.chdir(repo_name) @@ -404,7 +408,7 @@ def push_the_work(session, payload, arguments, local_config=None): print("== Collecting data on Pull-request...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}", json=None, ) pr_data = r.json() @@ -420,7 +424,7 @@ def push_the_work(session, payload, arguments, local_config=None): succeeded = True try: repo.remotes.origin.push( - "workbranch:{}".format(branch), force=True + f"workbranch:{branch}", force=True ).raise_if_error() # type:ignore[operator] except Exception: succeeded = False @@ -436,7 +440,11 @@ def push_the_work(session, payload, arguments, local_config=None): @admin def precommit( - *, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None + *, + session: Session, + payload: dict, + arguments: str, + local_config: Optional[dict] = None, ) -> Generator: comment_url = payload["issue"]["comments_url"] @@ -544,7 +552,7 @@ def blackify(*, session, payload, arguments, local_config=None): r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}", json=None, ) pr_data = r.json() @@ -689,7 +697,7 @@ def keen_stats(): print("== Collecting data on Pull-request ...") r = session.ghrequest( "GET", - "https://api.github.com/repos/{}/{}/pulls/{}".format(org_name, repo_name, prnumber), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls/{prnumber}", json=None, ) pr_data = r.json() @@ -773,7 +781,7 @@ def keen_stats(): clean_epoch = time.time() if os.path.exists(repo_name): print("== Cleaning up previous work... ") - run("rm -rf {}".format(repo_name)) + run(f"rm -rf {repo_name}") print("== Done cleaning ") s_clean_time = time.time() - clean_epoch import traceback @@ -790,7 +798,7 @@ def keen_stats(): [ "git", "clone", - "https://x-access-token:{}@github.com/{}/{}".format(atk, org_name, repo_name), + f"https://x-access-token:{atk}@github.com/{org_name}/{repo_name}", ] ) process.check_returncode() @@ -817,11 +825,11 @@ def keen_stats(): # do the backport on local filesystem repo = git.Repo(repo_name) - print("== Fetching branch to backport on ... {}".format(target_branch)) - repo.remotes.origin.fetch("refs/heads/{}:workbranch".format(target_branch)) + print(f"== Fetching branch to backport on ... {target_branch}") + repo.remotes.origin.fetch(f"refs/heads/{target_branch}:workbranch") repo.git.checkout("workbranch") - print("== Fetching Commits to {mergesha} backport...".format(mergesha=merge_sha)) - repo.remotes.origin.fetch("{mergesha}".format(mergesha=merge_sha)) + print(f"== Fetching Commits to {merge_sha} backport...") + repo.remotes.origin.fetch(f"{merge_sha}") print("== All has been fetched correctly") print("Cherry-picking %s" % merge_sha) @@ -843,7 +851,9 @@ def keen_stats(): raise except git.GitCommandError as e: - if ("git commit --allow-empty" in e.stderr) or ("git commit --allow-empty" in e.stdout): + if ("git commit --allow-empty" in e.stderr.lower()) or ( + "git commit --allow-empty" in e.stdout.lower() + ): session.post_comment( comment_url, "Can't Dooooo.... It seem like this is already backported (commit is empty)." @@ -856,7 +866,7 @@ def keen_stats(): s_reason = "empty commit" keen_stats() return - elif "after resolving the conflicts" in e.stderr: + elif "after resolving the conflicts" in e.stderr.lower(): # TODO, here we should also do a git merge --abort # to avoid thrashing the cache at next backport request. cmd = " ".join(pipes.quote(arg) for arg in sys.argv) @@ -936,7 +946,7 @@ def keen_stats(): ) if hasattr(e, "stderr"): print( - "\n" + e.stderr.decode("utf8", "replace"), # type:ignore[attr-defined] + "\n" + e.stderr.decode("utf8", "replace"), file=sys.stderr, ) print("\n" + repo.git.status(), file=sys.stderr) @@ -960,7 +970,7 @@ def keen_stats(): try: print(f"Trying to push to {remote_submit_branch} of {session.personal_account_name}") repo.remotes[session.personal_account_name].push( # type:ignore[operator] - "workbranch:{}".format(remote_submit_branch) + f"workbranch:{remote_submit_branch}" ).raise_if_error() except Exception as e: import traceback @@ -973,7 +983,8 @@ def keen_stats(): keen_stats() session.post_comment( - comment_url, f"Could not push to {remote_submit_branch} due to error, aborting." + comment_url, + f"Could not push to {remote_submit_branch} due to error, aborting.", ) print(e) succeeded = False @@ -995,11 +1006,11 @@ def keen_stats(): ) new_pr = session.personal_request( "POST", - "https://api.github.com/repos/{}/{}/pulls".format(org_name, repo_name), + f"https://api.github.com/repos/{org_name}/{repo_name}/pulls", json={ "title": f"Backport PR #{prnumber} on branch {target_branch} ({prtitle})", "body": msg, - "head": "{}:{}".format(session.personal_account_name, remote_submit_branch), + "head": f"{session.personal_account_name}:{remote_submit_branch}", "base": target_branch, }, ).json() @@ -1007,7 +1018,7 @@ def keen_stats(): new_number = new_pr["number"] resp = session.ghrequest( "PATCH", - "https://api.github.com/repos/{}/{}/issues/{}".format(org_name, repo_name, new_number), + f"https://api.github.com/repos/{org_name}/{repo_name}/issues/{new_number}", json={"milestone": milestone_number, "labels": labels_names}, ) # print(resp.json()) @@ -1146,7 +1157,7 @@ def untag(session, payload, arguments, local_config=None): num = payload.get("issue", payload.get("pull_request")).get("number") tags = [arg.strip() for arg in arguments.split(",")] name = "{name}" - url = "https://api.github.com/repos/{org}/{repo}/issues/{num}/labels/{name}".format(**locals()) + url = f"https://api.github.com/repos/{org}/{repo}/issues/{num}/labels/{name}" no_untag = [] for tag in tags: try: @@ -1158,7 +1169,11 @@ def untag(session, payload, arguments, local_config=None): @write def migrate_issue_request( - *, session: Session, payload: dict, arguments: str, local_config: Optional[dict] = None + *, + session: Session, + payload: dict, + arguments: str, + local_config: Optional[dict] = None, ) -> Generator: """Todo: @@ -1191,7 +1206,7 @@ def migrate_issue_request( if original_labels: available_labels = target_session.ghrequest( "GET", - "https://api.github.com/repos/{org}/{repo}/labels".format(org=org, repo=repo), + f"https://api.github.com/repos/{org}/{repo}/labels", None, ).json() diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index ba266f6..3aafdd2 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -46,7 +46,7 @@ def validate(self): if not attr.startswith("_") and getattr(self, attr) is None and attr != "key" ] if missing: - raise ValueError("The following configuration options are missing : {}".format(missing)) + raise ValueError(f"The following configuration options are missing : {missing}") return self @@ -462,7 +462,7 @@ def dispatch_on_mention(self, body: str, payload: dict, user: str) -> None: "mention": { "user": user, "organisation": org, - "repository": "{}/{}".format(org, repo), + "repository": f"{org}/{repo}", "command": command, } }, diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 866ec11..0c2a395 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -83,7 +83,7 @@ def fix_comment_body(body, original_poster, original_url, original_org, original This should be improved to quote mention of people """ - body = RELINK_RE.sub("{org}/{repo}\\1".format(org=original_org, repo=original_repo), body) + body = RELINK_RE.sub(f"{original_org}/{original_repo}\\1", body) return """[`@{op}` commented]({original_url}): {body}""".format( op=original_poster, original_url=original_url, body=body @@ -251,7 +251,11 @@ def regen_token(self) -> None: raise ValueError(resp.content, url) def personal_request( - self, method: str, url: str, json: Optional[dict] = None, raise_for_status: bool = True + self, + method: str, + url: str, + json: Optional[dict] = None, + raise_for_status: bool = True, ) -> requests.Response: """ Does a request but using the personal account name and token @@ -261,7 +265,7 @@ def personal_request( def prepare(): headers = { - "Authorization": "token {}".format(self.personal_account_token), + "Authorization": f"token {self.personal_account_token}", "Host": "api.github.com", "User-Agent": "python/requests", } @@ -293,7 +297,7 @@ def ghrequest( def prepare(): atk = self.token() headers = { - "Authorization": "Bearer {}".format(atk), + "Authorization": f"Bearer {atk}", "Accept": accept, "Host": "api.github.com", "User-Agent": "python/requests", @@ -395,7 +399,7 @@ def create_issue( return self.ghrequest( "POST", - "https://api.github.com/repos/{}/{}/issues".format(org, repo), + f"https://api.github.com/repos/{org}/{repo}/issues", json=arguments, ) diff --git a/meeseeksdev/tests/test_webhook.py b/meeseeksdev/tests/test_webhook.py index 2639136..de886c3 100644 --- a/meeseeksdev/tests/test_webhook.py +++ b/meeseeksdev/tests/test_webhook.py @@ -17,7 +17,10 @@ ) auth = Authenticator( - config.integration_id, config.key, config.personal_account_token, config.personal_account_name + config.integration_id, + config.key, + config.personal_account_token, + config.personal_account_name, ) application = tornado.web.Application( diff --git a/requirements.txt b/requirements.txt index 7e129f1..f5ca23e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,13 @@ -tornado==6.2 -requests==2.27 -pyjwt==2.4.0 -gitpython==3.1.27 -there==0.0.9 -mock==4.0 -cryptography==36.0 -yieldbreaker==0.0.1 black==22.1 -pyyaml==6.0 +cryptography==36.0 +gitpython==3.1.27 keen==0.7 -pre-commit==2.17 +mock==4.0 pip==22.0.4 +pre-commit==2.17 +pyjwt==2.4.0 +pyyaml==6.0 +requests==2.27 +there==0.0.9 +tornado==6.2 +yieldbreaker==0.0.1 diff --git a/runtime.txt b/runtime.txt index 2fef004..69b0ccf 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.10.8 \ No newline at end of file +python-3.10.8 From 0698103f2fafb16a5bb0a48646240d4e68776886 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Mon, 5 Dec 2022 14:14:19 -0500 Subject: [PATCH 113/153] Skip applying Still Needs Manual Backport label in backport PR (#94) Fix https://github.com/MeeseeksBox/MeeseeksDev/issues/93 --- meeseeksdev/commands.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/commands.py b/meeseeksdev/commands.py index 1440381..e258926 100644 --- a/meeseeksdev/commands.py +++ b/meeseeksdev/commands.py @@ -103,8 +103,14 @@ def migrate_issue_request( available_labels = [l["name"] for l in available_labels] - migrate_labels = [l for l in original_labels if l in available_labels] - not_set_labels = [l for l in original_labels if l not in available_labels] + migrate_labels = [ + l for l in original_labels if (l in available_labels and l != "Still Needs Manual Backport") + ] + not_set_labels = [ + l + for l in original_labels + if (l not in available_labels and l != "Still Needs Manual Backport") + ] new_response = target_session.create_issue( org, From 9312408bbd5bff431c9726843c1ac72ff3ee438e Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Tue, 6 Dec 2022 09:58:30 -0500 Subject: [PATCH 114/153] Skip applying Still Needs Manual Backport label in backport PR (try 2) (#95) fix https://github.com/MeeseeksBox/MeeseeksDev/issues/93 --- meeseeksdev/meeseeksbox/commands.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index e1af5c7..64beda2 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -724,9 +724,15 @@ def keen_stats(): milestone_number = int(milestone_number) labels_names = [] try: - labels_names = [l["name"] for l in pr_data["labels"]] + labels_names = [ + l["name"] for l in pr_data["labels"] if l["name"] != "Still Needs Manual Backport" + ] if not labels_names and ("issue" in payload.keys()): - labels_names = [l["name"] for l in payload["issue"]["labels"]] + labels_names = [ + l["name"] + for l in payload["issue"]["labels"] + if l["name"] != "Still Needs Manual Backport" + ] except KeyError: print("Did not find labels|", pr_data) # clone locally From 46fe439f28c406e90a7bb863b21ce3020eab3b20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 09:17:32 -0600 Subject: [PATCH 115/153] Bump gitpython from 3.1.27 to 3.1.30 (#96) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Steven Silvester --- meeseeksdev/meeseeksbox/commands.py | 6 ++---- requirements.txt | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 64beda2..4662da9 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -423,9 +423,7 @@ def push_the_work(session, payload, arguments, local_config=None): print(f"pushing with workbranch:{branch}") succeeded = True try: - repo.remotes.origin.push( - f"workbranch:{branch}", force=True - ).raise_if_error() # type:ignore[operator] + repo.remotes.origin.push(f"workbranch:{branch}", force=True).raise_if_error() except Exception: succeeded = False @@ -975,7 +973,7 @@ def keen_stats(): succeeded = True try: print(f"Trying to push to {remote_submit_branch} of {session.personal_account_name}") - repo.remotes[session.personal_account_name].push( # type:ignore[operator] + repo.remotes[session.personal_account_name].push( f"workbranch:{remote_submit_branch}" ).raise_if_error() except Exception as e: diff --git a/requirements.txt b/requirements.txt index f5ca23e..5aee706 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ black==22.1 cryptography==36.0 -gitpython==3.1.27 +gitpython==3.1.30 keen==0.7 mock==4.0 pip==22.0.4 From 5278cfff12f65cea16ed9021cf46fb563e4c0bf0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 12:15:24 -0600 Subject: [PATCH 116/153] Bump cryptography from 36.0 to 39.0.1 (#98) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Steven Silvester --- .pre-commit-config.yaml | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6e48e90..4bfe88f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,7 +25,7 @@ repos: args: ["--line-length", "100"] - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort files: \.py$ diff --git a/requirements.txt b/requirements.txt index 5aee706..04c840e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==36.0 +cryptography==39.0.1 gitpython==3.1.30 keen==0.7 mock==4.0 From f50e68b6458d97a1967dd2e03f159f9cd1d22ad3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 17:14:18 -0500 Subject: [PATCH 117/153] Bump cryptography from 39.0.1 to 41.0.0 (#102) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 04c840e..6daa091 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==39.0.1 +cryptography==41.0.0 gitpython==3.1.30 keen==0.7 mock==4.0 From 4fb69f6a0c4efbe636ca09dcda05f83e0550f08a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 17:14:27 -0500 Subject: [PATCH 118/153] Bump tornado from 6.2 to 6.3.2 (#101) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6daa091..b04e285 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,5 @@ pyjwt==2.4.0 pyyaml==6.0 requests==2.27 there==0.0.9 -tornado==6.2 +tornado==6.3.2 yieldbreaker==0.0.1 From f6f41156d240ea03ede6df2318818b43b970f9b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:05:23 -0500 Subject: [PATCH 119/153] Bump gitpython from 3.1.30 to 3.1.34 (#109) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.30 to 3.1.34. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.30...3.1.34) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b04e285..981decf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ black==22.1 cryptography==41.0.0 -gitpython==3.1.30 +gitpython==3.1.34 keen==0.7 mock==4.0 pip==22.0.4 From 7d533726134b67661c50b4815f042da613830363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Collonval?= Date: Fri, 8 Sep 2023 21:02:48 +0200 Subject: [PATCH 120/153] Fix link to GitHub app (#110) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ac7d66..ec8be01 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The drawback is if there is a security issue, then we're screwed. ## Activate on your Repo -1. Head [there](https://github.com/apps/meeseeksdev/) and activate +1. Head [there](https://github.com/apps/lumberbot-app/) and activate MeeseeksDev on repos you have access to. 1. On a repository with MeeseeksDev installed say: `@MeeseeksDev Hello` to be From 0a4db496f9bc5f104b43ff86489b97914f016809 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 17:05:37 -0500 Subject: [PATCH 121/153] Bump cryptography from 41.0.0 to 41.0.4 (#111) Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.0 to 41.0.4. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.0...41.0.4) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 981decf..bb4c8d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==41.0.0 +cryptography==41.0.4 gitpython==3.1.34 keen==0.7 mock==4.0 From a7e35bac9ba43fab2b062901e0a9610a49c955f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 17:11:03 -0500 Subject: [PATCH 122/153] Bump gitpython from 3.1.34 to 3.1.35 (#112) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.34 to 3.1.35. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.34...3.1.35) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bb4c8d6..47ccfda 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ black==22.1 cryptography==41.0.4 -gitpython==3.1.34 +gitpython==3.1.35 keen==0.7 mock==4.0 pip==22.0.4 From e3e8dbcdc05ac7438da87643f2aa706123ec8aff Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 21 Sep 2023 17:18:45 -0500 Subject: [PATCH 123/153] Fix pre-commit (#113) --- meeseeksdev/meeseeksbox/core.py | 2 +- meeseeksdev/meeseeksbox/utils.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/meeseeksdev/meeseeksbox/core.py b/meeseeksdev/meeseeksbox/core.py index 3aafdd2..5de402b 100644 --- a/meeseeksdev/meeseeksbox/core.py +++ b/meeseeksdev/meeseeksbox/core.py @@ -137,7 +137,7 @@ def fn(req, url): req = requests.Request("POST", url, headers=headers, data=req.body) prepared = req.prepare() with requests.Session() as s: - res = s.send(prepared) + res = s.send(prepared) # type:ignore[attr-defined] return res except Exception: import traceback diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 0c2a395..4ac5730 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -212,7 +212,7 @@ def _integration_authenticated_request(self, method, url, json=None): req = requests.Request(method, url, headers=headers, json=json) prepared = req.prepare() with requests.Session() as s: - return s.send(prepared) + return s.send(prepared) # type:ignore[attr-defined] class Forbidden(Exception): @@ -273,13 +273,13 @@ def prepare(): return req.prepare() with requests.Session() as s: - response = s.send(prepare()) + response = s.send(prepare()) # type:ignore[attr-defined] if response.status_code == 401: self.regen_token() - response = s.send(prepare()) + response = s.send(prepare()) # type:ignore[attr-defined] if raise_for_status: response.raise_for_status() - return response + return response # type:ignore[no-any-return] def ghrequest( self, @@ -307,10 +307,10 @@ def prepare(): return req.prepare() with requests.Session() as s: - response = s.send(prepare()) + response = s.send(prepare()) # type:ignore[attr-defined] if response.status_code == 401: self.regen_token() - response = s.send(prepare()) + response = s.send(prepare()) # type:ignore[attr-defined] if raise_for_status: response.raise_for_status() rate_limit = response.headers.get("X-RateLimit-Limit", -1) @@ -333,7 +333,7 @@ def prepare(): "installation": repo_name, }, ) - return response + return response # type:ignore[no-any-return] def _get_permission(self, org: str, repo: str, username: str) -> Permission: get_collaborators_query = API_COLLABORATORS_TEMPLATE.format( From ad84c98f5c4ec9862eb20fededc2b4766f970bd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 19:16:22 -0500 Subject: [PATCH 124/153] Bump gitpython from 3.1.35 to 3.1.37 (#114) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.35 to 3.1.37. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.35...3.1.37) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 47ccfda..5375793 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ black==22.1 cryptography==41.0.4 -gitpython==3.1.35 +gitpython==3.1.37 keen==0.7 mock==4.0 pip==22.0.4 From 64092745883f9291d22742b3920f7d3d7208abe6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 21:01:18 -0500 Subject: [PATCH 125/153] Bump pip from 22.0.4 to 23.3 (#116) * Bump pip from 22.0.4 to 23.3 Bumps [pip](https://github.com/pypa/pip) from 22.0.4 to 23.3. - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/22.0.4...23.3) --- updated-dependencies: - dependency-name: pip dependency-type: direct:production ... Signed-off-by: dependabot[bot] * lint * lint --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Steven Silvester --- .flake8 | 6 ++++++ requirements.txt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index fac3add..177cf82 100644 --- a/.flake8 +++ b/.flake8 @@ -13,4 +13,10 @@ extend-ignore = E731 # E203 whitespace before ':' E203 + # E231 whitespace after ':' + E231 + # E221 multiple spaces before operator + E221 + # E222 multiple spaces after operator + E222 per-file-ignores = diff --git a/requirements.txt b/requirements.txt index 5375793..b2537cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ cryptography==41.0.4 gitpython==3.1.37 keen==0.7 mock==4.0 -pip==22.0.4 +pip==23.3 pre-commit==2.17 pyjwt==2.4.0 pyyaml==6.0 From 53cd9931863d0d45cc91a3d78c48688238a098ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:16:57 -0600 Subject: [PATCH 126/153] Bump tornado from 6.3.2 to 6.3.3 (#108) Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.3.2 to 6.3.3. - [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.3.2...v6.3.3) --- updated-dependencies: - dependency-name: tornado dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b2537cc..b479f8e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,5 @@ pyjwt==2.4.0 pyyaml==6.0 requests==2.27 there==0.0.9 -tornado==6.3.2 +tornado==6.3.3 yieldbreaker==0.0.1 From 9f4c8cb9456dd1cc2f8a2410c201da95544270ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:21:17 -0600 Subject: [PATCH 127/153] Bump cryptography from 41.0.4 to 41.0.6 (#117) Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.4 to 41.0.6. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.4...41.0.6) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b479f8e..dde0bc5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==41.0.4 +cryptography==41.0.6 gitpython==3.1.37 keen==0.7 mock==4.0 From 882a4c5c36b84ad8e6f75068758167d3cc5fe10e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:15:41 -0600 Subject: [PATCH 128/153] Bump gitpython from 3.1.37 to 3.1.41 (#118) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.37 to 3.1.41. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.37...3.1.41) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dde0bc5..4011d73 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ black==22.1 cryptography==41.0.6 -gitpython==3.1.37 +gitpython==3.1.41 keen==0.7 mock==4.0 pip==23.3 From e1b2794f3a47bdbbdfb0ffd9082d23660a343025 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 05:38:51 -0600 Subject: [PATCH 129/153] Bump cryptography from 41.0.6 to 42.0.0 (#119) Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.6 to 42.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.6...42.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4011d73..bf2835d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==41.0.6 +cryptography==42.0.0 gitpython==3.1.41 keen==0.7 mock==4.0 From efd11f612a47d03661783015fe046206e5c9fea8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 20:29:17 -0600 Subject: [PATCH 130/153] Bump cryptography from 42.0.0 to 42.0.2 (#120) Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.0 to 42.0.2. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/42.0.0...42.0.2) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bf2835d..8a641d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==42.0.0 +cryptography==42.0.2 gitpython==3.1.41 keen==0.7 mock==4.0 From 92d9ffa21560e0c7e870da2f83d2edd5b6272506 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 21:01:55 -0600 Subject: [PATCH 131/153] Bump cryptography from 42.0.2 to 42.0.4 (#121) Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.2 to 42.0.4. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/42.0.2...42.0.4) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8a641d7..93faa7e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==22.1 -cryptography==42.0.2 +cryptography==42.0.4 gitpython==3.1.41 keen==0.7 mock==4.0 From 8d6db4cfc7c1920e7ccd27afee96e69b5affb5a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 03:46:40 -0700 Subject: [PATCH 132/153] Bump black from 22.1 to 24.3.0 (#122) Bumps [black](https://github.com/psf/black) from 22.1 to 24.3.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/22.1.0...24.3.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 93faa7e..999e8bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -black==22.1 +black==24.3.0 cryptography==42.0.4 gitpython==3.1.41 keen==0.7 From 3614e29632a7cc0cad63a9fb24b3476b42e9765a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 00:50:10 -0700 Subject: [PATCH 133/153] --- (#124) updated-dependencies: - dependency-name: requests dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 999e8bd..2b8f3db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ pip==23.3 pre-commit==2.17 pyjwt==2.4.0 pyyaml==6.0 -requests==2.27 +requests==2.32.0 there==0.0.9 tornado==6.3.3 yieldbreaker==0.0.1 From 45f3be05656e1cdcb930d0c5607e313865d46592 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Jun 2024 03:08:23 -0500 Subject: [PATCH 134/153] Bump tornado from 6.3.3 to 6.4.1 (#125) Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.3.3 to 6.4.1. - [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.3.3...v6.4.1) --- updated-dependencies: - dependency-name: tornado dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2b8f3db..3505a93 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,5 @@ pyjwt==2.4.0 pyyaml==6.0 requests==2.32.0 there==0.0.9 -tornado==6.3.3 +tornado==6.4.1 yieldbreaker==0.0.1 From 4c4731be2e26d3decffda2bbd7fb5918612db0c6 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 10 Jun 2024 09:58:10 +0200 Subject: [PATCH 135/153] some debug --- meeseeksdev/meeseeksbox/utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 4ac5730..00e9d26 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -170,7 +170,9 @@ def _build_auth_id_mapping(self): self._update_installation(installation) def _update_installation(self, installation): + print("Updating installations") iid = installation["id"] + print("... making a session") session = self.session(iid) try: # Make sure we get all pages. @@ -309,6 +311,7 @@ def prepare(): with requests.Session() as s: response = s.send(prepare()) # type:ignore[attr-defined] if response.status_code == 401: + print("Unauthorized, regen token") self.regen_token() response = s.send(prepare()) # type:ignore[attr-defined] if raise_for_status: @@ -339,6 +342,7 @@ def _get_permission(self, org: str, repo: str, username: str) -> Permission: get_collaborators_query = API_COLLABORATORS_TEMPLATE.format( org=org, repo=repo, username=username ) + print("_get_permission") resp = self.ghrequest( "GET", get_collaborators_query, From ea9ed2151f594a2d60d51f9508b22d4142536e1c Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 10 Jun 2024 10:01:25 +0200 Subject: [PATCH 136/153] more debug --- meeseeksdev/meeseeksbox/utils.py | 10 ++++++++-- runtime.txt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/meeseeksdev/meeseeksbox/utils.py b/meeseeksdev/meeseeksbox/utils.py index 00e9d26..4f96d6f 100644 --- a/meeseeksdev/meeseeksbox/utils.py +++ b/meeseeksdev/meeseeksbox/utils.py @@ -170,9 +170,9 @@ def _build_auth_id_mapping(self): self._update_installation(installation) def _update_installation(self, installation): - print("Updating installations") + print("Updating installations", installation) iid = installation["id"] - print("... making a session") + print("... making a session", iid) session = self.session(iid) try: # Make sure we get all pages. @@ -181,6 +181,12 @@ def _update_installation(self, installation): res = session.ghrequest("GET", url) repositories = res.json() for repo in repositories["repositories"]: + print( + "Mapping repo to installation:", + repo["full_name"], + repo["owner"]["login"], + iid, + ) self.idmap[repo["full_name"]] = iid self._org_idmap[repo["owner"]["login"]] = iid if "next" in res.links: diff --git a/runtime.txt b/runtime.txt index 69b0ccf..2bccd9d 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.10.8 +python-3.10.14 From 781b3acc60f6a58f959c0bb3dbf6c8411e088110 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 10 Jun 2024 10:10:43 +0200 Subject: [PATCH 137/153] bump python to 3.12.3 --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 2bccd9d..4ddc7cd 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.10.14 +python-3.12.3 From ba80a4b5797b46be7e1a2aab29d2edde785dd502 Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 10 Jun 2024 10:10:59 +0200 Subject: [PATCH 138/153] bump python to 3.12.4 --- runtime.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime.txt b/runtime.txt index 4ddc7cd..74d315a 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.12.3 +python-3.12.4 From 3419dacee7a0d6fe4aa48b3a1a3bf66ec3abc871 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Mon, 10 Jun 2024 14:31:40 -0400 Subject: [PATCH 139/153] MAINT: Add dependabot yaml (#128) * MAINT: Add dependabot yaml * Update .github/dependabot.yml Co-authored-by: Matthew Feickert --------- Co-authored-by: Matthew Feickert --- .github/dependabot.yml | 13 +++++++++++++ .github/release.yml | 6 ++++++ README.md | 3 --- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/release.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..18aff79 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + actions: + patterns: + - "*" + labels: + - "github-actions" + - "dependabot" diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..6dd6bd3 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,6 @@ +changelog: + exclude: + authors: + - dependabot + - pre-commit-ci + - meeseeksmachine diff --git a/README.md b/README.md index ec8be01..3c31cb7 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,6 @@ The drawback is if there is a security issue, then we're screwed. 1. Enjoy -Beta Phase: During Beta phase repository/users need to be vetted/allowlisted -open an issue if you wish to participate. - You might also want to tell your CI-integration (like travis-ci) **not** to test the **push** __and__ **the merge**. To do so use: From 8e8161777506d8a8b6692d69fbf8d152d392f694 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:38:29 -0500 Subject: [PATCH 140/153] Bump the actions group with 3 updates (#129) Bumps the actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-python](https://github.com/actions/setup-python) and [pre-commit/action](https://github.com/pre-commit/action). Updates `actions/checkout` from 2 to 4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) Updates `actions/setup-python` from 2 to 5 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v5) Updates `pre-commit/action` from 2.0.0 to 3.0.1 - [Release notes](https://github.com/pre-commit/action/releases) - [Commits](https://github.com/pre-commit/action/compare/v2.0.0...v3.0.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: pre-commit/action dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4919062..fdc5f34 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-20.04 timeout-minutes: 5 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - uses: pre-commit/action@v2.0.0 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - uses: pre-commit/action@v3.0.1 with: extra_args: --all-files --hook-stage=manual - name: Help message if pre-commit fail @@ -39,7 +39,7 @@ jobs: python-version: ["3.10"] steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install the Python dependencies From bfd704fcbb4cfe58fa851e1fde740e4b71cafb1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:44:21 -0700 Subject: [PATCH 141/153] Bump cryptography from 42.0.4 to 43.0.1 (#131) Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.4 to 43.0.1. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/42.0.4...43.0.1) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3505a93..1d74a28 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==24.3.0 -cryptography==42.0.4 +cryptography==43.0.1 gitpython==3.1.41 keen==0.7 mock==4.0 From 391980b6bfa4998fd83cc8bedcc417af3374201d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 15:47:02 -0700 Subject: [PATCH 142/153] Bump tornado from 6.4.1 to 6.4.2 (#134) Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4.1 to 6.4.2. - [Changelog](https://github.com/tornadoweb/tornado/blob/v6.4.2/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.1...v6.4.2) --- updated-dependencies: - dependency-name: tornado dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1d74a28..06fabc9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,5 @@ pyjwt==2.4.0 pyyaml==6.0 requests==2.32.0 there==0.0.9 -tornado==6.4.1 +tornado==6.4.2 yieldbreaker==0.0.1 From ba221d0e63393c8c68179bbe5915f4a0d9e3c2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Sat, 24 May 2025 11:17:08 -0700 Subject: [PATCH 143/153] CI: adding workflow_dispatch (#136) * CI: adding workflow_dispatch * CI: default branch has been renamed * CI: update VM version * MAINT: shutting up mypy complaints --- .github/workflows/build.yml | 5 +++-- meeseeksdev/meeseeksbox/commands.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fdc5f34..4a74ad1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,9 @@ name: Tests on: push: - branches: ["master"] + branches: ["main"] pull_request: + workflow_dispatch: concurrency: group: ci-${{ github.ref }} @@ -11,7 +12,7 @@ concurrency: jobs: # Run "pre-commit run --all-files --hook-stage=manual" pre-commit: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v4 diff --git a/meeseeksdev/meeseeksbox/commands.py b/meeseeksdev/meeseeksbox/commands.py index 4662da9..9c06321 100644 --- a/meeseeksdev/meeseeksbox/commands.py +++ b/meeseeksdev/meeseeksbox/commands.py @@ -432,7 +432,7 @@ def push_the_work(session, payload, arguments, local_config=None): "GET", f"https://api.github.com/repos/{org_name}/{repo_name}" ).json()["default_branch"] repo.git.checkout(default_branch) - repo.branches.workbranch.delete(repo, "workbranch", force=True) # type:ignore[attr-defined] + repo.branches.workbranch.delete(repo, "workbranch", force=True) return succeeded @@ -994,7 +994,7 @@ def keen_stats(): succeeded = False repo.git.checkout(default_branch) - repo.branches.workbranch.delete(repo, "workbranch", force=True) # type:ignore[attr-defined] + repo.branches.workbranch.delete(repo, "workbranch", force=True) # TODO checkout the default_branch and get rid of branch From 4eb5d9aedd8abd66df62857dbbafb059574200a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 May 2025 11:19:16 -0700 Subject: [PATCH 144/153] Bump cryptography from 43.0.1 to 44.0.1 (#135) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [cryptography](https://github.com/pyca/cryptography) from 43.0.1 to 44.0.1. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/43.0.1...44.0.1) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Brigitta Sipőcz --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 06fabc9..6e53156 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==24.3.0 -cryptography==43.0.1 +cryptography==44.0.1 gitpython==3.1.41 keen==0.7 mock==4.0 From fb202d8cbddbadf59c748aba7562a1f0113f0c71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:16:03 -0400 Subject: [PATCH 145/153] Bump requests from 2.32.0 to 2.32.4 (#137) Bumps [requests](https://github.com/psf/requests) from 2.32.0 to 2.32.4. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.32.0...v2.32.4) --- updated-dependencies: - dependency-name: requests dependency-version: 2.32.4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6e53156..4c41648 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ pip==23.3 pre-commit==2.17 pyjwt==2.4.0 pyyaml==6.0 -requests==2.32.0 +requests==2.32.4 there==0.0.9 tornado==6.4.2 yieldbreaker==0.0.1 From 83c8f3061bcc84bcc89d3841efaef7a2c53bc334 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:41:02 -0400 Subject: [PATCH 146/153] Bump tornado from 6.4.2 to 6.5.1 (#138) Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4.2 to 6.5.1. - [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.2...v6.5.1) --- updated-dependencies: - dependency-name: tornado dependency-version: 6.5.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4c41648..516ef5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,5 @@ pyjwt==2.4.0 pyyaml==6.0 requests==2.32.4 there==0.0.9 -tornado==6.4.2 +tornado==6.5.1 yieldbreaker==0.0.1 From 5c7f763408caa74cc88a576adc826d784e1fccf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 19:23:57 +0200 Subject: [PATCH 147/153] Bump actions/checkout from 4 to 5 in the actions group (#139) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4a74ad1..a68078e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-python@v5 - uses: pre-commit/action@v3.0.1 with: @@ -40,7 +40,7 @@ jobs: python-version: ["3.10"] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install the Python dependencies From addef819d7bd02cb2dca9e8464921a2def571098 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 09:36:15 -0400 Subject: [PATCH 148/153] Bump actions/setup-python from 5 to 6 in the actions group (#140) Bumps the actions group with 1 update: [actions/setup-python](https://github.com/actions/setup-python). Updates `actions/setup-python` from 5 to 6 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a68078e..7de4f2f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 - uses: pre-commit/action@v3.0.1 with: extra_args: --all-files --hook-stage=manual From 5ba5dcdd6dda739b23378c2776df6d2076b245eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 18:56:26 -0400 Subject: [PATCH 149/153] Bump pip from 23.3 to 25.2 (#141) Bumps [pip](https://github.com/pypa/pip) from 23.3 to 25.2. - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/23.3...25.2) --- updated-dependencies: - dependency-name: pip dependency-version: '25.2' dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 516ef5d..9e9a043 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ cryptography==44.0.1 gitpython==3.1.41 keen==0.7 mock==4.0 -pip==23.3 +pip==25.2 pre-commit==2.17 pyjwt==2.4.0 pyyaml==6.0 From 55518df1e599cc6f41905d4bce649d993cbdc830 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:02:04 +0100 Subject: [PATCH 150/153] Bump actions/checkout from 5 to 6 in the actions group (#142) Bumps the actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 5 to 6 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7de4f2f..1930dc3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 - uses: pre-commit/action@v3.0.1 with: @@ -40,7 +40,7 @@ jobs: python-version: ["3.10"] steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install the Python dependencies From 933623cb1475aee60a80d08174fe9cce8a76932b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 07:45:55 -0700 Subject: [PATCH 151/153] Bump pip from 25.2 to 25.3 (#143) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9e9a043..cb26606 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ cryptography==44.0.1 gitpython==3.1.41 keen==0.7 mock==4.0 -pip==25.2 +pip==25.3 pre-commit==2.17 pyjwt==2.4.0 pyyaml==6.0 From 9d217df318d0e1f9899507895f93951b3cd31ae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 16:37:26 -0800 Subject: [PATCH 152/153] Bump pip from 25.3 to 26.0 (#144) Bumps [pip](https://github.com/pypa/pip) from 25.3 to 26.0. - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/25.3...26.0) --- updated-dependencies: - dependency-name: pip dependency-version: '26.0' dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cb26606..dea9c4d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ cryptography==44.0.1 gitpython==3.1.41 keen==0.7 mock==4.0 -pip==25.3 +pip==26.0 pre-commit==2.17 pyjwt==2.4.0 pyyaml==6.0 From 85e98c598eee2dbb6481e9d39a58a4e5a10ba3ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 10:17:12 -0800 Subject: [PATCH 153/153] Bump cryptography from 44.0.1 to 46.0.5 (#145) Bumps [cryptography](https://github.com/pyca/cryptography) from 44.0.1 to 46.0.5. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/44.0.1...46.0.5) --- updated-dependencies: - dependency-name: cryptography dependency-version: 46.0.5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dea9c4d..2eccb0f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ black==24.3.0 -cryptography==44.0.1 +cryptography==46.0.5 gitpython==3.1.41 keen==0.7 mock==4.0