bitwarden_workflow_linter 0.1.0__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/workflows/scan.yml +2 -2
  2. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/PKG-INFO +1 -2
  3. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/__about__.py +1 -1
  4. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/actions.py +2 -0
  5. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/cli.py +2 -0
  6. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/lint.py +1 -0
  7. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/load.py +4 -0
  8. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/models/job.py +1 -0
  9. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/models/step.py +1 -0
  10. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rule.py +2 -0
  11. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/job_environment_prefix.py +1 -0
  12. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/name_capitalized.py +10 -3
  13. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/name_exists.py +1 -0
  14. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/pinned_job_runner.py +1 -0
  15. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/step_approved.py +1 -0
  16. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/step_pinned.py +4 -0
  17. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/underscore_outputs.py +9 -4
  18. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/utils.py +8 -0
  19. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_name_capitalized.py +23 -0
  20. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_step_pinned.py +12 -3
  21. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_underscore_output.py +2 -1
  22. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.editorconfig +0 -0
  23. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.gitattributes +0 -0
  24. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/CODEOWNERS +0 -0
  25. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  26. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  27. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/renovate.json +0 -0
  28. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/workflows/_version_type.yml +0 -0
  29. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/workflows/cd.yml +0 -0
  30. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/workflows/ci.yml +0 -0
  31. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.github/workflows/enforce-labels.yml +0 -0
  32. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.gitignore +0 -0
  33. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.husky/pre-commit +0 -0
  34. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/.python-version +0 -0
  35. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/CONTRIBUTING.md +0 -0
  36. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/LICENSE.txt +0 -0
  37. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/Pipfile +0 -0
  38. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/Pipfile.lock +0 -0
  39. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/README.md +0 -0
  40. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/SECURITY.md +0 -0
  41. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/Taskfile.yml +0 -0
  42. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/package-lock.json +0 -0
  43. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/package.json +0 -0
  44. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/pylintrc +0 -0
  45. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/pyproject.toml +0 -0
  46. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/pyproject.toml.tpl +0 -0
  47. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/settings.yaml +0 -0
  48. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/__init__.py +0 -0
  49. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/default_actions.json +0 -0
  50. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/default_settings.yaml +0 -0
  51. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/models/__init__.py +0 -0
  52. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/models/workflow.py +0 -0
  53. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/src/bitwarden_workflow_linter/rules/__init__.py +0 -0
  54. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/__init__.py +0 -0
  55. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/conftest.py +0 -0
  56. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/fixtures/test-alt.yml +0 -0
  57. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/fixtures/test-min-incorrect.yaml +0 -0
  58. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/fixtures/test-min.yaml +0 -0
  59. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/fixtures/test-outputs-incorrect.yml +0 -0
  60. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/fixtures/test.yml +0 -0
  61. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/fixtures/test_a.yaml +0 -0
  62. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/__init__.py +0 -0
  63. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_job_environment_prefix.py +0 -0
  64. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_name_exists.py +0 -0
  65. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_pinned_job_runner.py +0 -0
  66. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/rules/test_step_approved.py +0 -0
  67. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_job.py +0 -0
  68. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_lint.py +0 -0
  69. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_load.py +0 -0
  70. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_rule.py +0 -0
  71. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_step.py +0 -0
  72. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_utils.py +0 -0
  73. {bitwarden_workflow_linter-0.1.0 → bitwarden_workflow_linter-0.1.1}/tests/test_workflow.py +0 -0
@@ -31,7 +31,7 @@ jobs:
31
31
  ref: ${{ github.event.pull_request.head.sha }}
32
32
 
33
33
  - name: Scan with Checkmarx
34
- uses: checkmarx/ast-github-action@f0869bd1a37fddc06499a096101e6c900e815d81 # 2.0.36
34
+ uses: checkmarx/ast-github-action@03a90e7253dadd7e2fff55f5dfbce647b39040a1 # 2.0.37
35
35
  env:
36
36
  INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
37
37
  with:
@@ -46,7 +46,7 @@ jobs:
46
46
  --output-path . ${{ env.INCREMENTAL }}
47
47
 
48
48
  - name: Upload Checkmarx results to GitHub
49
- uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0
49
+ uses: github/codeql-action/upload-sarif@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1
50
50
  with:
51
51
  sarif_file: cx_result.sarif
52
52
 
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bitwarden_workflow_linter
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Custom GitHub Action Workflow Linter
5
5
  Project-URL: Homepage, https://github.com/bitwarden/workflow-linter
