From e1951c752bf4cf264a899f4af7c6f484b10e7510 Mon Sep 17 00:00:00 2001 From: Joseph Flinn Date: Thu, 29 Feb 2024 12:04:51 -0800 Subject: [PATCH] Add hacky safety measure to alert on GitHub Response Schema changes --- lint-workflow-v2/Taskfile.yml | 2 +- .../src/bitwarden_workflow_linter/actions.py | 56 +++++++++++-------- .../src/bitwarden_workflow_linter/load.py | 1 + 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/lint-workflow-v2/Taskfile.yml b/lint-workflow-v2/Taskfile.yml index 9f8fcafb..00cc69c4 100644 --- a/lint-workflow-v2/Taskfile.yml +++ b/lint-workflow-v2/Taskfile.yml @@ -62,7 +62,7 @@ tasks: test:e2e:actions:update: cmds: - - pipenv run bwwl actions update --output test.json + - pipenv run bwwl actions --output test.json update dist: silent: true diff --git a/lint-workflow-v2/src/bitwarden_workflow_linter/actions.py b/lint-workflow-v2/src/bitwarden_workflow_linter/actions.py index 90cd0bae..88698127 100644 --- a/lint-workflow-v2/src/bitwarden_workflow_linter/actions.py +++ b/lint-workflow-v2/src/bitwarden_workflow_linter/actions.py @@ -12,6 +12,12 @@ from .utils import Colors, Settings, Action +class GitHubApiSchemaError(Exception): + """A generic Exception to catch redefinitions of GitHub Api Schema changes.""" + + pass + + class ActionsCmd: """Command to manage the pre-approved list of Actions @@ -115,33 +121,39 @@ def exists(self, action: Action) -> bool: def get_latest_version(self, action: Action) -> Action | None: """Gets the latest version of the Action to compare against.""" - # Get tag from latest release - response = self.get_github_api_response( - f"https://api.github.com/repos/{action.name}/releases/latest", action.name - ) - if not response: - return None - - tag_name = json.loads(response.data)["tag_name"] + try: + # Get tag from latest release + response = self.get_github_api_response( + f"https://api.github.com/repos/{action.name}/releases/latest", + action.name, + ) + if not response: + return None - # Get the URL to the commit for the tag - response = self.get_github_api_response( - f"https://api.github.com/repos/{action.name}/git/ref/tags/{tag_name}", - action.name, - ) - if not response: - return None + tag_name = json.loads(response.data)["tag_name"] - if json.loads(response.data)["object"]["type"] == "commit": - sha = json.loads(response.data)["object"]["sha"] - else: - url = json.loads(response.data)["object"]["url"] - # Follow the URL and get the commit sha for tags - response = self.get_github_api_response(url, action.name) + # Get the URL to the commit for the tag + response = self.get_github_api_response( + f"https://api.github.com/repos/{action.name}/git/ref/tags/{tag_name}", + action.name, + ) if not response: return None - sha = json.loads(response.data)["object"]["sha"] + if json.loads(response.data)["object"]["type"] == "commit": + sha = json.loads(response.data)["object"]["sha"] + else: + url = json.loads(response.data)["object"]["url"] + # Follow the URL and get the commit sha for tags + response = self.get_github_api_response(url, action.name) + if not response: + return None + + sha = json.loads(response.data)["object"]["sha"] + except KeyError as err: + raise GitHubApiSchemaError( + f"Error with the GitHub API Response Schema for either /releases or /tags: {err}" + ) return Action(name=action.name, version=tag_name, sha=sha) diff --git a/lint-workflow-v2/src/bitwarden_workflow_linter/load.py b/lint-workflow-v2/src/bitwarden_workflow_linter/load.py index a378f0f6..7f863725 100644 --- a/lint-workflow-v2/src/bitwarden_workflow_linter/load.py +++ b/lint-workflow-v2/src/bitwarden_workflow_linter/load.py @@ -112,6 +112,7 @@ def __init__(self, settings: Settings) -> None: A Settings object that contains any default, overridden, or custom settings required anywhere in the application. """ + # [TODO]: data resiliency for rule in settings.enabled_rules: module_name = rule.split(".") module_name = ".".join(module_name[:-1])