bitwarden_workflow_linter 0.8.1__tar.gz → 0.9.0__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.
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/ci.yml +14 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/PKG-INFO +19 -16
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/README.md +18 -15
- bitwarden_workflow_linter-0.9.0/settings.yaml +24 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/__about__.py +1 -1
- bitwarden_workflow_linter-0.9.0/src/bitwarden_workflow_linter/default_settings.yaml +24 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/lint.py +23 -4
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/models/workflow.py +2 -0
- bitwarden_workflow_linter-0.9.0/src/bitwarden_workflow_linter/rules/permissions_exist.py +43 -0
- bitwarden_workflow_linter-0.9.0/tests/rules/test_permissions_exist.py +96 -0
- bitwarden_workflow_linter-0.8.1/.github/workflows/lint-examples.yml +0 -37
- bitwarden_workflow_linter-0.8.1/settings.yaml +0 -21
- bitwarden_workflow_linter-0.8.1/src/bitwarden_workflow_linter/default_settings.yaml +0 -21
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.editorconfig +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.gitattributes +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/CODEOWNERS +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/renovate.json +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/_version_type.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/bwwl_operations.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/cd.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/enforce-labels.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/ci.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/example-references/_build.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/example-references/_docker.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/example-references/_test.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/example-references/_version.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/example.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/examples/scan.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/scan.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.gitignore +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.husky/pre-commit +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.python-version +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/CONTRIBUTING.md +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/LICENSE.txt +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/Pipfile +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/Pipfile.lock +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/RULE_ROLLOUT.md +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/SECURITY.md +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/Taskfile.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/package-lock.json +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/package.json +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/pylintrc +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/pyproject.toml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/pyproject.toml.tpl +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/__init__.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/actions.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/cli.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/default_actions.json +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/load.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/models/__init__.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/models/job.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/models/step.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rule.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/__init__.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/check_pr_target.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/job_environment_prefix.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/name_capitalized.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/name_exists.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/pinned_job_runner.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/run_actionlint.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/step_approved.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/step_pinned.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/rules/underscore_outputs.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/src/bitwarden_workflow_linter/utils.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/__init__.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/conftest.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test-alt.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test-min-incorrect.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test-min.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test-outputs-incorrect.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test.yml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test_a.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test_workflow.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test_workflow_incorrect.yaml +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/__init__.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_check_pr_target.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_job_environment_prefix.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_name_capitalized.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_name_exists.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_pinned_job_runner.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_run_actionlint.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_step_approved.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_step_pinned.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_underscore_output.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_job.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_lint.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_load.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_rule.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_step.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_utils.py +0 -0
- {bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/test_workflow.py +0 -0
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/ci.yml
RENAMED
@@ -7,6 +7,8 @@ on:
|
|
7
7
|
- "tests/**"
|
8
8
|
workflow_dispatch:
|
9
9
|
|
10
|
+
permissions: read-all
|
11
|
+
|
10
12
|
jobs:
|
11
13
|
test:
|
12
14
|
name: CI workflow-linter (v2)
|
@@ -31,3 +33,15 @@ jobs:
|
|
31
33
|
|
32
34
|
- name: Check type hinting
|
33
35
|
run: pipenv run pytype src
|
36
|
+
|
37
|
+
- name: Test against example workflows
|
38
|
+
# run notes:
|
39
|
+
# - Changing directories will help catch any repo specific paths in the linter
|
40
|
+
# that would not work in a different repository
|
41
|
+
# - Changing directories utilizes the default_settings.yaml rather than this repos
|
42
|
+
# settings.yaml, which better simulates running from another repository
|
43
|
+
# - Using strict to ensure that our examples pass all checks including warnings
|
44
|
+
run: |
|
45
|
+
pipenv run pip install -e .
|
46
|
+
cd .github/workflows
|
47
|
+
pipenv run bwwl lint --strict -f ./examples
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: bitwarden_workflow_linter
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
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
|
@@ -60,20 +60,20 @@ the below and create a `settings.yaml` in the directory that `bwwl` will be runn
|
|
60
60
|
|
61
61
|
```yaml
|
62
62
|
enabled_rules:
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
63
|
+
- id: bitwarden_workflow_linter.rules.name_exists.RuleNameExists
|
64
|
+
level: error
|
65
|
+
- id: bitwarden_workflow_linter.rules.name_capitalized.RuleNameCapitalized
|
66
|
+
level: error
|
67
|
+
- id: bitwarden_workflow_linter.rules.pinned_job_runner.RuleJobRunnerVersionPinned
|
68
|
+
level: error
|
69
|
+
- id: bitwarden_workflow_linter.rules.job_environment_prefix.RuleJobEnvironmentPrefix
|
70
|
+
level: error
|
71
|
+
- id: bitwarden_workflow_linter.rules.step_pinned.RuleStepUsesPinned
|
72
|
+
level: error
|
73
|
+
- id: bitwarden_workflow_linter.rules.underscore_outputs.RuleUnderscoreOutputs
|
74
|
+
level: warning
|
75
|
+
- id: bitwarden_workflow_linter.rules.run_actionlint.RunActionlint
|
76
|
+
level: warning
|
77
77
|
|
78
78
|
approved_actions_path: default_actions.json
|
79
79
|
```
|
@@ -187,7 +187,10 @@ By default, a new Rule needs five things:
|
|
187
187
|
not support Rules that check against multiple objects at a time OR file level formatting (one empty between each step or
|
188
188
|
two empty lines between each job)
|
189
189
|
|
190
|
-
|
190
|
+
_IMPORTANT: A rule must be implemented and tested then merged into `main` before it can be activated.<br>_
|
191
|
+
This is because the released version of bwwl will use the current `settings.yaml` file, but it will not have the new rule functionality yet and cause an error in the workflow linting of this repository.
|
192
|
+
|
193
|
+
To activate a rule after implementing and releasing it, add it to `settings.yaml` in the project's base folder
|
191
194
|
and `src/bitwarden_workflow_linter/default_settings.yaml` to make the rule default
|
192
195
|
|
193
196
|
Before creating a new rule please read the [Workflow linter rule rollout process](./RULE_ROLLOUT.md) document in which you'll find the process for rolling out new workflow linter rules.
|
@@ -34,20 +34,20 @@ the below and create a `settings.yaml` in the directory that `bwwl` will be runn
|
|
34
34
|
|
35
35
|
```yaml
|
36
36
|
enabled_rules:
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
37
|
+
- id: bitwarden_workflow_linter.rules.name_exists.RuleNameExists
|
38
|
+
level: error
|
39
|
+
- id: bitwarden_workflow_linter.rules.name_capitalized.RuleNameCapitalized
|
40
|
+
level: error
|
41
|
+
- id: bitwarden_workflow_linter.rules.pinned_job_runner.RuleJobRunnerVersionPinned
|
42
|
+
level: error
|
43
|
+
- id: bitwarden_workflow_linter.rules.job_environment_prefix.RuleJobEnvironmentPrefix
|
44
|
+
level: error
|
45
|
+
- id: bitwarden_workflow_linter.rules.step_pinned.RuleStepUsesPinned
|
46
|
+
level: error
|
47
|
+
- id: bitwarden_workflow_linter.rules.underscore_outputs.RuleUnderscoreOutputs
|
48
|
+
level: warning
|
49
|
+
- id: bitwarden_workflow_linter.rules.run_actionlint.RunActionlint
|
50
|
+
level: warning
|
51
51
|
|
52
52
|
approved_actions_path: default_actions.json
|
53
53
|
```
|
@@ -161,7 +161,10 @@ By default, a new Rule needs five things:
|
|
161
161
|
not support Rules that check against multiple objects at a time OR file level formatting (one empty between each step or
|
162
162
|
two empty lines between each job)
|
163
163
|
|
164
|
-
|
164
|
+
_IMPORTANT: A rule must be implemented and tested then merged into `main` before it can be activated.<br>_
|
165
|
+
This is because the released version of bwwl will use the current `settings.yaml` file, but it will not have the new rule functionality yet and cause an error in the workflow linting of this repository.
|
166
|
+
|
167
|
+
To activate a rule after implementing and releasing it, add it to `settings.yaml` in the project's base folder
|
165
168
|
and `src/bitwarden_workflow_linter/default_settings.yaml` to make the rule default
|
166
169
|
|
167
170
|
Before creating a new rule please read the [Workflow linter rule rollout process](./RULE_ROLLOUT.md) document in which you'll find the process for rolling out new workflow linter rules.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
enabled_rules:
|
2
|
+
- id: bitwarden_workflow_linter.rules.name_exists.RuleNameExists
|
3
|
+
level: error
|
4
|
+
- id: bitwarden_workflow_linter.rules.name_capitalized.RuleNameCapitalized
|
5
|
+
level: error
|
6
|
+
- id: bitwarden_workflow_linter.rules.pinned_job_runner.RuleJobRunnerVersionPinned
|
7
|
+
level: error
|
8
|
+
- id: bitwarden_workflow_linter.rules.job_environment_prefix.RuleJobEnvironmentPrefix
|
9
|
+
level: error
|
10
|
+
# - id: bitwarden_workflow_linter.rules.step_approved.RuleStepUsesApproved
|
11
|
+
# level: error
|
12
|
+
- id: bitwarden_workflow_linter.rules.step_pinned.RuleStepUsesPinned
|
13
|
+
level: error
|
14
|
+
- id: bitwarden_workflow_linter.rules.underscore_outputs.RuleUnderscoreOutputs
|
15
|
+
level: warning
|
16
|
+
- id: bitwarden_workflow_linter.rules.run_actionlint.RunActionlint
|
17
|
+
level: warning
|
18
|
+
- id: bitwarden_workflow_linter.rules.check_pr_target.RuleCheckPrTarget
|
19
|
+
level: warning
|
20
|
+
# Cannot add this in until the rule functionality is merged through to main
|
21
|
+
# - id: bitwarden_workflow_linter.rules.permissions_exist.RulePermissionsExist
|
22
|
+
# level: warning
|
23
|
+
|
24
|
+
approved_actions_path: default_actions.json
|
@@ -0,0 +1,24 @@
|
|
1
|
+
enabled_rules:
|
2
|
+
- id: bitwarden_workflow_linter.rules.name_exists.RuleNameExists
|
3
|
+
level: error
|
4
|
+
- id: bitwarden_workflow_linter.rules.name_capitalized.RuleNameCapitalized
|
5
|
+
level: error
|
6
|
+
- id: bitwarden_workflow_linter.rules.pinned_job_runner.RuleJobRunnerVersionPinned
|
7
|
+
level: error
|
8
|
+
- id: bitwarden_workflow_linter.rules.job_environment_prefix.RuleJobEnvironmentPrefix
|
9
|
+
level: error
|
10
|
+
# - id: bitwarden_workflow_linter.rules.step_approved.RuleStepUsesApproved
|
11
|
+
# level: error
|
12
|
+
- id: bitwarden_workflow_linter.rules.step_pinned.RuleStepUsesPinned
|
13
|
+
level: error
|
14
|
+
- id: bitwarden_workflow_linter.rules.underscore_outputs.RuleUnderscoreOutputs
|
15
|
+
level: warning
|
16
|
+
- id: bitwarden_workflow_linter.rules.run_actionlint.RunActionlint
|
17
|
+
level: warning
|
18
|
+
- id: bitwarden_workflow_linter.rules.check_pr_target.RuleCheckPrTarget
|
19
|
+
level: warning
|
20
|
+
# Cannot add this in until the rule functionality is merged through to main
|
21
|
+
# - id: bitwarden_workflow_linter.rules.permissions_exist.RulePermissionsExist
|
22
|
+
# level: warning
|
23
|
+
|
24
|
+
approved_actions_path: default_actions.json
|
@@ -4,7 +4,6 @@ Workflows."""
|
|
4
4
|
import argparse
|
5
5
|
import os
|
6
6
|
|
7
|
-
from functools import reduce
|
8
7
|
from typing import Optional
|
9
8
|
|
10
9
|
from .load import WorkflowBuilder, Rules
|
@@ -115,6 +114,7 @@ class LinterCmd:
|
|
115
114
|
if len(findings) > 0:
|
116
115
|
for finding in findings:
|
117
116
|
print(f" - {finding}")
|
117
|
+
print(f"Issues found by {len(findings)} rules in {filename}")
|
118
118
|
print()
|
119
119
|
|
120
120
|
max_error_level = self.get_max_error_level(findings)
|
@@ -162,9 +162,28 @@ class LinterCmd:
|
|
162
162
|
files = self.generate_files(input_files)
|
163
163
|
|
164
164
|
if len(input_files) > 0:
|
165
|
-
|
166
|
-
|
167
|
-
|
165
|
+
files_with_issues = []
|
166
|
+
return_code = 0
|
167
|
+
for file in files:
|
168
|
+
return_value = self.lint_file(file)
|
169
|
+
if return_value > 0:
|
170
|
+
files_with_issues.append(file)
|
171
|
+
return_code = max(return_code, return_value)
|
172
|
+
|
173
|
+
if len(files_with_issues) > 0:
|
174
|
+
newline = "\n" # For compatibility with Python 3.11
|
175
|
+
print(
|
176
|
+
f"""Found {len(files_with_issues)} file(s) with issues:
|
177
|
+
{f"{newline} ".join(files_with_issues)}
|
178
|
+
|
179
|
+
For help, refer to
|
180
|
+
- Workflow Syntax: \
|
181
|
+
https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions
|
182
|
+
- Bitwarden Examples: \
|
183
|
+
https://github.com/bitwarden/workflow-linter/tree/main/.github/workflows/examples")"""
|
184
|
+
)
|
185
|
+
else:
|
186
|
+
print("No issues found")
|
168
187
|
|
169
188
|
if return_code == 1 and not strict:
|
170
189
|
return_code = 0
|
@@ -27,6 +27,7 @@ class Workflow:
|
|
27
27
|
name: Optional[str] = None
|
28
28
|
on: Optional[CommentedMap] = None
|
29
29
|
jobs: Optional[Dict[str, Job]] = None
|
30
|
+
permissions: Optional[object] = None # This can be a CommentedMap or a string
|
30
31
|
|
31
32
|
@classmethod
|
32
33
|
def init(cls: Self, key: str, filename: str, data: CommentedMap) -> Self:
|
@@ -35,6 +36,7 @@ class Workflow:
|
|
35
36
|
"filename": filename,
|
36
37
|
"name": data["name"] if "name" in data else None,
|
37
38
|
"on": data["on"] if "on" in data else None,
|
39
|
+
"permissions": data["permissions"] if "permissions" in data else None,
|
38
40
|
}
|
39
41
|
|
40
42
|
new_workflow = cls.from_dict(init_data)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""A Rule to enforce that the required permissions are specified on every workflow"""
|
2
|
+
|
3
|
+
from typing import Optional, Tuple
|
4
|
+
|
5
|
+
from ..models.workflow import Workflow
|
6
|
+
from ..rule import Rule
|
7
|
+
from ..utils import LintLevels, Settings
|
8
|
+
|
9
|
+
|
10
|
+
class RulePermissionsExist(Rule):
|
11
|
+
"""
|
12
|
+
Rule to enforce that the required permissions are specified on every workflow.
|
13
|
+
|
14
|
+
To allow for keeping repository default GITHUB_TOKEN permissions to a minimum,
|
15
|
+
each workflow must specify the permissions block (including read).
|
16
|
+
|
17
|
+
This has 2 benefits:
|
18
|
+
1) When changing the default repository setting to a more restrictive one,
|
19
|
+
the workflows will not be affected.
|
20
|
+
2) It is clear to the user what permissions are required for the workflow to run.
|
21
|
+
"""
|
22
|
+
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
settings: Optional[Settings] = None,
|
26
|
+
lint_level: Optional[LintLevels] = LintLevels.NONE,
|
27
|
+
) -> None:
|
28
|
+
self.message = (
|
29
|
+
"A top-level permissions section must be configured in the workflow."
|
30
|
+
)
|
31
|
+
self.on_fail = lint_level
|
32
|
+
self.compatibility = [Workflow]
|
33
|
+
self.settings = settings
|
34
|
+
|
35
|
+
def permissions_exist(self, obj: Workflow) -> bool:
|
36
|
+
if obj.permissions is None:
|
37
|
+
return False
|
38
|
+
return True
|
39
|
+
|
40
|
+
def fn(self, obj: Workflow) -> Tuple[bool, str]:
|
41
|
+
if not self.permissions_exist(obj):
|
42
|
+
return False, f"{self.message}"
|
43
|
+
return True, ""
|
@@ -0,0 +1,96 @@
|
|
1
|
+
"""Test src/bitwarden_workflow_linter/rules/permissions_exist.py."""
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from ruamel.yaml import YAML
|
6
|
+
|
7
|
+
from src.bitwarden_workflow_linter.load import WorkflowBuilder
|
8
|
+
from src.bitwarden_workflow_linter.rules.permissions_exist import RulePermissionsExist
|
9
|
+
|
10
|
+
|
11
|
+
yaml = YAML()
|
12
|
+
|
13
|
+
|
14
|
+
@pytest.fixture(name="correct_workflow_read_all")
|
15
|
+
def fixture_correct_workflow_read_all():
|
16
|
+
workflow = """\
|
17
|
+
---
|
18
|
+
name: Test Workflow
|
19
|
+
|
20
|
+
on:
|
21
|
+
workflow_dispatch:
|
22
|
+
|
23
|
+
permissions: read-all
|
24
|
+
|
25
|
+
jobs:
|
26
|
+
job-key:
|
27
|
+
name: Test
|
28
|
+
runs-on: ubuntu-latest
|
29
|
+
steps:
|
30
|
+
- name: Test
|
31
|
+
run: echo test
|
32
|
+
"""
|
33
|
+
return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
|
34
|
+
|
35
|
+
|
36
|
+
@pytest.fixture(name="correct_workflow_scoped_permissions")
|
37
|
+
def fixture_correct_workflow_scoped_permissions():
|
38
|
+
workflow = """\
|
39
|
+
---
|
40
|
+
on:
|
41
|
+
workflow_dispatch:
|
42
|
+
|
43
|
+
permissions:
|
44
|
+
checks: write
|
45
|
+
contents: read
|
46
|
+
id-token: write
|
47
|
+
pull-requests: write
|
48
|
+
|
49
|
+
|
50
|
+
jobs:
|
51
|
+
job-key:
|
52
|
+
runs-on: ubuntu-latest
|
53
|
+
steps:
|
54
|
+
- run: echo test
|
55
|
+
"""
|
56
|
+
return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
|
57
|
+
|
58
|
+
|
59
|
+
@pytest.fixture(name="incorrect_workflow_missing_permissions")
|
60
|
+
def fixture_incorrect_workflow_missing_permissions():
|
61
|
+
workflow = """\
|
62
|
+
---
|
63
|
+
on:
|
64
|
+
workflow_dispatch:
|
65
|
+
|
66
|
+
jobs:
|
67
|
+
job-key:
|
68
|
+
runs-on: ubuntu-latest
|
69
|
+
steps:
|
70
|
+
- run: echo test
|
71
|
+
"""
|
72
|
+
return WorkflowBuilder.build(workflow=yaml.load(workflow), from_file=False)
|
73
|
+
|
74
|
+
|
75
|
+
@pytest.fixture(name="rule")
|
76
|
+
def fixture_rule():
|
77
|
+
return RulePermissionsExist()
|
78
|
+
|
79
|
+
|
80
|
+
def test_rule_on_correct_workflow_read_all(rule, correct_workflow_read_all):
|
81
|
+
result, _ = rule.fn(correct_workflow_read_all)
|
82
|
+
assert result is True
|
83
|
+
|
84
|
+
|
85
|
+
def test_rule_on_correct_workflow_scoped_permissions(
|
86
|
+
rule, correct_workflow_scoped_permissions
|
87
|
+
):
|
88
|
+
result, _ = rule.fn(correct_workflow_scoped_permissions)
|
89
|
+
assert result is True
|
90
|
+
|
91
|
+
|
92
|
+
def test_rule_on_incorrect_workflow_missing_permissions(
|
93
|
+
rule, incorrect_workflow_missing_permissions
|
94
|
+
):
|
95
|
+
result, _ = rule.fn(incorrect_workflow_missing_permissions)
|
96
|
+
assert result is False
|
@@ -1,37 +0,0 @@
|
|
1
|
-
name: Lint Example Workflows
|
2
|
-
|
3
|
-
on:
|
4
|
-
pull_request:
|
5
|
-
branches:
|
6
|
-
- "main"
|
7
|
-
merge_group:
|
8
|
-
types: [checks_requested]
|
9
|
-
workflow_call:
|
10
|
-
workflow_dispatch:
|
11
|
-
|
12
|
-
jobs:
|
13
|
-
test-lint-workflow:
|
14
|
-
name: Test Lint Workflow
|
15
|
-
runs-on: ubuntu-24.04
|
16
|
-
steps:
|
17
|
-
- name: Checkout Branch
|
18
|
-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
19
|
-
|
20
|
-
- name: Get workflow list
|
21
|
-
id: workflow-list
|
22
|
-
run: |
|
23
|
-
WORKFLOW_LIST=$(find .github/workflows/examples -maxdepth 1 -type f | xargs -I {} echo -n "{} ")
|
24
|
-
echo "workflow-list=$WORKFLOW_LIST" >> $GITHUB_OUTPUT
|
25
|
-
|
26
|
-
- name: Lint examples
|
27
|
-
id: lint-examples
|
28
|
-
uses: bitwarden/gh-actions/lint-workflow@main
|
29
|
-
with:
|
30
|
-
workflows: ${{ steps.workflow-list.outputs.workflow-list }}
|
31
|
-
|
32
|
-
- name: Failure message
|
33
|
-
if: ${{ failure() && steps.lint-examples.conclusion == 'failure' }}
|
34
|
-
run: |
|
35
|
-
echo "Changes to the workflow linter should include updating workflow \
|
36
|
-
examples in .github/workflows/examples directory"
|
37
|
-
exit 1
|
@@ -1,21 +0,0 @@
|
|
1
|
-
enabled_rules:
|
2
|
-
- id: bitwarden_workflow_linter.rules.name_exists.RuleNameExists
|
3
|
-
level: error
|
4
|
-
- id: bitwarden_workflow_linter.rules.name_capitalized.RuleNameCapitalized
|
5
|
-
level: error
|
6
|
-
- id: bitwarden_workflow_linter.rules.pinned_job_runner.RuleJobRunnerVersionPinned
|
7
|
-
level: error
|
8
|
-
- id: bitwarden_workflow_linter.rules.job_environment_prefix.RuleJobEnvironmentPrefix
|
9
|
-
level: error
|
10
|
-
# - id: bitwarden_workflow_linter.rules.step_approved.RuleStepUsesApproved
|
11
|
-
# level: error
|
12
|
-
- id: bitwarden_workflow_linter.rules.step_pinned.RuleStepUsesPinned
|
13
|
-
level: error
|
14
|
-
- id: bitwarden_workflow_linter.rules.underscore_outputs.RuleUnderscoreOutputs
|
15
|
-
level: warning
|
16
|
-
- id: bitwarden_workflow_linter.rules.run_actionlint.RunActionlint
|
17
|
-
level: warning
|
18
|
-
- id: bitwarden_workflow_linter.rules.check_pr_target.RuleCheckPrTarget
|
19
|
-
level: warning
|
20
|
-
|
21
|
-
approved_actions_path: default_actions.json
|
@@ -1,21 +0,0 @@
|
|
1
|
-
enabled_rules:
|
2
|
-
- id: bitwarden_workflow_linter.rules.name_exists.RuleNameExists
|
3
|
-
level: error
|
4
|
-
- id: bitwarden_workflow_linter.rules.name_capitalized.RuleNameCapitalized
|
5
|
-
level: error
|
6
|
-
- id: bitwarden_workflow_linter.rules.pinned_job_runner.RuleJobRunnerVersionPinned
|
7
|
-
level: error
|
8
|
-
- id: bitwarden_workflow_linter.rules.job_environment_prefix.RuleJobEnvironmentPrefix
|
9
|
-
level: error
|
10
|
-
# - id: bitwarden_workflow_linter.rules.step_approved.RuleStepUsesApproved
|
11
|
-
# level: error
|
12
|
-
- id: bitwarden_workflow_linter.rules.step_pinned.RuleStepUsesPinned
|
13
|
-
level: error
|
14
|
-
- id: bitwarden_workflow_linter.rules.underscore_outputs.RuleUnderscoreOutputs
|
15
|
-
level: warning
|
16
|
-
- id: bitwarden_workflow_linter.rules.run_actionlint.RunActionlint
|
17
|
-
level: warning
|
18
|
-
- id: bitwarden_workflow_linter.rules.check_pr_target.RuleCheckPrTarget
|
19
|
-
level: warning
|
20
|
-
|
21
|
-
approved_actions_path: default_actions.json
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/PULL_REQUEST_TEMPLATE.md
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/cd.yml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/.github/workflows/scan.yml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test-alt.yml
RENAMED
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test-min.yaml
RENAMED
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/fixtures/test_a.yaml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_name_exists.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{bitwarden_workflow_linter-0.8.1 → bitwarden_workflow_linter-0.9.0}/tests/rules/test_step_pinned.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|