6
6
  Project-URL: Issues, https://github.com/bitwarden/workflow-linter/issues
7
- License-File: LICENSE.txt
8
7
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
9
8
  Classifier: Operating System :: OS Independent
10
9
  Classifier: Programming Language :: Python :: 3
@@ -1,3 +1,3 @@
1
1
  """Metadata for Workflow Linter."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.1"
@@ -11,11 +11,13 @@ from typing import Optional, Union
11
11
 
12
12
  from .utils import Colors, Settings, Action
13
13
 
14
+
14
15
  class GitHubApiSchemaError(Exception):
15
16
  """A generic Exception to catch redefinitions of GitHub Api Schema changes."""
16
17
 
17
18
  pass
18
19
 
20
+
19
21
  class ActionsCmd:
20
22
  """Command to manage the pre-approved list of Actions
21
23
 
@@ -11,6 +11,7 @@ from .utils import Settings
11
11
 
12
12
  local_settings = Settings.factory()
13
13
 
14
+
14
15
  def main(input_args: Optional[List[str]] = None) -> int:
15
16
  """CLI utility to lint GitHub Action Workflows.
16
17
 
@@ -48,5 +49,6 @@ def main(input_args: Optional[List[str]] = None) -> int:
48
49
 
49
50
  return -1
50
51
 
52
+
51
53
  if __name__ == "__main__":
52
54
  sys.exit(main())
@@ -10,6 +10,7 @@ from typing import Optional
10
10
  from .load import WorkflowBuilder, Rules
11
11
  from .utils import LintFinding, Settings
12
12
 
13
+
13
14
  class LinterCmd:
14
15
  """Command to lint GitHub Action Workflow files
15
16
 
@@ -15,11 +15,13 @@ from .utils import Settings
15
15
 
16
16
  yaml = YAML()
17
17
 
18
+
18
19
  class WorkflowBuilderError(Exception):
19
20
  """Exception to indicate an error with the WorkflowBuilder."""
20
21
 
21
22
  pass
22
23
 
24
+
23
25
  class WorkflowBuilder:
24
26
  """Collection of methods to build Workflow objects."""
25
27
 
@@ -82,11 +84,13 @@ class WorkflowBuilder:
82
84
  "The workflow must either be built from a file or from a CommentedMap"
83
85
  )
84
86
 
87
+
85
88
  class LoadRulesError(Exception):
86
89
  """Exception to indicate an error with loading rules."""
87
90
 
88
91
  pass
89
92
 
93
+
90
94
  class Rules:
91
95
  """A collection of all of the types of rules.
92
96
 
@@ -8,6 +8,7 @@ from ruamel.yaml.comments import CommentedMap
8
8
 
9
9
  from .step import Step
10
10
 
11
+
11
12
  @dataclass_json(undefined=Undefined.EXCLUDE)
12
13
  @dataclass
13
14
  class Job:
@@ -6,6 +6,7 @@ from typing import Optional, Self
6
6
  from dataclasses_json import config, dataclass_json, Undefined
7
7
  from ruamel.yaml.comments import CommentedMap
8
8
 
9
+
9
10
  @dataclass_json(undefined=Undefined.EXCLUDE)
10
11
  @dataclass
11
12
  class Step:
@@ -7,11 +7,13 @@ from .models.job import Job
7
7
  from .models.step import Step
8
8
  from .utils import LintFinding, LintLevels, Settings
9
9
 
10
+
10
11
  class RuleExecutionException(Exception):
11
12
  """Exception for the Base Rule class."""
12
13
 
13
14
  pass
14
15
 
16
+
15
17
  class Rule:
16
18
  """Base class of a Rule to extend to create a linting Rule."""
17
19
 
@@ -6,6 +6,7 @@ from ..models.job import Job
6
6
  from ..rule import Rule
7
7
  from ..utils import LintLevels, Settings
8
8
 
9
+
9
10
  class RuleJobEnvironmentPrefix(Rule):
10
11
  """Rule to enforce specific prefixes for environment variables.
11
12
 
@@ -8,6 +8,7 @@ from ..models.workflow import Workflow
8
8
  from ..rule import Rule
9
9
  from ..utils import LintLevels, Settings
10
10
 
11
+
11
12
  class RuleNameCapitalized(Rule):
12
13
  """Rule to enforce all 'name' values start with a capital letter.
13
14
 
@@ -50,6 +51,12 @@ class RuleNameCapitalized(Rule):
50
51
  capitalized names. This Rule DOES NOT enforce that the name exists.
51
52
  It only enforces capitalization IF it does.
52
53
  """
