From 42e1c1a3c8869f9ea7e8dc16dc332b43bbb1c40e Mon Sep 17 00:00:00 2001 From: Or Shoval Date: Thu, 4 Nov 2021 14:46:40 +0200 Subject: [PATCH] WIP, tox and black Signed-off-by: Or Shoval --- .gitignore | 3 ++- common.py | 11 +++++--- create_ticket.py | 51 ++++++++++++++++++++---------------- githublib.py | 26 ++++++++++--------- jiralib.py | 55 +++++++++++++++++++++------------------ manifests/cronjob.yaml | 27 +++++++++---------- manifests/gitpod.yaml | 27 +++++++++---------- tox.ini | 59 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 168 insertions(+), 91 deletions(-) create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 01f0f54..443eb7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__ -secret.txt \ No newline at end of file +secret.txt +.tox/ diff --git a/common.py b/common.py index f1a7824..4fccd58 100755 --- a/common.py +++ b/common.py @@ -3,16 +3,19 @@ import os import sys + def get_envvar(name, default_value=None): value = os.getenv(name, default_value) - if value == None: + if value is None: print(f"Error: cant find {name}, exiting") sys.exit(1) return value - + + def main(): print("common self test") - get_envvar('JIRA_TOKEN') + get_envvar("JIRA_TOKEN") + -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/create_ticket.py b/create_ticket.py index 97292cd..cf4d209 100755 --- a/create_ticket.py +++ b/create_ticket.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -import os -import json import sys import argparse @@ -16,31 +14,36 @@ # how many tickets can be opened on each cycle flood_protection_limit = 3 + def process_issue(jira, github, issue, dryrun): html_url = issue["html_url"] if "pull" in html_url: return False - if github.check_labels(issue) == False: + if not github.check_labels(issue): return False issue_id = issue["number"] - if jira.issue_exists(github.repo, issue_id) == False: - if github.check_time(issue, max_delta_weeks) == False: + if not jira.issue_exists(github.repo, issue_id): + if not github.check_time(issue, max_delta_weeks): return False - if dryrun == False: - created_issue = jira.create_issue(github.repo, issue_id, issue["title"], html_url) - print(f'Created issue {jira.server}/browse/{created_issue} for {html_url}') + if not dryrun: + created_issue = jira.create_issue( + github.repo, issue_id, issue["title"], html_url + ) + issue_url = f"{jira.server}/browse/{created_issue}" + print(f"Created issue {issue_url} for {html_url}") else: - print(f'Dry Run Created issue for {html_url}') + print(f"Dry Run Created issue for {html_url}") return True else: print("Issue for", html_url, "already exists") return False + def loop(jira, github, dryrun): issues_created = 0 @@ -51,27 +54,28 @@ def loop(jira, github, dryrun): for issue in issues: res = process_issue(jira, github, issue, dryrun) - if res == True: + if res: issues_created += 1 if issues_created == flood_protection_limit: print("Flood protection limit reached, exiting") sys.exit(0) + def main(): - server = get_envvar('JIRA_SERVER') - username = get_envvar('JIRA_USERNAME') - token = get_envvar('JIRA_TOKEN') - project = get_envvar('JIRA_PROJECT') - project_id = get_envvar('JIRA_PROJECT_ID') - jira_component = get_envvar('JIRA_COMPONENT') - - github_token = get_envvar('GITHUB_TOKEN') - github_owner = get_envvar('GITHUB_OWNER') - github_repo = get_envvar('GITHUB_REPO') - github_label = get_envvar('GITHUB_LABEL') + server = get_envvar("JIRA_SERVER") + username = get_envvar("JIRA_USERNAME") + token = get_envvar("JIRA_TOKEN") + project = get_envvar("JIRA_PROJECT") + project_id = get_envvar("JIRA_PROJECT_ID") + jira_component = get_envvar("JIRA_COMPONENT") + + github_token = get_envvar("GITHUB_TOKEN") + github_owner = get_envvar("GITHUB_OWNER") + github_repo = get_envvar("GITHUB_REPO") + github_label = get_envvar("GITHUB_LABEL") parser = argparse.ArgumentParser() - parser.add_argument('--dryrun', default=False, action='store_true') + parser.add_argument("--dryrun", default=False, action="store_true") args = parser.parse_args() if args.dryrun: @@ -82,5 +86,6 @@ def main(): loop(jira, github, args.dryrun) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/githublib.py b/githublib.py index c1a27b0..03dd289 100755 --- a/githublib.py +++ b/githublib.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -import os -import sys import requests import json import time @@ -11,18 +9,17 @@ SECONDS_PER_WEEK = 604800 + class Github: def __init__(self, token, owner, repo, expected_label): self.owner = owner self.repo = repo self.expected_label = expected_label self.query_url = f"https://api.github.com/repos/{owner}/{repo}/issues" - self.headers = {'Authorization': f'token {token}'} - + self.headers = {"Authorization": f"token {token}"} + def get_issues(self, page): - params = { - "state": "open", "page" : page, "per_page": "100" - } + params = {"state": "open", "page": page, "per_page": "100"} r = requests.get(self.query_url, headers=self.headers, params=params) data = r.json() @@ -38,19 +35,24 @@ def check_labels(self, issue): def check_time(self, issue, max_delta): epoch_time_now = int(time.time()) - epoch = int(datetime.strptime(issue["created_at"], "%Y-%m-%dT%H:%M:%SZ").timestamp()) + TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" + epoch = int( + datetime.strptime(issue["created_at"], TIME_FORMAT).timestamp() + ) return (epoch_time_now - epoch) < (max_delta * SECONDS_PER_WEEK) + def main(): print("githublib self test") - github_token = get_envvar('GITHUB_TOKEN') - github_owner = get_envvar('GITHUB_OWNER') - github_repo = get_envvar('GITHUB_REPO') + github_token = get_envvar("GITHUB_TOKEN") + github_owner = get_envvar("GITHUB_OWNER") + github_repo = get_envvar("GITHUB_REPO") github = Github(github_token, github_owner, github_repo, "") data = github.get_issues(1) print(json.dumps(data[0], sort_keys=True, indent=4)) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/jiralib.py b/jiralib.py index 3a3c510..6cf567a 100755 --- a/jiralib.py +++ b/jiralib.py @@ -1,21 +1,25 @@ #!/usr/bin/env python3 -import os -import sys - from jira import JIRA from common import get_envvar + class Jira: - def __init__(self, server, username, token, project, project_id, component): + def __init__(self, + server, + username, + token, + project, + project_id, + component): self.project = project self.project_id = project_id self.server = server self.component = component - - jiraOptions = {'server': self.server} - self.jira = JIRA(options = jiraOptions, basic_auth = (username, token)) + + jiraOptions = {"server": self.server} + self.jira = JIRA(options=jiraOptions, basic_auth=(username, token)) def issue_exists(self, repo, id): query = f'project={self.project} AND text ~ "GITHUB:{repo}-{id}"' @@ -23,33 +27,34 @@ def issue_exists(self, repo, id): return len(issues) != 0 def create_issue(self, repo, issue_id, title, body): - issue_dict=dict() - issue_dict['project']=dict({'id':self.project_id}) - issue_dict['summary']=f"[GITHUB:{repo}-{issue_id}] {title}" - issue_dict['description']=body - issue_dict['issuetype']=dict({'name':'Task'}) - if self.component != '': - issue_dict['components']=[dict({'name':self.component})] + issue_dict = dict() + issue_dict["project"] = dict({"id": self.project_id}) + issue_dict["summary"] = f"[GITHUB:{repo}-{issue_id}] {title}" + issue_dict["description"] = body + issue_dict["issuetype"] = dict({"name": "Task"}) + if self.component != "": + issue_dict["components"] = [dict({"name": self.component})] issue = self.jira.create_issue(issue_dict) return issue - + + def main(): print("jiralib self test") - server = get_envvar('JIRA_SERVER') - username = get_envvar('JIRA_USERNAME') - token = get_envvar('JIRA_TOKEN') - project = get_envvar('JIRA_PROJECT') - project_id = get_envvar('JIRA_PROJECT_ID') - jira_component = get_envvar('JIRA_COMPONENT', "") + server = get_envvar("JIRA_SERVER") + username = get_envvar("JIRA_USERNAME") + token = get_envvar("JIRA_TOKEN") + project = get_envvar("JIRA_PROJECT") + project_id = get_envvar("JIRA_PROJECT_ID") + jira_component = get_envvar("JIRA_COMPONENT", "") - print(jira_component) jira = Jira(server, username, token, project, project_id, jira_component) - res = jira.issue_exists('kubevirt', '123') + res = jira.issue_exists("kubevirt", "123") if not res: raise AssertionError() - print('OK') + print("OK") + -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/manifests/cronjob.yaml b/manifests/cronjob.yaml index 3293c85..b1537fd 100644 --- a/manifests/cronjob.yaml +++ b/manifests/cronjob.yaml @@ -1,3 +1,4 @@ +--- apiVersion: batch/v1 kind: CronJob metadata: @@ -11,19 +12,19 @@ spec: template: spec: containers: - - name: github - image: quay.io/oshoval/github:latest - command: - - /bin/sh - - -ce - - | - source /app/secret.txt - git clone https://github.com/oshoval/github2jira.git - ./github2jira/create_ticket.py - volumeMounts: - - name: configs - mountPath: /app/secret.txt - subPath: secret.txt + - name: github + image: quay.io/oshoval/github:latest + command: + - /bin/sh + - -ce + - | + source /app/secret.txt + git clone https://github.com/oshoval/github2jira.git + ./github2jira/create_ticket.py + volumeMounts: + - name: configs + mountPath: /app/secret.txt + subPath: secret.txt restartPolicy: Never volumes: - name: configs diff --git a/manifests/gitpod.yaml b/manifests/gitpod.yaml index a6f68ee..54edcd0 100644 --- a/manifests/gitpod.yaml +++ b/manifests/gitpod.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Pod metadata: @@ -5,17 +6,17 @@ metadata: namespace: default spec: containers: - - image: quay.io/oshoval/github:latest - name: github - command: - - /bin/bash - - -c - - sleep infinity - volumeMounts: - - name: configs - mountPath: /app/secret.txt - subPath: secret.txt + - image: quay.io/oshoval/github:latest + name: github + command: + - /bin/bash + - -c + - sleep infinity + volumeMounts: + - name: configs + mountPath: /app/secret.txt + subPath: secret.txt volumes: - - name: configs - configMap: - name: git-token + - name: configs + configMap: + name: git-token diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..b921e26 --- /dev/null +++ b/tox.ini @@ -0,0 +1,59 @@ +[tox] +envlist = black, flake8, pylint, yamllint, py36, py38 +skip_missing_interpreters = True + +[testenv:black] +skip_install = true +basepython = python3.6 +changedir = {toxinidir} +deps = + black==21.6b0 +# style configured via pyproject.toml +commands = + black \ + --check \ + --diff \ + {posargs} \ + ./ + +[testenv:flake8] +basepython = python3.6 +skip_install = true +changedir = {toxinidir} +deps = + flake8==3.7.9 +commands = + flake8 \ + --statistics {posargs} \ + common.py \ + githublib.py \ + jiralib.py \ + create_ticket.py + +[testenv:pylint] +basepython = python3.6 +sitepackages = true +skip_install = true +changedir = {toxinidir} +deps = + pylint==2.4.4 +commands = + pylint \ + --errors-only \ + {posargs} \ + common.py \ + githublib.py \ + jiralib.py \ + create_ticket.py + +[testenv:yamllint] +basepython = python3.6 +skip_install = true +changedir = {toxinidir} +deps = + yamllint==1.23.0 +commands = + yamllint manifests/ + +[flake8] +show_source = True