diff --git a/lint-workflow/src/actions.py b/lint-workflow/src/actions.py index 76937293..4cb867d6 100644 --- a/lint-workflow/src/actions.py +++ b/lint-workflow/src/actions.py @@ -187,4 +187,3 @@ def update(self, filename: str) -> None: updated_actions[action.name] = latest_release self.save_actions(updated_actions, filename) - diff --git a/lint-workflow/src/lint.py b/lint-workflow/src/lint.py index d4d6ded4..5aea8aa3 100644 --- a/lint-workflow/src/lint.py +++ b/lint-workflow/src/lint.py @@ -11,7 +11,7 @@ class LinterCmd: def __init__(self, settings: Settings = None) -> None: """Command to lint GitHub Action Workflow files - This class contains logic to lint workflows that are passed in. + This class contains logic to lint workflows that are passed in. Supporting logic is supplied to: - build out the list of Rules desired - select and validate the workflow files to lint @@ -149,8 +149,7 @@ def run(self, input_files: list[str], strict: bool = False) -> int: if len(input_files) > 0: return_code = reduce( - lambda a, b: a if a > b else b, - map(self.lint_file, files) + lambda a, b: a if a > b else b, map(self.lint_file, files) ) if return_code == 1 and not strict: diff --git a/lint-workflow/src/load.py b/lint-workflow/src/load.py index 59af3cfa..1dda9f71 100644 --- a/lint-workflow/src/load.py +++ b/lint-workflow/src/load.py @@ -16,6 +16,7 @@ class WorkflowBuilderError(Exception): """Custom Exception to indicate an error with the WorkflowBuilder.""" + pass diff --git a/lint-workflow/src/rule.py b/lint-workflow/src/rule.py index 1492f535..791c105b 100644 --- a/lint-workflow/src/rule.py +++ b/lint-workflow/src/rule.py @@ -8,6 +8,7 @@ class Rule: """Base class of a Rule to extend to create a linting Rule.""" + message: str = "error" on_fail: str = "error" compatibility: List[Union[Workflow, Job, Step]] = [Workflow, Job, Step] diff --git a/lint-workflow/src/rules/step_approved.py b/lint-workflow/src/rules/step_approved.py index 88a6673b..b184059b 100644 --- a/lint-workflow/src/rules/step_approved.py +++ b/lint-workflow/src/rules/step_approved.py @@ -63,7 +63,7 @@ def fn(self, obj: Step) -> Tuple[bool, str]: run: echo "test" In this example, 'actions/checkout' must be on the pre-approved list - and the metadata must match in order to succeed. The other three + and the metadata must match in order to succeed. The other three Steps will be skipped. """ if self.skip(obj): diff --git a/lint-workflow/src/rules/step_pinned.py b/lint-workflow/src/rules/step_pinned.py index a2fe2eee..2f49cfd7 100644 --- a/lint-workflow/src/rules/step_pinned.py +++ b/lint-workflow/src/rules/step_pinned.py @@ -36,7 +36,7 @@ def fn(self, obj: Step) -> Tuple[bool, str]: break the pipelines or be the entry point to a supply chain attack. Pinning internal Actions to branches allow for less updates as work - is done on those repos. This is mainly to support our Action + is done on those repos. This is mainly to support our Action monorepo architecture of our Actions. Example: @@ -52,7 +52,7 @@ def fn(self, obj: Step) -> Tuple[bool, str]: - name: Test Run Action run: echo "test" - In this example, 'actions/checkout' must be pinned to the full commit + In this example, 'actions/checkout' must be pinned to the full commit of the tag while 'bitwarden/gh-actions/get-keyvault-secrets' must be pinned to 'main'. The other two Steps will be skipped. """ diff --git a/lint-workflow/src/utils.py b/lint-workflow/src/utils.py index 77b6ae47..18e2b11a 100644 --- a/lint-workflow/src/utils.py +++ b/lint-workflow/src/utils.py @@ -20,12 +20,14 @@ class Colors: @dataclass class LintLevel: """Class to contain the numeric level and color of linting.""" + code: int color: Colors class LintLevels(LintLevel, Enum): """Collection of the different types of LintLevels available.""" + NONE = 0, Colors.white WARNING = 1, Colors.yellow ERROR = 2, Colors.red @@ -35,9 +37,7 @@ class LintFinding: """Represents a problem detected by linting.""" def __init__( - self, - description: str = "", - level: LintLevel = None + self, description: str = "", level: LintLevel = None ) -> None: self.description = description self.level = level @@ -54,6 +54,7 @@ def __str__(self) -> str: @dataclass class Action: """Collection of the metadata associated with a GitHub Action.""" + name: str version: str = "" sha: str = "" @@ -89,6 +90,7 @@ def __ne__(self, other: Self) -> bool: class SettingsError(Exception): """Custom Exception to indicate an error with loading Settings.""" + pass diff --git a/lint-workflow/tests/rules/test_name_capitalized.py b/lint-workflow/tests/rules/test_name_capitalized.py index 12acf926..1a4f3849 100644 --- a/lint-workflow/tests/rules/test_name_capitalized.py +++ b/lint-workflow/tests/rules/test_name_capitalized.py @@ -66,7 +66,6 @@ def missing_name_workflow(): return WorkflowBuilder.build(yaml=yaml.load(workflow), from_file=False) - @pytest.fixture def rule(): return RuleNameCapitalized() diff --git a/lint-workflow/tests/test_lint.py b/lint-workflow/tests/test_lint.py index 277aa374..eee5bddf 100644 --- a/lint-workflow/tests/test_lint.py +++ b/lint-workflow/tests/test_lint.py @@ -16,19 +16,31 @@ def settings(): def test_get_max_error_level(settings): linter = LinterCmd(settings=settings) - assert linter.get_max_error_level([ - LintFinding(level=LintLevels.WARNING), - LintFinding(level=LintLevels.WARNING) - ]) == 1 - - assert linter.get_max_error_level([ - LintFinding(level=LintLevels.ERROR), - LintFinding(level=LintLevels.ERROR) - ]) == 2 - - assert linter.get_max_error_level([ - LintFinding(level=LintLevels.ERROR), - LintFinding(level=LintLevels.ERROR), - LintFinding(level=LintLevels.WARNING), - LintFinding(level=LintLevels.WARNING) - ]) == 2 + assert ( + linter.get_max_error_level( + [ + LintFinding(level=LintLevels.WARNING), + LintFinding(level=LintLevels.WARNING), + ] + ) + == 1 + ) + + assert ( + linter.get_max_error_level( + [LintFinding(level=LintLevels.ERROR), LintFinding(level=LintLevels.ERROR)] + ) + == 2 + ) + + assert ( + linter.get_max_error_level( + [ + LintFinding(level=LintLevels.ERROR), + LintFinding(level=LintLevels.ERROR), + LintFinding(level=LintLevels.WARNING), + LintFinding(level=LintLevels.WARNING), + ] + ) + == 2 + ) diff --git a/lint-workflow/tests/test_utils.py b/lint-workflow/tests/test_utils.py index 77830eb7..d8756882 100644 --- a/lint-workflow/tests/test_utils.py +++ b/lint-workflow/tests/test_utils.py @@ -11,11 +11,7 @@ def test_action_eq(): - action_def = { - "name": "bitwarden/sm-action", - "version": "1.0.0", - "sha": "some-sha" - } + action_def = {"name": "bitwarden/sm-action", "version": "1.0.0", "sha": "some-sha"} action_a = Action(**action_def) action_b = Action(**action_def) @@ -25,16 +21,8 @@ def test_action_eq(): def test_action_ne(): - action_a = Action( - name = "bitwarden/sm-action", - version = "1.0.0", - sha = "some-sha" - ) - action_b = Action( - name = "bitwarden/sm-action", - version = "1.1.0", - sha = "some-other-sha" - ) + action_a = Action(name="bitwarden/sm-action", version="1.0.0", sha="some-sha") + action_b = Action(name="bitwarden/sm-action", version="1.1.0", sha="some-other-sha") assert (action_a == action_b) == False assert (action_a != action_b) == True @@ -48,7 +36,7 @@ def test_lint_level(): def test_lint_finding(): warning = LintFinding(level=LintLevels.WARNING) - assert str(warning) == '\x1b[33mwarning\x1b[0m ' + assert str(warning) == "\x1b[33mwarning\x1b[0m " error = LintFinding(level=LintLevels.ERROR) - assert str(error) == '\x1b[31merror\x1b[0m ' + assert str(error) == "\x1b[31merror\x1b[0m "