53
- if obj.name:
54
- return obj.name[0].isupper(), self.message
55
- return True, "" # Force passing if obj.name doesn't exist
54
+ if isinstance(obj, Workflow):
55
+ if obj.name:
56
+ if obj.name[0] != "_":
57
+ return obj.name[0].isupper(), self.message
58
+ else:
59
+ if obj.name:
60
+ return obj.name[0].isupper(), self.message
61
+
62
+ return True, "" # Force passing
@@ -8,6 +8,7 @@ from ..models.step import Step
8
8
  from ..rule import Rule
9
9
  from ..utils import LintLevels, Settings
10
10
 
11
+
11
12
  class RuleNameExists(Rule):
12
13
  """Rule to enforce a 'name' key exists for every object in GitHub Actions.
13
14
 
@@ -6,6 +6,7 @@ from ..models.job import Job
6
6
  from ..rule import Rule
7
7
  from ..utils import LintLevels, Settings
8
8
 
9
+
9
10
  class RuleJobRunnerVersionPinned(Rule):
10
11
  """Rule to enforce pinned Runner OS versions.
11
12
 
@@ -6,6 +6,7 @@ from ..models.step import Step
6
6
  from ..rule import Rule
7
7
  from ..utils import LintLevels, Settings
8
8
 
9
+
9
10
  class RuleStepUsesApproved(Rule):
10
11
  """Rule to enforce that all Actions have been pre-approved.
11
12
 
@@ -6,6 +6,7 @@ from ..models.step import Step
6
6
  from ..rule import Rule
7
7
  from ..utils import LintLevels, Settings
8
8
 
9
+
9
10
  class RuleStepUsesPinned(Rule):
10
11
  """Rule to contain the enforcement logic for pinning Actions versions.
11
12
 
@@ -94,4 +95,7 @@ class RuleStepUsesPinned(Rule):
94
95
  if len(ref) != 40:
95
96
  return False, "Please use the full commit sha to pin the action"
96
97
 
98
+ if not obj.uses_comment:
99
+ return False, "Please comment the version of the action commit sha"
100
+
97
101
  return True, ""
@@ -1,3 +1,5 @@
1
+ """ Rule to enforce all GitHub outputs with more than one words use an underscore."""
2
+
1
3
  import re
2
4
 
3
5
  from typing import Optional, Union, Tuple
@@ -8,8 +10,9 @@ from ..models.workflow import Workflow
8
10
  from ..models.step import Step
9
11
  from ..utils import LintLevels, Settings
10
12
 
13
+
11
14
  class RuleUnderscoreOutputs(Rule):
12
- """Rule to enforce all GitHub 'outputs' more than one words contain an underscore.
15
+ """Rule to enforce all GitHub outputs with more than one word use an underscore.
13
16
 
14
17
  A simple standard to ensure uniformity in naming.
15
18
  """
@@ -98,9 +101,11 @@ class RuleUnderscoreOutputs(Rule):
98
101
 
99
102
  if isinstance(obj, Step):
100
103
  if obj.run:
101
- outputs.extend(re.findall(
102
- r"\b([a-zA-Z0-9_-]+)\s*=\s*[^=]*>>\s*\$GITHUB_OUTPUT",
103
- obj.run))
104
+ outputs.extend(
105
+ re.findall(
106
+ r"\b([a-zA-Z0-9_-]+)\s*=\s*[^=]*>>\s*\$GITHUB_OUTPUT", obj.run
107
+ )
108
+ )
104
109
 
105
110
  for output_name in outputs:
106
111
  if "-" in output_name:
@@ -12,6 +12,7 @@ from ruamel.yaml import YAML
12
12
 
13
13
  yaml = YAML()
14
14
 
15
+
15
16
  @dataclass
16
17
  class Colors:
17
18
  """Class containing color codes for printing strings to output."""
@@ -25,6 +26,7 @@ class Colors:
25
26
  cyan = "36m"
26
27
  white = "37m"
27
28
 
29
+
28
30
  @dataclass
29
31
  class LintLevel:
30
32
  """Class to contain the numeric level and color of linting."""
@@ -32,6 +34,7 @@ class LintLevel:
32
34
  code: int
33
35
  color: Colors
34
36
 
37
+
35
38
  class LintLevels(LintLevel, Enum):
36
39
  """Collection of the different types of LintLevels available."""
37
40
 
@@ -39,6 +42,7 @@ class LintLevels(LintLevel, Enum):
39
42
  WARNING = 1, Colors.yellow
40
43
  ERROR = 2, Colors.red
41
44
 
45
+
42
46
  class LintFinding:
43
47
  """Represents a problem detected by linting."""
44
48
 
@@ -57,6 +61,7 @@ class LintFinding:
57
61
  f"{self.description}"
58
62
  )
59
63
 
64
+
60
65
  @dataclass
61
66
  class Action:
62
67
  """Collection of the metadata associated with a GitHub Action."""
@@ -93,13 +98,16 @@ class Action:
93
98
  """
