bitwarden_workflow_linter 0.3.0__tar.gz → 0.4.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.
Files changed (75) hide show
  1. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/workflows/scan.yml +2 -2
  2. bitwarden_workflow_linter-0.4.0/.github/workflows/update_actions.yml +118 -0
  3. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/PKG-INFO +3 -2
  4. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/__about__.py +1 -1
  5. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/actions.py +44 -20
  6. bitwarden_workflow_linter-0.4.0/src/bitwarden_workflow_linter/default_actions.json +372 -0
  7. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/job_environment_prefix.py +8 -2
  8. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/name_capitalized.py +2 -1
  9. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/step_approved.py +8 -11
  10. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/step_pinned.py +1 -1
  11. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/underscore_outputs.py +1 -9
  12. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/fixtures/test.yml +2 -2
  13. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_step_approved.py +0 -6
  14. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_step_pinned.py +6 -0
  15. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_underscore_output.py +1 -20
  16. bitwarden_workflow_linter-0.3.0/src/bitwarden_workflow_linter/default_actions.json +0 -267
  17. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.editorconfig +0 -0
  18. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.gitattributes +0 -0
  19. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/CODEOWNERS +0 -0
  20. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  21. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  22. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/renovate.json +0 -0
  23. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/workflows/_version_type.yml +0 -0
  24. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/workflows/cd.yml +0 -0
  25. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/workflows/ci.yml +0 -0
  26. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.github/workflows/enforce-labels.yml +0 -0
  27. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.gitignore +0 -0
  28. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.husky/pre-commit +0 -0
  29. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/.python-version +0 -0
  30. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/CONTRIBUTING.md +0 -0
  31. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/LICENSE.txt +0 -0
  32. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/Pipfile +0 -0
  33. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/Pipfile.lock +0 -0
  34. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/README.md +0 -0
  35. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/SECURITY.md +0 -0
  36. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/Taskfile.yml +0 -0
  37. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/package-lock.json +0 -0
  38. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/package.json +0 -0
  39. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/pylintrc +0 -0
  40. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/pyproject.toml +0 -0
  41. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/pyproject.toml.tpl +0 -0
  42. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/settings.yaml +0 -0
  43. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/__init__.py +0 -0
  44. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/cli.py +0 -0
  45. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/default_settings.yaml +0 -0
  46. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/lint.py +0 -0
  47. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/load.py +0 -0
  48. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/models/__init__.py +0 -0
  49. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/models/job.py +0 -0
  50. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/models/step.py +0 -0
  51. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/models/workflow.py +0 -0
  52. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rule.py +0 -0
  53. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/__init__.py +0 -0
  54. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/name_exists.py +0 -0
  55. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/rules/pinned_job_runner.py +0 -0
  56. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/src/bitwarden_workflow_linter/utils.py +0 -0
  57. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/__init__.py +0 -0
  58. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/conftest.py +0 -0
  59. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/fixtures/test-alt.yml +0 -0
  60. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/fixtures/test-min-incorrect.yaml +0 -0
  61. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/fixtures/test-min.yaml +0 -0
  62. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/fixtures/test-outputs-incorrect.yml +0 -0
  63. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/fixtures/test_a.yaml +0 -0
  64. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/__init__.py +0 -0
  65. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_job_environment_prefix.py +0 -0
  66. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_name_capitalized.py +0 -0
  67. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_name_exists.py +0 -0
  68. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/rules/test_pinned_job_runner.py +0 -0
  69. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/test_job.py +0 -0
  70. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/test_lint.py +0 -0
  71. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/test_load.py +0 -0
  72. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/test_rule.py +0 -0
  73. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/test_step.py +0 -0
  74. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/tests/test_utils.py +0 -0
  75. {bitwarden_workflow_linter-0.3.0 → bitwarden_workflow_linter-0.4.0}/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@03a90e7253dadd7e2fff55f5dfbce647b39040a1 # 2.0.37
34
+ uses: checkmarx/ast-github-action@b74e8d514feae4ad5ad2b43e72590935bd2daf5f # 2.0.39
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@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1
49
+ uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
50
50
  with:
