diff --git a/lint-workflow/src/rules/job_environment_prefix.py b/lint-workflow/src/rules/job_environment_prefix.py index 13a33172..036e5c04 100644 --- a/lint-workflow/src/rules/job_environment_prefix.py +++ b/lint-workflow/src/rules/job_environment_prefix.py @@ -11,10 +11,19 @@ class RuleJobEnvironmentPrefix(Rule): """Rule to enforce specific prefixes for environemnt variables. - Maintaining l + Automated testing is not easily written for GitHub Action Workflows. CI can also + get complicated really quickly and take up hundreds of lines. All of this can + make it very difficult to debug and troubleshoot, especially when environment + variables can be set in four different places: Workflow level, Job level, Step + level, and inside a shell Step. + + To alleviate some of the pain, we have decided that all Job level environment + variables should be prefixed with an underscore. All Workflow environment + variables are normally at the top of the file and Step level ones are pretty + visible when debugging a shell Step. """ def __init__(self, settings: Settings = None) -> None: - """RuleJobEnvironmentPrefix constructor. + """RuleJobEnvironmentPrefix constructor to override the Rule class. Args: settings: diff --git a/lint-workflow/src/rules/name_capitalized.py b/lint-workflow/src/rules/name_capitalized.py index eca419b9..84b4d948 100644 --- a/lint-workflow/src/rules/name_capitalized.py +++ b/lint-workflow/src/rules/name_capitalized.py @@ -1,4 +1,4 @@ -"""Enforce all 'name' values start with a capital letter.""" +"""A Rule to enforce all 'name' values start with a capital letter.""" from typing import Union, Tuple from ..rule import Rule @@ -9,9 +9,12 @@ class RuleNameCapitalized(Rule): - """Rule to enforce all 'name' values start with a capital letter.""" + """Rule to enforce all 'name' values start with a capital letter. + + A simple standard to help keep uniformity in naming. + """ def __init__(self, settings: Settings = None) -> None: - """Contructor for RuleNameCapitalized. + """Contructor for RuleNameCapitalized to override the Rule class. Args: settings: diff --git a/lint-workflow/src/rules/name_exists.py b/lint-workflow/src/rules/name_exists.py index 165038b0..e3a8920d 100644 --- a/lint-workflow/src/rules/name_exists.py +++ b/lint-workflow/src/rules/name_exists.py @@ -1,3 +1,4 @@ +"""A Rule to enforce that a 'name' exists.""" from typing import Union, Tuple from ..rule import Rule @@ -8,7 +9,22 @@ class RuleNameExists(Rule): + """Rule to enforce a 'name' exists for every object in GitHub Actions. + + For pipeline run troubleshooting and debugging, it is helpful to have a + name to immediately identify a Workflow, Job, or Step while moving between + run and the code. + + It also helps with uniformity of runs. + """ def __init__(self, settings: Settings = None) -> None: + """Contructor for RuleNameCapitalized to override Rule class. + + Args: + settings: + A Settings object that contains any default, overriden, or custom settings + required anywhere in the application. + """ self.message = "name must exist" self.on_fail: LintLevels = LintLevels.ERROR self.settings: Settings = settings diff --git a/lint-workflow/tests/rules/test_name_exists.py b/lint-workflow/tests/rules/test_name_exists.py index 1634acc4..e1e7e6ca 100644 --- a/lint-workflow/tests/rules/test_name_exists.py +++ b/lint-workflow/tests/rules/test_name_exists.py @@ -1,44 +1,69 @@ +"""Test src/rules/name_exists.py.""" import pytest -from ..conftest import FIXTURE_DIR -from ..context import src from src.load import WorkflowBuilder from src.rules.name_exists import RuleNameExists -@pytest.fixture -def correct_workflow(): - return WorkflowBuilder.build(f"{FIXTURE_DIR}/test-min.yaml") +@pytest.fixture(name="correct_workflow") +def fixture_correct_workflow(): + workflow = """\ +--- +name: Test Workflow +on: + workflow_dispatch: -@pytest.fixture -def incorrect_workflow(): - return WorkflowBuilder.build(f"{FIXTURE_DIR}/test-min-incorrect.yaml") +jobs: + job-key: + name: Test + runs-on: ubuntu-latest + steps: + - name: Test + run: echo test +""" + return WorkflowBuilder.build(workflow=workflow, from_file=False) -@pytest.fixture -def rule(): +@pytest.fixture(name="incorrect_workflow") +def fixture_incorrect_workflow(): + workflow = """\ +--- +on: + workflow_dispatch: + +jobs: + job-key: + runs-on: ubuntu-latest + steps: + - run: echo test +""" + return WorkflowBuilder.build(workflow=workflow, from_file=False) + + +@pytest.fixture(name="rule") +def fixture_rule(): return RuleNameExists() def test_rule_on_correct_workflow(rule, correct_workflow): - result, message = rule.fn(correct_workflow) - assert result == True + result, _ = rule.fn(correct_workflow) + assert result is True - result, message = rule.fn(correct_workflow.jobs["job-key"]) - assert result == True + result, _ = rule.fn(correct_workflow.jobs["job-key"]) + assert result is True - result, message = rule.fn(correct_workflow.jobs["job-key"].steps[0]) - assert result == True + result, _ = rule.fn(correct_workflow.jobs["job-key"].steps[0]) + assert result is True def test_rule_on_incorrect_workflow(rule, incorrect_workflow): print(f"Workflow name: {incorrect_workflow.name}") - result, message = rule.fn(incorrect_workflow) - assert result == False + result, _ = rule.fn(incorrect_workflow) + assert result is False - result, message = rule.fn(incorrect_workflow.jobs["job-key"]) - assert result == False + result, _ = rule.fn(incorrect_workflow.jobs["job-key"]) + assert result is False - result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[0]) - assert result == False + result, _ = rule.fn(incorrect_workflow.jobs["job-key"].steps[0]) + assert result is False