From da8861fd882faf108e0b3dd8edb6e7236cd4f962 Mon Sep 17 00:00:00 2001 From: Christopher Becker Date: Wed, 12 Jun 2024 09:57:20 +0200 Subject: [PATCH] linted with flake8 --- .flake8 | 2 ++ pipeline/GitCommit.py | 7 ++++--- pipeline/GitException.py | 2 ++ pipeline/GitHubCommit.py | 14 ++++++++----- pipeline/GitLabCommit.py | 23 +++++++++++++-------- pipeline/TrelloBoard.py | 26 +++++++++++++++--------- pipeline/TrelloException.py | 2 ++ pipeline/TrelloTask.py | 40 ++++++++++++++++++++----------------- pipeline/pipeline.py | 6 +++--- src/main.py | 3 +++ src/test_main.py | 2 ++ 11 files changed, 81 insertions(+), 46 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..1bb1554 --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +per-file-ignores = ./pipeline/TrelloTask.py:E501 diff --git a/pipeline/GitCommit.py b/pipeline/GitCommit.py index 6e944f1..21ce8b3 100644 --- a/pipeline/GitCommit.py +++ b/pipeline/GitCommit.py @@ -5,6 +5,7 @@ import os from GitException import GitException + class GitCommit: ''' Diese Klasse beinhaltet die nötigen Informationen eines Git Commits, @@ -16,7 +17,7 @@ class GitCommit: branch_name (str): Name des Git Branches des Commits commit_hash(str): Hashwert des Commits commit_message(str): Nachricht des Commits - image_name(str): Name des Docker-Images, das aus dem Commit erzeugt wird + image_name(str): Name des Docker-Images für den Commit project_url(str): URL zu dem konkreten Projekt bei GitHub/Lab pipeline_id(str): ID der aktuellen CI/CD Pipeline pipeline_link_url(str): Link zur Pipeline bei GitHub/Lab @@ -24,8 +25,8 @@ class GitCommit: test_report_link_url(str): Link zum Unittest Report bei GitHub/Lab ''' def __init__(self, branch_name, commit_hash, commit_message, - image_name, project_url, pipeline_id, pipeline_link_url, - commit_link_url, test_report_link_url): + image_name, project_url, pipeline_id, pipeline_link_url, + commit_link_url, test_report_link_url): self.branch_name = branch_name self.commit_hash = commit_hash self.commit_message = commit_message diff --git a/pipeline/GitException.py b/pipeline/GitException.py index 22ac098..14065b8 100644 --- a/pipeline/GitException.py +++ b/pipeline/GitException.py @@ -1,6 +1,8 @@ ''' Diese Datei beinhaltet die Klasse GitException ''' + + class GitException(Exception): ''' Einfache Fehlerklasse für Git-spezifische Fehler diff --git a/pipeline/GitHubCommit.py b/pipeline/GitHubCommit.py index 6d2f5e4..180685d 100644 --- a/pipeline/GitHubCommit.py +++ b/pipeline/GitHubCommit.py @@ -5,10 +5,11 @@ import os from GitCommit import GitCommit + class GitHubCommit(GitCommit): ''' Die Klasse beinhaltet die relevanten Informationen eines jeden Git Commits. - Der Konstruktor bezieht alle Informationen dafür spezifisch von GitHub Actions. + Der Konstruktor bezieht alle Informationen dafür von GitHub Actions. Diese werden aus den Umgebungsvariablen extrahiert und dem Verwender zur Verfügung gestellt. Die Umgebungsvariablen werden entweder von GitHub an sich gestellt oder @@ -23,9 +24,12 @@ def __init__(self): github_image_name = f'{github_full_name}:{github_commit_hash}' github_project_url = os.environ.get('GH_PROJECT_URL') github_pipeline_id = os.environ.get('GITHUB_RUN_ID') - github_pipeline_link_url = f'{github_project_url}/actions/runs/{github_pipeline_id}' + github_pipeline_link_url = \ + f'{github_project_url}/actions/runs/{github_pipeline_id}' github_test_report_link_url = github_pipeline_link_url - super().__init__(github_branch_name, github_commit_hash, github_commit_message, - github_image_name, github_project_url, github_pipeline_id, github_pipeline_link_url, - github_commit_link_url, github_test_report_link_url) + super().__init__(github_branch_name, github_commit_hash, + github_commit_message, github_image_name, + github_project_url, github_pipeline_id, + github_pipeline_link_url, github_commit_link_url, + github_test_report_link_url) diff --git a/pipeline/GitLabCommit.py b/pipeline/GitLabCommit.py index 517f8ad..521744e 100644 --- a/pipeline/GitLabCommit.py +++ b/pipeline/GitLabCommit.py @@ -6,10 +6,12 @@ import re from GitCommit import GitCommit + class GitLabCommit(GitCommit): ''' - Die Klasse extrahiert alle Infomationen aus GitLab und erzeugt einen GitCommit. - Der Konstruktor bezieht alle Informationen dafür spezifisch von GitLab Runnern. + Die Klasse extrahiert alle Infomationen aus GitLab und erzeugt einen + GitCommit. Der Konstruktor bezieht alle Informationen dafür spezifisch + von GitLab Runnern. Diese werden aus den Umgebungsvariablen extrahiert und dem Verwender zur Verfügung gestellt. ''' @@ -17,7 +19,8 @@ def __init__(self): gitlab_commit_message = os.environ.get('CI_COMMIT_MESSAGE') pipeline_source = os.environ.get('CI_PIPELINE_SOURCE') # Wenn Prod Pipeline - if pipeline_source == 'merge_request_event' and "Merge branch '" in gitlab_commit_message: + if pipeline_source == 'merge_request_event' and \ + "Merge branch '" in gitlab_commit_message: match = re.search(r"Merge branch '([^']*)'", gitlab_commit_message) if match: gitlab_branch_name = match.group(1) @@ -27,10 +30,14 @@ def __init__(self): gitlab_image_name = os.environ.get('CI_REGISTRY_IMAGE') gitlab_project_url = os.environ.get('CI_PROJECT_URL') gitlab_pipeline_id = os.environ.get('CI_PIPELINE_ID') - gitlab_pipeline_link_url = f'{gitlab_project_url}/-/pipelines/{gitlab_pipeline_id}' - gitlab_commit_link_url = f'{gitlab_project_url}/-/commit/{gitlab_commit_hash}' + gitlab_pipeline_link_url = \ + f'{gitlab_project_url}/-/pipelines/{gitlab_pipeline_id}' + gitlab_commit_link_url = \ + f'{gitlab_project_url}/-/commit/{gitlab_commit_hash}' gitlab_test_report_link_url = f'{gitlab_pipeline_link_url}/test_report' - super().__init__(gitlab_branch_name, gitlab_commit_hash, gitlab_commit_message, - gitlab_image_name, gitlab_project_url, gitlab_pipeline_id, gitlab_pipeline_link_url, - gitlab_commit_link_url, gitlab_test_report_link_url) + super().__init__(gitlab_branch_name, gitlab_commit_hash, + gitlab_commit_message, gitlab_image_name, + gitlab_project_url, gitlab_pipeline_id, + gitlab_pipeline_link_url, gitlab_commit_link_url, + gitlab_test_report_link_url) diff --git a/pipeline/TrelloBoard.py b/pipeline/TrelloBoard.py index f23b881..49ca61b 100644 --- a/pipeline/TrelloBoard.py +++ b/pipeline/TrelloBoard.py @@ -6,20 +6,25 @@ import requests from TrelloException import TrelloException + class TrelloBoard: ''' - Diese Klasse beinhaltet alle Informationen und Verbindungen zu dem konkreten - Trello Board, was verwendet wird. + Diese Klasse beinhaltet alle Informationen und Verbindungen zu dem + konkreten Trello Board, was verwendet wird. Parameters: - board_id (str): Id des Trello Boards. Wird in den CI/CD Variables konfiguriert. + board_id (str): Id des Trello Boards. Wird in den CI/CD + Variablen konfiguriert. api_key (str): API Key zur Authentifizierung api_token (str): API Token zur Authentifzierung ''' def __init__(self, board_id=None, api_key=None, api_token=None): - self.board_id = board_id if board_id is not None else os.environ.get('TRELLO_BOARD_ID') - self.api_key = api_key if api_key is not None else os.environ.get('TRELLO_API_KEY') - self.api_token = api_token if api_token is not None else os.environ.get('TRELLO_API_TOKEN') + self.board_id = board_id if board_id is not None \ + else os.environ.get('TRELLO_BOARD_ID') + self.api_key = api_key if api_key is not None \ + else os.environ.get('TRELLO_API_KEY') + self.api_token = api_token if api_token is not None \ + else os.environ.get('TRELLO_API_TOKEN') self.board_lists = self.__query_lists_in_board() def get_board_lists(self): @@ -27,11 +32,13 @@ def get_board_lists(self): Gibt alle Listen im Trello Board zurück. Returns: - board_lists (dict): Name aller Boards zusammen mit ihren IDs als Key-Value + board_lists (dict): Name aller Boards zusammen mit ihren IDs als + Key-Value Paar ''' return self.board_lists - def query_trello_api(self, url, params=None, method='GET', file_blob=None, timeout=10): + def query_trello_api(self, url, params=None, method='GET', + file_blob=None, timeout=10): ''' Wrapper für die GET API Requests an die Trello REST API ''' @@ -73,7 +80,8 @@ def query_trello_api(self, url, params=None, method='GET', file_blob=None, timeo def __query_lists_in_board(self): ''' - Diese Funktion gibt alle Listen inklusive der IDs innerhalb des Trello Boards zurück + Diese Funktion gibt alle Listen inklusive der IDs innerhalb des + Trello Boards zurück Returns: lists (dict): Dict aller Listen mit ID und Name diff --git a/pipeline/TrelloException.py b/pipeline/TrelloException.py index e7e7ecc..8ef702e 100644 --- a/pipeline/TrelloException.py +++ b/pipeline/TrelloException.py @@ -1,6 +1,8 @@ ''' Diese Datei beinhaltet die Klasse TrelloException ''' + + class TrelloException(Exception): ''' Einfache Fehlerklasse für Trello-spezifische Fehler diff --git a/pipeline/TrelloTask.py b/pipeline/TrelloTask.py index 9cd49cf..afb7808 100644 --- a/pipeline/TrelloTask.py +++ b/pipeline/TrelloTask.py @@ -7,13 +7,14 @@ from TrelloBoard import TrelloBoard from TrelloException import TrelloException + class TrelloTask(TrelloBoard): ''' Diese Klasse beinhaltet alle Funktionen die in den verschiedenen Pipeline - Jobs aufgerufen werden können und damit dann der Status des passenden Tickets geändert - werden kann. - Damit dies funktioniert muss ein Ticket in dem Trello Board vorhanden sein, dass den - Namen des Branches beinhaltet und das "gitlab" Label hat. + Jobs aufgerufen werden können und damit dann der Status des passenden + Tickets geändert werden kann. + Damit dies funktioniert muss ein Ticket in dem Trello Board vorhanden sein, + das den Namen des Branches beinhaltet und das "gitlab" Label hat. Parameters: board_id (str): ID des Trello Boards @@ -21,10 +22,11 @@ class TrelloTask(TrelloBoard): api_token (str): API Token des Trello Benutzers gitlab_branch_name (str): Name des aktuelle Gitlab Branches gitlab_commit_hash (str): (voller) Commit Hash - gitlab_commit_message (str): Nachricht des Entwicklers innerhalb des Commits + gitlab_commit_message (str): Nachricht des Entwicklers + innerhalb des Commits gitlab_pipeline_id (str): ID der Gitlab Pipeline - gitlab_project_url (str): URL zum Projekt innerhalb von Gitlab - gitlab_image_name (str): Name des Docker Images in der Gitlab Registry + gitlab_project_url (str): URL zum Projekt in von Gitlab + gitlab_image_name (str): Name des Docker Images in Gitlab ''' def __init__(self, git_commit): super().__init__() @@ -53,8 +55,8 @@ def __get_task(self): api_response = self.query_trello_api(url, query) # Prüfen der Karte auf Einmaligkeit if len(api_response['cards']) != 1: - raise TrelloException('''Too many cards found. Need exactly one result. - Check the unique and matching naming of branch and card. + raise TrelloException('''Too many cards found. Need exactly one + result. Check the unique and matching naming of branch and card. Aborting.''') task = api_response['cards'][0] # Prüfen auf das GitLab label @@ -62,7 +64,8 @@ def __get_task(self): if label['name'] == 'git': git_label_existing = True if not git_label_existing: - raise TrelloException('The identified task has not the git label. Aborting.') + raise TrelloException('''The identified task has not the git label. + Aborting.''') return { 'task_id': task['id'], 'list_id': task['idList'] @@ -88,12 +91,12 @@ def pre_feature_branch_pipeline(self): def intra_feature_branch_pipeline(self): ''' - Diese Funktion wird aufgerufen wenn die Review Umgebung in der Pipeline gestartet - worden ist. + Diese Funktion wird aufgerufen wenn die Review Umgebung in der Pipeline + gestartet worden ist. Folgende Dinge passieren hier: - Card wird auf "In Review" verschoben - - Status Meldung in das Ticket mit der Zeit und dem Link zum Review Bereich - TODO - Upload der Ergebnisse der statischen Tests (Artefakte) + - Status Meldung in das Ticket mit der Zeit und dem Link zum Review + Bereich ''' self.__move_card_to('In Review') @@ -102,7 +105,7 @@ def intra_feature_branch_pipeline(self): card_comment_text = f''' Automatisiert generierte Nachricht von {self.source_system} um {self.now}: - Für den [Commit]({self.git_commit.get_commit_link_url()}) `{self.git_commit.get_commit_message()}` ist die Review gestartet worden. - - Der Task wird auf den Status "In Review" verschoben. + - Der Task wird auf den Status "In Review" verschoben. - Die Review Instanz kann [hier]({review_url}) eingesehen werden. - Die Review muss [hier]({self.git_commit.get_pipeline_link_url()}) akzeptiert oder abgelehnt werden. - Die Ergebnisse der CI Tests finden sich im Anhang dieses Tasks. @@ -115,13 +118,14 @@ def intra_feature_branch_pipeline(self): # self.__upload_attachment('gl-container-scanning-report.json') # self.__upload_attachment('gl-sbom-report.cdx.json') - def post_feature_branch_pipeline(self, is_review_failed, is_pipeline_failed): + def post_feature_branch_pipeline(self, is_review_failed, + is_pipeline_failed): ''' Diese Funktion wird aufgerufen wenn die Review Pipelines enden. Folgende Dinge passieren hier: - Bei Erfolg: - Card wird auf "Ready to Deploy" geschoben - - Link zum Commit und der Pipeline werden in das Ticket geschrieben + - Link zum Commit und Pipeline werden in das Ticket geschrieben - Link zu Unit Test werden geschrieben - Artefakte werden als Anhänge in das Ticket geladen - Bei Ablehnung der Review und bei Fehlern in der Pipeline: @@ -189,7 +193,7 @@ def post_production_pipeline(self, is_failed): - Fehlermeldung mit Commit wird eingetragen - Bei Erfolg: - Card wird auf "Deployed" geschoben - - Link zum Commit und der Pipeline werden in das Ticket geschrieben + - Link zum Commit und Pipeline werden in das Ticket geschrieben ''' if not is_failed: self.__move_card_to('Deployed') diff --git a/pipeline/pipeline.py b/pipeline/pipeline.py index f6a40bd..07923c6 100644 --- a/pipeline/pipeline.py +++ b/pipeline/pipeline.py @@ -12,8 +12,8 @@ parser = argparse.ArgumentParser( prog='pipeline', - description='Dieses Programm führt die Trello Integrationen für GitLab CI/CD aus') -parser.add_argument('--step', action='store', type=str, help='Name der auszuführenden Funktion') + description='Dieses Programm ruft die Git und Trello Integration auf') +parser.add_argument('--step', action='store', type=str, help='CI Schritt') args = parser.parse_args() allowed_step_strings = [ @@ -57,7 +57,7 @@ if args.step == allowed_step_strings[4]: IS_PIPELINE_FAILED = os.environ.get('PIPELINE_FAILED') == 'true' if os.environ.get('REVIEW_ACCEPTED') is not None \ - and os.environ.get('REVIEW_ACCEPTED').lower() in ['yes', 'true']: + and os.environ.get('REVIEW_ACCEPTED').lower() in ['yes', 'true']: IS_REVIEW_FAILED = False else: IS_REVIEW_FAILED = True diff --git a/src/main.py b/src/main.py index e7dff71..5036131 100644 --- a/src/main.py +++ b/src/main.py @@ -6,6 +6,7 @@ from http import HTTPStatus import threading + class Handler(http.server.SimpleHTTPRequestHandler): ''' Logik innerhalb des Get Requests @@ -15,6 +16,7 @@ def do_GET(self): self.end_headers() self.wfile.write(b'Hallo Welt!') + class ServerThread(threading.Thread): ''' Hier ist der Webserver definiert @@ -31,6 +33,7 @@ def shutdown(self): '''Stoppen des Servers''' self.server.shutdown() + if __name__ == '__main__': httpd = socketserver.TCPServer(('', 5000), Handler) httpd.serve_forever() diff --git a/src/test_main.py b/src/test_main.py index 0e79c53..03d86c8 100644 --- a/src/test_main.py +++ b/src/test_main.py @@ -7,6 +7,7 @@ import requests from src.main import ServerThread + class TestHTTPServer(unittest.TestCase): ''' Test Cases für den Unit Test @@ -30,5 +31,6 @@ def test_server_response(self): self.assertEqual(response.status_code, HTTPStatus.OK) self.assertEqual(response.content, b'Hallo Welt!') + if __name__ == '__main__': unittest.main()