51
51
  sarif_file: cx_result.sarif
52
52
 
@@ -0,0 +1,118 @@
1
+ name: Update Approved Actions
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 0 */14 * *'
6
+
7
+ jobs:
8
+ actions-update:
9
+ name: "Update Approved Actions"
10
+ runs-on: ubuntu-24.04
11
+ steps:
12
+ - name: Login to Azure - CI Subscription
13
+ uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
14
+ with:
15
+ creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
16
+
17
+ - name: Retrieve secrets
18
+ id: retrieve-secrets
19
+ uses: bitwarden/gh-actions/get-keyvault-secrets@main
20
+ with:
21
+ keyvault: "bitwarden-ci"
22
+ secrets: "github-gpg-private-key,
23
+ github-gpg-private-key-passphrase"
24
+
25
+ - name: Import GPG key
26
+ uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0
27
+ with:
28
+ gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
29
+ passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
30
+ git_user_signingkey: true
31
+ git_commit_gpgsign: true
32
+
33
+ - name: Setup git
34
+ run: |
35
+ git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
36
+ git config --local user.name "bitwarden-devops-bot"
37
+
38
+ - name: Checkout Branch
39
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
40
+
41
+ - name: Set up Python 3.11
42
+ uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
43
+ with:
44
+ python-version: "3.11"
45
+
46
+ - name: Install bwwl binary
47
+ run: python -m pip install --upgrade bitwarden_workflow_linter
48
+
49
+ - name: Create Branch
50
+ id: create-branch
51
+ run: |
52
+ NAME="update-actions-$(date +'%Y%m%d-%H%M%S')"
53
+ git switch -c $NAME
54
+ echo "name=$NAME" >> $GITHUB_OUTPUT
55
+
56
+ - name: Run bwwl update
57
+ run: bwwl actions update -o src/bitwarden_workflow_linter/default_actions.json
58
+
59
+ - name: Check if there are changes to commit
60
+ id: new-changes
61
+ run: |
62
+ if [ -n "$(git status --porcelain)" ]; then
63
+ echo "new_changes=TRUE" >> $GITHUB_OUTPUT
64
+ else
65
+ echo "new_changes=FALSE" >> $GITHUB_OUTPUT
66
+ echo "No changes to commit!";
67
+ fi
68
+
69
+ - name: Commit changes
70
+ if: steps.new-changes.outputs.new_changes == 'TRUE'
71
+ env:
72
+ PR_BRANCH: ${{ steps.create-branch.outputs.name }}
73
+ run: |
74
+ git commit -m "Update approved actions" -a
75
+ git push origin $PR_BRANCH
76
+
77
+ - name: Generate GH App token
78
+ if: steps.new-changes.outputs.new_changes == 'TRUE'
79
+ uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
80
+ id: app-token
81
+ with:
82
+ app-id: ${{ secrets.GH_APP_ID }}
83
+ private-key: ${{ secrets.GH_APP_KEY }}
84
+ owner: ${{ github.repository_owner }}
85
+
86
+ - name: Create PR
87
+ if: steps.new-changes.outputs.new_changes == 'TRUE'
88
+ id: create-pr
89
+ env:
90
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
91
+ PR_BRANCH: ${{ steps.create-branch.outputs.name }}
92
+ TITLE: "Update bwwl Approved Actions"
93
+ run: |
94
+ PR_URL=$(gh pr create --title "$TITLE" \
95
+ --base "main" \
96
+ --head "$PR_BRANCH" \
97
+ --label "version:patch" \
98
+ --label "automated pr" \
99
+ --body "
100
+ ## Type of change
101
+ - [ ] Bug fix
102
+ - [ ] New feature development
103
+ - [X] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
104
+ - [ ] Build/deploy pipeline (DevOps)
105
+ - [ ] Other
106
+
107
+ ## Description
108
+ - This PR updates the approved actions for the Bitwarden Workflow Linter.")
109
+ echo "pr_number=${PR_URL##*/}" >> $GITHUB_OUTPUT
110
+
111
+ - name: Approve and Merge PR
112
+ if: ${{ steps.create-pr.outcome == 'success' }}
113
+ env:
114
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
115
+ PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
116
+ run: |
117
+ gh pr review $PR_NUMBER --approve
118
+ gh pr merge $PR_NUMBER --squash --auto --delete-branch
@@ -1,9 +1,10 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: bitwarden_workflow_linter
3
- Version: 0.3.0
3
+ Version: 0.4.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
7
+ License-File: LICENSE.txt
7
8
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
8
9
  Classifier: Operating System :: OS Independent
9
10
  Classifier: Programming Language :: Python :: 3
@@ -1,3 +1,3 @@
1
1
  """Metadata for Workflow Linter."""
2
2
 
3
- __version__ = "0.3.0"
3
+ __version__ = "0.4.0"
@@ -57,17 +57,22 @@ class ActionsCmd:
57
57
  parser_actions = subparsers.add_parser(
58
58
  "actions", help="!!BETA!!\nAdd or Update Actions in the pre-approved list."
59
59
  )
60
- parser_actions.add_argument(
61
- "-o", "--output", action="store", default="actions.json"
62
- )
63
60
  subparsers_actions = parser_actions.add_subparsers(
64
61
  required=True, dest="actions_command"
65
62
  )
66
- subparsers_actions.add_parser("update", help="update action versions")
63
+ parser_actions_update = subparsers_actions.add_parser(
64
+ "update", help="update action versions"
65
+ )
66
+ parser_actions_update.add_argument(
67
+ "-o", "--output", action="store", default="actions.json", help="output file"
68
+ )
67
69
  parser_actions_add = subparsers_actions.add_parser(
68
70
  "add", help="add action to approved list"
69
71
  )
70
72
  parser_actions_add.add_argument("name", help="action name [git owner/repo]")
73
+ parser_actions_add.add_argument(
74
+ "-o", "--output", action="store", default="actions.json", help="output file"
75
+ )
71
76
 
72
77
  return subparsers
73
78
 
@@ -127,29 +132,38 @@ class ActionsCmd:
127
132
  f"https://api.github.com/repos/{action.name}/releases/latest",
128
133
  action.name,
129
134
  )