94
99
  return not self.__eq__(other)
95
100
 
101
+
96
102
  class SettingsError(Exception):
97
103
  """Custom Exception to indicate an error with loading Settings."""
98
104
 
99
105
  pass
100
106
 
107
+
101
108
  SettingsFromFactory = TypeVar("SettingsFromFactory", bound="Settings")
102
109
 
110
+
103
111
  class Settings:
104
112
  """Class that contains configuration-as-code for any portion of the app."""
105
113
 
@@ -49,6 +49,24 @@ jobs:
49
49
  return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
50
50
 
51
51
 
52
+ @pytest.fixture(name="underscore_name_workflow")
53
+ def fixture_underscore_name_workflow():
54
+ workflow = """\
55
+ name: _test
56
+ on:
57
+ workflow_dispatch:
58
+
59
+ jobs:
60
+ job-key:
61
+ name: test
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - name: test
65
+ run: echo test
66
+ """
67
+ return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
68
+
69
+
52
70
  @pytest.fixture(name="missing_name_workflow")
53
71
  def fixture_missing_name_workflow():
54
72
  workflow = """\
@@ -86,6 +104,11 @@ def test_rule_on_incorrect_workflow_name(rule, incorrect_workflow):
86
104
  assert result is False
87
105
 
88
106
 
107
+ def test_rule_on_underscore_name_workflow(rule, underscore_name_workflow):
108
+ result, _ = rule.fn(underscore_name_workflow)
109
+ assert result is True
110
+
111
+
89
112
  def test_rule_on_incorrect_job_name(rule, incorrect_workflow):
90
113
  result, _ = rule.fn(incorrect_workflow.jobs["job-key"])
91
114
  assert result is False
@@ -47,6 +47,9 @@ jobs:
47
47
  job-key:
48
48
  runs-on: ubuntu-22.04
49
49
  steps:
50
+ - name: Test 3rd Party Action without version pinned
51
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
52
+
50
53
  - name: Test External Branch
51
54
  uses: actions/checkout@main
52
55
 
@@ -78,20 +81,26 @@ def test_rule_on_correct_workflow(rule, correct_workflow):
78
81
  assert result is True
79
82
 
80
83
 
81
- def test_rule_on_incorrect_workflow_external_branch(rule, incorrect_workflow):
84
+ def test_rule_on_incorrect_workflow_version_comment(rule, incorrect_workflow):
82
85
  result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[0])
83
86
  assert result is False
87
+ assert "the version of the action commit sha" in message
88
+
89
+
90
+ def test_rule_on_incorrect_workflow_external_branch(rule, incorrect_workflow):
91
+ result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[1])
92
+ assert result is False
84
93
  assert "Please pin the action" in message
85
94
 
86
95
 
87
96
  def test_rule_on_incorrect_workflow_hex(rule, incorrect_workflow):
88
- result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[1])
97
+ result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[2])
89
98
  assert result is False
90
99
  assert "Please use the full commit sha" in message
91
100
 
92
101
 
93
102
  def test_rule_on_incorrect_workflow_internal_commit(rule, incorrect_workflow):
94
- result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[2])
103
+ result, message = rule.fn(incorrect_workflow.jobs["job-key"].steps[3])
95
104
  assert result is False
96
105
  assert "Please pin to main" in message
97
106
 
@@ -141,6 +141,7 @@ jobs:
141
141
  """
142
142
  return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
143
143
 
144
+
144
145
  @pytest.fixture(name="misc_workflow")
145
146
  def fixture_misc_workflow():
146
147
  workflow = """\
@@ -164,6 +165,7 @@ jobs:
164
165
  """
165
166
  return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
166
167
 
168
+
167
169
  @pytest.fixture(name="no_output_workflow")
168
170
  def fixture_no_output_workflow():
169
171
  workflow = """\
@@ -184,7 +186,6 @@ jobs:
184
186
  return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
185
187
 
186
188
 
187
-
188
189
  @pytest.fixture(name="rule")
189
190
  def fixture_rule():
190
191
  return RuleUnderscoreOutputs()