130
- if not response:
131
- return None
135
+ if response is not None and response.status != 404:
136
+ tag_name = json.loads(response.data)["tag_name"]
132
137
 
133
- tag_name = json.loads(response.data)["tag_name"]
138
+ # Get the URL to the commit for the tag
139
+ response = self.get_github_api_response(
140
+ f"https://api.github.com/repos/{action.name}/git/ref/tags/{tag_name}",
141
+ action.name,
142
+ )
134
143
 
135
- # Get the URL to the commit for the tag
136
- response = self.get_github_api_response(
137
- f"https://api.github.com/repos/{action.name}/git/ref/tags/{tag_name}",
138
- action.name,
139
- )
140
- if not response:
141
- return None
144
+ if response is None or response.status != 200:
145
+ return None
146
+
147
+ if json.loads(response.data)["object"]["type"] != "commit":
148
+ url = json.loads(response.data)["object"]["url"]
149
+ # Follow the URL and get the commit sha for tags
150
+ response = self.get_github_api_response(url, action.name)
151
+ if not response:
152
+ return None
142
153
 
143
- if json.loads(response.data)["object"]["type"] == "commit":
144
154
  sha = json.loads(response.data)["object"]["sha"]
145
155
  else:
146
- url = json.loads(response.data)["object"]["url"]
147
- # Follow the URL and get the commit sha for tags
148
- response = self.get_github_api_response(url, action.name)
149
- if not response:
156
+ # Get tag from latest tag
157
+ response = self.get_github_api_response(
158
+ f"https://api.github.com/repos/{action.name}/tags",
159
+ action.name,
160
+ )
161
+
162
+ if response is None or response.status != 200:
150
163
  return None
151
164
 
152
- sha = json.loads(response.data)["object"]["sha"]
165
+ sha = json.loads(response.data)[0]["commit"]["sha"]
166
+ tag_name = json.loads(response.data)[0]["name"]
153
167
  except KeyError as err:
154
168
  raise GitHubApiSchemaError(
155
169
  f"Error with the GitHub API Response Schema for either /releases or"
@@ -182,10 +196,20 @@ class ActionsCmd:
182
196
  updated_actions = self.settings.approved_actions
183
197
  proposed_action = Action(name=new_action_name)
184
198
 
199
+ # Remove the action directory if the action is in a multi-actions repo
200
+ if len(new_action_name.split("/")) > 2:
201
+ modified_action = "/".join(new_action_name.split("/")[:-1])
202
+ print(
203
+ f" - {new_action_name} \033[{Colors.yellow}modified\033[0m to {modified_action}"
204
+ )
205
+ proposed_action = Action(name=modified_action)
206
+
185
207
  if self.exists(proposed_action):
186
208
  latest = self.get_latest_version(proposed_action)
187
209
  if latest:
188
210
  updated_actions[latest.name] = latest
211
+ else:
212
+ print(f" - {new_action_name} \033[{Colors.red}not found\033[0m")
189
213
 
190
214
  self.save_actions(updated_actions, filename)
191
215
  return 0
@@ -0,0 +1,372 @@
1
+ {
2
+ "Asana/create-app-attachment-github-action": {
3
+ "name": "Asana/create-app-attachment-github-action",
4
+ "sha": "affc72d57bac733d864d4189ed69a9cbd61a9e4f",
5
+ "version": "v1.3"
6
+ },
7
+ "Azure/functions-action": {
8
+ "name": "Azure/functions-action",
9
+ "sha": "fd80521afbba9a2a76a99ba1acc07aff8d733d11",
10
+ "version": "v1.5.2"
11
+ },
12
+ "Azure/get-keyvault-secrets": {
13
+ "name": "Azure/get-keyvault-secrets",
14
+ "sha": "b5c723b9ac7870c022b8c35befe620b7009b336f",
15
+ "version": "v1"
16
+ },
17
+ "Azure/login": {
18
+ "name": "Azure/login",
19
+ "sha": "a65d910e8af852a8061c627c456678983e180302",
20
+ "version": "v2.2.0"
21
+ },
22
+ "Azure/setup-helm": {
23
+ "name": "Azure/setup-helm",
24
+ "sha": "fe7b79cd5ee1e45176fcad797de68ecaf3ca4814",
25
+ "version": "v4.2.0"
26
+ },
27
+ "Swatinem/rust-cache": {
28
+ "name": "Swatinem/rust-cache",
29
+ "sha": "82a92a6e8fbeee089604da2575dc567ae9ddeaab",
30
+ "version": "v2.7.5"
31
+ },
32
+ "SwiftDocOrg/github-wiki-publish-action": {
33
+ "name": "SwiftDocOrg/github-wiki-publish-action",
34
+ "sha": "a87db85ed06e4431be29cfdcb22b9653881305d0",
35
+ "version": "1.0.0"
36
+ },
37
+ "SwiftDocOrg/swift-doc": {
38
+ "name": "SwiftDocOrg/swift-doc",
39
+ "sha": "f935ebfe524a0ff27bda07dadc3662e3e45b5125",
40
+ "version": "1.0.0-rc.1"
41
+ },
42
+ "act10ns/slack": {
43
+ "name": "act10ns/slack",
44
+ "sha": "44541246747a30eb3102d87f7a4cc5471b0ffb7d",
45
+ "version": "v2.1.0"
46
+ },
47
+ "actions-cool/check-user-permission": {
48
+ "name": "actions-cool/check-user-permission",
49
+ "sha": "956b2e73cdfe3bcb819bb7225e490cb3b18fd76e",
50
+ "version": "v2.2.1"
51
+ },
52
+ "actions/cache": {
53
+ "name": "actions/cache",
54
+ "sha": "1bd1e32a3bdc45362d1e726936510720a7c30a57",
55
+ "version": "v4.2.0"
56
+ },
57
+ "actions/checkout": {
58
+ "name": "actions/checkout",
59
+ "sha": "11bd71901bbe5b1630ceea73d27597364c9af683",
60
+ "version": "v4.2.2"
61
+ },
62
+ "actions/create-github-app-token": {
63
+ "name": "actions/create-github-app-token",
64
+ "sha": "5d869da34e18e7287c1daad50e0b8ea0f506ce69",
65
+ "version": "v1.11.0"
66
+ },
67
+ "actions/delete-package-versions": {
68
+ "name": "actions/delete-package-versions",
69
+ "sha": "e5bc658cc4c965c472efe991f8beea3981499c55",
70
+ "version": "v5.0.0"
71
+ },
72
+ "actions/deploy-pages": {
73
+ "name": "actions/deploy-pages",
74
+ "sha": "d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e",
75
+ "version": "v4.0.5"
76
+ },
77
+ "actions/download-artifact": {
78
+ "name": "actions/download-artifact",
79
+ "sha": "fa0a91b85d4f404e444e00e005971372dc801d16",
80
+ "version": "v4.1.8"
81
+ },
82
+ "actions/github-script": {
83
+ "name": "actions/github-script",
84
+ "sha": "60a0d83039c74a4aee543508d2ffcb1c3799cdea",
85
+ "version": "v7.0.1"
86
+ },
87
+ "actions/labeler": {
88
+ "name": "actions/labeler",
89
+ "sha": "8558fd74291d67161a8a78ce36a881fa63b766a9",
90
+ "version": "v5.0.0"
91
+ },
92
+ "actions/setup-dotnet": {
93
+ "name": "actions/setup-dotnet",
94
+ "sha": "3e891b0cb619bf60e2c25674b222b8940e2c1c25",
95
+ "version": "v4.1.0"
96
+ },
97
+ "actions/setup-java": {
98
+ "name": "actions/setup-java",
99
+ "sha": "8df1039502a15bceb9433410b1a100fbe190c53b",
100
+ "version": "v4.5.0"
101
+ },
102
+ "actions/setup-node": {
103
+ "name": "actions/setup-node",
104
+ "sha": "39370e3970a6d050c480ffad4ff0ed4d3fdee5af",
105
+ "version": "v4.1.0"
106
+ },
107
+ "actions/setup-python": {
108
+ "name": "actions/setup-python",
109
+ "sha": "0b93645e9fea7318ecaed2b359559ac225c90a2b",
110
+ "version": "v5.3.0"
111
+ },
112
+ "actions/stale": {
113
+ "name": "actions/stale",
114
+ "sha": "28ca1036281a5e5922ead5184a1bbf96e5fc984e",
115
+ "version": "v9.0.0"
116
+ },
117
+ "actions/upload-artifact": {
118
+ "name": "actions/upload-artifact",
119
+ "sha": "b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882",
120
+ "version": "v4.4.3"
121
+ },
122
+ "actions/upload-pages-artifact": {
123
+ "name": "actions/upload-pages-artifact",
124
+ "sha": "56afc609e74202658d3ffba0e8f6dda462b719fa",
125
+ "version": "v3.0.1"
126
+ },
127
+ "anchore/scan-action": {
128
+ "name": "anchore/scan-action",
129
+ "sha": "869c549e657a088dc0441b08ce4fc0ecdac2bb65",
130
+ "version": "v5.3.0"
131
+ },
132
+ "android-actions/setup-android": {
133
+ "name": "android-actions/setup-android",
134
+ "sha": "9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407",
135
+ "version": "v3.2.2"
136
+ },
137
+ "andymckay/labeler": {
138
+ "name": "andymckay/labeler",
139
+ "sha": "e6c4322d0397f3240f0e7e30a33b5c5df2d39e90",
140
+ "version": "1.0.4"
141
+ },
142
+ "azure/webapps-deploy": {
143
+ "name": "azure/webapps-deploy",
144
+ "sha": "de617f46172a906d0617bb0e50d81e9e3aec24c8",
145
+ "version": "v3.0.1"
146
+ },
147
+ "bitwarden/sm-action": {
148
+ "name": "bitwarden/sm-action",
149
+ "sha": "92d1d6a4f26a89a8191c83ab531a53544578f182",
150
+ "version": "v2.0.0"
151
+ },
152
+ "checkmarx/ast-github-action": {
153
+ "name": "checkmarx/ast-github-action",
154
+ "sha": "b74e8d514feae4ad5ad2b43e72590935bd2daf5f",
155
+ "version": "2.0.39"
156
+ },
157
+ "chrnorm/deployment-action": {
158
+ "name": "chrnorm/deployment-action",
159
+ "sha": "55729fcebec3d284f60f5bcabbd8376437d696b1",
160
+ "version": "v2.0.7"
161
+ },
162
+ "chrnorm/deployment-status": {
163
+ "name": "chrnorm/deployment-status",
164
+ "sha": "9a72af4586197112e0491ea843682b5dc280d806",
165
+ "version": "v2.0.3"
166
+ },
167
+ "chromaui/action": {
168
+ "name": "chromaui/action",
169
+ "sha": "e90c5a5e3bc2eb3b8e110d606f56a0f44fa47700",
170
+ "version": "v1"
171
+ },
172
+ "cloudflare/pages-action": {
173
+ "name": "cloudflare/pages-action",
174
+ "sha": "f0a1cd58cd66095dee69bfa18fa5efd1dde93bca",
175
+ "version": "v1.5.0"
176
+ },
177
+ "codecov/codecov-action": {
178
+ "name": "codecov/codecov-action",
179
+ "sha": "7f8b4b4bde536c465e797be725718b88c5d95e0e",
180
+ "version": "v5.1.1"
181
+ },
182
+ "codecov/test-results-action": {
183
+ "name": "codecov/test-results-action",
184
+ "sha": "9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820",
185
+ "version": "v1.0.1"
186
+ },
187
+ "convictional/trigger-workflow-and-wait": {
188
+ "name": "convictional/trigger-workflow-and-wait",
189
+ "sha": "f69fa9eedd3c62a599220f4d5745230e237904be",
190
+ "version": "v1.6.5"
191
+ },
192
+ "crazy-max/ghaction-import-gpg": {
193
+ "name": "crazy-max/ghaction-import-gpg",
194
+ "sha": "cb9bde2e2525e640591a934b1fd28eef1dcaf5e5",
195
+ "version": "v6.2.0"
196
+ },
197
+ "crowdin/github-action": {
198
+ "name": "crowdin/github-action",
199
+ "sha": "a9ffb7d5ac46eca1bb1f06656bf888b39462f161",
200
+ "version": "v2.4.0"
201
+ },
202
+ "dawidd6/action-download-artifact": {
203
+ "name": "dawidd6/action-download-artifact",
204
+ "sha": "80620a5d27ce0ae443b965134db88467fc607b43",
205
+ "version": "v7"
206
+ },
207
+ "dawidd6/action-homebrew-bump-formula": {
208
+ "name": "dawidd6/action-homebrew-bump-formula",
209
+ "sha": "8d494330bce4434918392df134ad3db1167904db",
210
+ "version": "v4"
211
+ },
212
+ "digitalocean/action-doctl": {
213
+ "name": "digitalocean/action-doctl",
214
+ "sha": "135ac0aa0eed4437d547c6f12c364d3006b42824",
215
+ "version": "v2.5.1"
216
+ },
217
+ "docker/build-push-action": {
218
+ "name": "docker/build-push-action",
219
+ "sha": "48aba3b46d1b1fec4febb7c5d0c644b249a11355",
220
+ "version": "v6.10.0"
221
+ },
222
+ "docker/setup-buildx-action": {
223
+ "name": "docker/setup-buildx-action",
224
+ "sha": "c47758b77c9736f4b2ef4073d4d51994fabfe349",
225
+ "version": "v3.7.1"
226
+ },
227
+ "docker/setup-qemu-action": {
228
+ "name": "docker/setup-qemu-action",
229
+ "sha": "49b3bc8e6bdd4a60e6116a5414239cba5943d3cf",
230
+ "version": "v3.2.0"
231
+ },
232
+ "dorny/test-reporter": {
233
+ "name": "dorny/test-reporter",
234
+ "sha": "31a54ee7ebcacc03a09ea97a7e5465a47b84aea5",
235
+ "version": "v1.9.1"
236
+ },
237
+ "dtolnay/rust-toolchain": {
238
+ "name": "dtolnay/rust-toolchain",
239
+ "sha": "1482605bfc5719782e1267fd0c0cc350fe7646b8",
240
+ "version": "v1"
241
+ },
242
+ "futureware-tech/simulator-action": {
243
+ "name": "futureware-tech/simulator-action",
244
+ "sha": "dab10d813144ef59b48d401cd95da151222ef8cd",
245
+ "version": "v4"
246
+ },
247
+ "github/codeql-action": {
248
+ "name": "github/codeql-action",
249
+ "sha": "3096afedf9873361b2b2f65e1445b13272c83eb8",
250
+ "version": "codeql-bundle-v2.20.0"
251
+ },
252
+ "gradle/actions": {
253
+ "name": "gradle/actions",
254
+ "sha": "cc4fc85e6b35bafd578d5ffbc76a5518407e1af0",
255
+ "version": "v4.2.1"
256
+ },
257
+ "hashicorp/setup-packer": {
258
+ "name": "hashicorp/setup-packer",
259
+ "sha": "1aa358be5cf73883762b302a3a03abd66e75b232",
260
+ "version": "v3.1.0"
261
+ },
262
+ "helm/chart-releaser-action": {
263
+ "name": "helm/chart-releaser-action",
264
+ "sha": "a917fd15b20e8b64b94d9158ad54cd6345335584",
265
+ "version": "v1.6.0"
266
+ },
267
+ "helm/chart-testing-action": {
268
+ "name": "helm/chart-testing-action",
269
+ "sha": "e6669bcd63d7cb57cb4380c33043eebe5d111992",
270
+ "version": "v2.6.1"
271
+ },
272
+ "helm/kind-action": {
273
+ "name": "helm/kind-action",
274
+ "sha": "0025e74a8c7512023d06dc019c617aa3cf561fde",
275
+ "version": "v1.10.0"
276
+ },
277
+ "launchdarkly/find-code-references-in-pull-request": {
278
+ "name": "launchdarkly/find-code-references-in-pull-request",
279
+ "sha": "d008aa4f321d8cd35314d9cb095388dcfde84439",
280
+ "version": "v2.0.0"
281
+ },
282
+ "macauley/action-homebrew-bump-cask": {
283
+ "name": "macauley/action-homebrew-bump-cask",
284
+ "sha": "445c42390d790569d938f9068d01af39ca030feb",
285
+ "version": "v1.0.0"
286
+ },
287
+ "maxim-lobanov/setup-xcode": {
288
+ "name": "maxim-lobanov/setup-xcode",
289
+ "sha": "60606e260d2fc5762a71e64e74b2174e8ea3c8bd",
290
+ "version": "v1.6.0"
291
+ },
292
+ "microsoft/setup-msbuild": {
293
+ "name": "microsoft/setup-msbuild",
294
+ "sha": "6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce",
295
+ "version": "v2"
296
+ },
297
+ "ncipollo/release-action": {
298
+ "name": "ncipollo/release-action",
299
+ "sha": "2c591bcc8ecdcd2db72b97d6147f871fcd833ba5",
300
+ "version": "v1.14.0"
301
+ },
302
+ "peter-evans/close-issue": {
303
+ "name": "peter-evans/close-issue",
304
+ "sha": "276d7966e389d888f011539a86c8920025ea0626",
305
+ "version": "v3.0.1"
306
+ },
307
+ "reactivecircus/android-emulator-runner": {
308
+ "name": "reactivecircus/android-emulator-runner",
309
+ "sha": "62dbb605bba737720e10b196cb4220d374026a6d",
310
+ "version": "v2.33.0"
311
+ },
312
+ "ruby/setup-ruby": {
313
+ "name": "ruby/setup-ruby",
314
+ "sha": "2a18b06812b0e15bb916e1df298d3e740422c47e",
315
+ "version": "v1.203.0"
316
+ },
317
+ "samuelmeuli/action-snapcraft": {
318
+ "name": "samuelmeuli/action-snapcraft",
319
+ "sha": "d33c176a9b784876d966f80fb1b461808edc0641",
320
+ "version": "v2.1.1"
321
+ },
322
+ "slackapi/slack-github-action": {
323
+ "name": "slackapi/slack-github-action",
324
+ "sha": "485a9d42d3a73031f12ec201c457e2162c45d02d",
325
+ "version": "v2.0.0"
326
+ },
327
+ "sigstore/cosign-installer": {
328
+ "name": "sigstore/cosign-installer",
329
+ "sha": "dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da",
330
+ "version": "v3.7.0"
331
+ },
332
+ "snapcore/action-build": {
333
+ "name": "snapcore/action-build",
334
+ "sha": "3bdaa03e1ba6bf59a65f84a751d943d549a54e79",
335
+ "version": "v1.3.0"
336
+ },
337
+ "softprops/action-gh-release": {
338
+ "name": "softprops/action-gh-release",
339
+ "sha": "7b4da11513bf3f43f9999e90eabced41ab8bb048",
340
+ "version": "v2.2.0"
341
+ },
342
+ "sonarsource/sonarcloud-github-action": {
343
+ "name": "sonarsource/sonarcloud-github-action",
344
+ "sha": "02ef91109b2d589e757aefcfb2854c2783fd7b19",
345
+ "version": "v4.0.0"
346
+ },
347
+ "sonarsource/sonarqube-scan-action": {
348
+ "name": "sonarsource/sonarqube-scan-action",
349
+ "sha": "bfd4e558cda28cda6b5defafb9232d191be8c203",
350
+ "version": "v4.2.1"
351
+ },
352
+ "stackrox/kube-linter-action": {
353
+ "name": "stackrox/kube-linter-action",
354
+ "sha": "5792edc6a03735d592b13c08201711327a935735",
355
+ "version": "v1.0.5"
356
+ },
357
+ "tj-actions/changed-files": {
358
+ "name": "tj-actions/changed-files",
359
+ "sha": "bab30c2299617f6615ec02a68b9a40d10bd21366",
360
+ "version": "v45.0.5"
361
+ },
362
+ "tyrrrz/action-http-request": {
363
+ "name": "tyrrrz/action-http-request",
364
+ "sha": "64c70c67f5ebc54d4c7ea09cbe3553322778afd5",
365
+ "version": "1.1.2"
366
+ },
367
+ "yogevbd/enforce-label-action": {
368
+ "name": "yogevbd/enforce-label-action",
369
+ "sha": "a3c219da6b8fa73f6ba62b68ff09c469b3a1c024",
370
+ "version": "2.2.2"
371
+ }
372
+ }
@@ -58,7 +58,13 @@ class RuleJobEnvironmentPrefix(Rule):
58
58
  incorrectly named environment variables.
59
59
  """
60
60
  correct = True
61
- allowed_envs = {"NODE_OPTION", "NUGET_PACKAGES", "MINT_PATH", "MINT_LINK_PATH"}
61
+ allowed_envs = {
62
+ "NODE_OPTIONS",
63
+ "NUGET_PACKAGES",
64
+ "MINT_PATH",
65
+ "MINT_LINK_PATH",
66
+ "HUSKY",
67
+ }
62
68
 
63
69
  if obj.env:
64
70
  offending_keys = []
@@ -70,4 +76,4 @@ class RuleJobEnvironmentPrefix(Rule):
70
76
  if correct:
71
77
  return True, ""
72
78
 
73
- return False, f"{self.message} ({' ,'.join(offending_keys)})"
79
+ return False, f"{self.message} ({', '.join(offending_keys)})"
@@ -1,5 +1,6 @@
1
1
  """A Rule to enforce all 'name' values start with a capital letter."""
2
2
 
3
+ import re
3
4
  from typing import Optional, Tuple, Union
4
5
 
5
6
  from ..models.job import Job
@@ -56,7 +57,7 @@ class RuleNameCapitalized(Rule):
56
57
  if obj.name[0] != "_":
57
58
  return obj.name[0].isupper(), self.message
58
59
  else:
59
- if obj.name:
60
+ if obj.name and not re.match(r"^\s*\${{\s*matrix\..*}}.*", obj.name):
60
61
  return obj.name[0].isupper(), self.message
61
62
 
62
63
  return True, "" # Force passing