Skip to content

Commit

Permalink
Build out the majority of the rules
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-flinn committed Jan 3, 2024
1 parent 42ad11a commit 34a4319
Show file tree
Hide file tree
Showing 33 changed files with 919 additions and 161 deletions.
2 changes: 1 addition & 1 deletion lint-workflow/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions lint-workflow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@ black .

- [x] assert name exists
- [x] assert name is capitalized
- [ ] assert runs-on is pinned
- [ ] assert any environment variables start with "_"
- [x] assert runs-on is pinned
- [x] assert any environment variables start with "_"

#### shared steps
- [x] assert name exists
- [x] assert name is capitilized

#### uses steps
- [ ] assert valid hash format - correct length
- [ ] assert valid hash format - cast to hexidecimal
- [ ] assert valid action repo path format
- [ ] assert action exists in GitHub
- [ ] warn out of date Action
- [ ] warn using an unapproved Action
- [x] assert valid hash format - correct length
- [x] assert valid hash format - cast to hexidecimal
- [x] warn using an unapproved Action
- [x] warn out of date Action
- [ ] (DEPRECATED) assert action exists in GitHub (deprecated in favor of the approved list of actions)
- [ ] (DEPRECATED) assert valid action repo path format (deprecated in favor fo the approved list of actions)

#### run steps
- [ ] assert correct format for single line run
Expand Down
54 changes: 54 additions & 0 deletions lint-workflow/actions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[
{"name": "act10ns/slack", "version": "", "sha": ""},
{"name": "actions/cache", "version": "", "sha": ""},
{"name": "actions/checkout", "version": "", "sha": ""},
{"name": "actions/delete-package-versions", "version": "", "sha": ""},
{"name": "actions/download-artifact", "version": "", "sha": ""},
{"name": "actions/github-script", "version": "", "sha": ""},
{"name": "actions/labeler", "version": "", "sha": ""},
{"name": "actions/setup-dotnet", "version": "", "sha": ""},
{"name": "actions/setup-java", "version": "", "sha": ""},
{"name": "actions/setup-node", "version": "", "sha": ""},
{"name": "actions/setup-python", "version": "", "sha": ""},
{"name": "actions/stale", "version": "", "sha": ""},
{"name": "actions/upload-artifact", "version": "", "sha": ""},
{"name": "android-actions/setup-android", "version": "", "sha": ""},
{"name": "Asana/create-app-attachment-github-action", "version": "", "sha": ""},
{"name": "Azure/functions-action", "version": "", "sha": ""},
{"name": "Azure/get-keyvault-secrets", "version": "", "sha": ""},
{"name": "Azure/login", "version": "", "sha": ""},
{"name": "azure/webapps-deploy", "version": "", "sha": ""},
{"name": "bitwarden/sm-action", "version": "", "sha": ""},
{"name": "checkmarx/ast-github-action", "version": "", "sha": ""},
{"name": "chrnorm/deployment-action", "version": "", "sha": ""},
{"name": "chrnorm/deployment-status", "version": "", "sha": ""},
{"name": "chromaui/action", "version": "", "sha": ""},
{"name": "cloudflare/pages-action", "version": "", "sha": ""},
{"name": "convictional/trigger-workflow-and-wait", "version": "", "sha": ""},
{"name": "crazy-max/ghaction-import-gpg", "version": "", "sha": ""},
{"name": "crowdin/github-action", "version": "", "sha": ""},
{"name": "dawidd6/action-download-artifact", "version": "", "sha": ""},
{"name": "dawidd6/action-homebrew-bump-formula", "version": "", "sha": ""},
{"name": "digitalocean/action-doctl", "version": "", "sha": ""},
{"name": "docker/build-push-action", "version": "", "sha": ""},
{"name": "docker/setup-buildx-action", "version": "", "sha": ""},
{"name": "docker/setup-qemu-action", "version": "", "sha": ""},
{"name": "dorny/test-reporter", "version": "", "sha": ""},
{"name": "dtolnay/rust-toolchain", "version": "", "sha": ""},
{"name": "futureware-tech/simulator-action", "version": "", "sha": ""},
{"name": "hashicorp/setup-packer", "version": "", "sha": ""},
{"name": "macauley/action-homebrew-bump-cask", "version": "", "sha": ""},
{"name": "microsoft/setup-msbuild", "version": "", "sha": ""},
{"name": "ncipollo/release-action", "version": "", "sha": ""},
{"name": "peter-evans/close-issue", "version": "", "sha": ""},
{"name": "ruby/setup-ruby", "version": "", "sha": ""},
{"name": "samuelmeuli/action-snapcraft", "version": "", "sha": ""},
{"name": "snapcore/action-build", "version": "", "sha": ""},
{"name": "sonarsource/sonarcloud-github-action", "version": "", "sha": ""},
{"name": "stackrox/kube-linter-action", "version": "", "sha": ""},
{"name": "Swatinem/rust-cache", "version": "", "sha": ""},
{"name": "SwiftDocOrg/github-wiki-publish-action", "version": "", "sha": ""},
{"name": "SwiftDocOrg/swift-doc", "version": "", "sha": ""},
{"name": "tj-actions/changed-files", "version": "", "sha": ""},
{"name": "yogevbd/enforce-label-action", "version": "", "sha": ""}
]
25 changes: 17 additions & 8 deletions lint-workflow/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import urllib3 as urllib
import logging

#from src.rules import workflow_rules, job_rules, step_rules, uses_step_rules, run_step_rules
from settings import enabled_rules
# from src.rules import workflow_rules, job_rules, step_rules, uses_step_rules, run_step_rules
import settings
from src.load import WorkflowBuilder, Rules
from src.utils import LintFinding
from src.utils import LintFinding, Settings, SettingsError


PROBLEM_LEVELS = {
Expand All @@ -19,10 +19,22 @@

memoized_action_update_urls = {}

try:
lint_settings = Settings(
enabled_rules=settings.enabled_rules,
approved_actions=settings.approved_actions
)
except:
raise SettingsError(
(
"Required settings: enabled_rules, approved_actions\n"
"Please see documentation for more information"
)
)

lint_rules = Rules(enabled_rules, verbose=True)
lint_rules = Rules(settings=lint_settings, verbose=True)

#print(lint_rules.workflow)
# print(lint_rules.workflow)


class Colors:
Expand Down Expand Up @@ -240,7 +252,6 @@ def lint(filename):


def _old_lint(filename):

findings = []
max_error_level = 0

Expand Down Expand Up @@ -332,7 +343,6 @@ def _old_lint(filename):

# If the step has a 'uses' key, check value hash.
try:

# Check to make sure SHA1 hash is 40 characters.
if len(hash) != 40:
findings.append(
Expand Down Expand Up @@ -420,7 +430,6 @@ def _old_lint(filename):


def main(input_args=None):

# Pull the arguments from the command line
if not input_args:
input_args = sys.argv[1:]
Expand Down
66 changes: 26 additions & 40 deletions lint-workflow/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Colors:

class LintFinding:
"""Represents a linting problem."""

description: str = "<no description>"
level: str = None

Expand Down Expand Up @@ -95,7 +96,7 @@ def action_repo_exists(action_id):

path, *hash = action_id.split("@")

if "bitwarden/gh-actions" in path:
if "bitwarden" in path:
path_list = path.split("/", 2)
url = f"https://api.github.com/repos/{path_list[0]}/{path_list[1]}"
response = get_github_api_response(url, action_id)
Expand Down Expand Up @@ -150,7 +151,7 @@ def get_action_update(action_id):
if path in memoized_action_update_urls:
return memoized_action_update_urls[path]
else:
if "bitwarden/gh-actions" in path:
if "bitwarden" in path:
path_list = path.split("/", 2)
url = f"https://api.github.com/repos/{path_list[0]}/{path_list[1]}/commits?path={path_list[2]}"
response = get_github_api_response(url, action_id)
Expand Down Expand Up @@ -200,11 +201,6 @@ def get_action_update(action_id):


def lint(filename):

supported_actions = {"act10ns/slack", "actions/cache", "actions/checkout", "actions/delete-package-versions", "actions/download-artifact", "actions/github-script", "actions/labeler", "actions/setup-dotnet", "actions/setup-java", "actions/setup-node", "actions/setup-python", "actions/stale", "actions/upload-artifact", "android-actions/setup-android", "Asana/create-app-attachment-github-action", "Azure/functions-action", "Azure/get-keyvault-secrets", "Azure/login", "azure/webapps-deploy", "bitwarden/sm-action", "checkmarx/ast-github-action", "chrnorm/deployment-action", "chrnorm/deployment-status", "chromaui/action", "cloudflare/pages-action", "convictional/trigger-workflow-and-wait", "crazy-max/ghaction-import-gpg", "crowdin/github-action", "dawidd6/action-download-artifact", "dawidd6/action-homebrew-bump-formula", "digitalocean/action-doctl", "docker/build-push-action", "docker/setup-buildx-action", "docker/setup-qemu-action", "dorny/test-reporter", "dtolnay/rust-toolchain", "futureware-tech/simulator-action", "hashicorp/setup-packer", "macauley/action-homebrew-bump-cask", "microsoft/setup-msbuild", "ncipollo/release-action", "peter-evans/close-issue", "ruby/setup-ruby", "samuelmeuli/action-snapcraft", "snapcore/action-build", "sonarsource/sonarcloud-github-action", "stackrox/kube-linter-action", "Swatinem/rust-cache", "SwiftDocOrg/github-wiki-publish-action", "SwiftDocOrg/swift-doc", "tj-actions/changed-files", "yogevbd/enforce-label-action"}



findings = []
max_error_level = 0

Expand Down Expand Up @@ -294,49 +290,40 @@ def lint(filename):
logging.info("Skipping local action in workflow.")
break

# If the step has a 'uses' key, check if actions are in supported actions list and also value hash, except bitwarden actions.
if "bitwarden/gh-actions" not in path:
try:
# Check if actions are in supported actions list.
if path not in supported_actions:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' uses an unsupported action: {path}.",
"warning",
)
)
# Check to make sure SHA1 hash is 40 characters.
if len(hash) != 40:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' does not have a valid action hash. (not 40 characters)",
"error",
)
# If the step has a 'uses' key, check value hash.
try:
# Check to make sure SHA1 hash is 40 characters.
if len(hash) != 40:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' does not have a valid action hash. (not 40 characters)",
"error",
)
)

# Attempts to convert the hash to a integer
# which will succeed if all characters are hexadecimal
try:
int(hash, 16)
except ValueError:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' does not have a valid action hash. (not all hexadecimal characters)",
"error",
)
)
except:
# Attempts to convert the hash to a integer
# which will succeed if all characters are hexadecimal
try:
int(hash, 16)
except ValueError:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' does not have a valid action hash. (missing '@' character)",
f"Step {str(i)} of job key '{job_key}' does not have a valid action hash. (not all hexadecimal characters)",
"error",
)
)
except:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' does not have a valid action hash. (missing '@' character)",
"error",
)
)

# If the step has a 'uses' key, check path for external workflow
path_list = path.split("/", 2)

if "bitwarden/gh-actions" in path and len(path_list) < 3:
if "bitwarden" in path and len(path_list) < 3:
findings.append(
LintFinding(
f"Step {str(i)} of job key '{job_key}' does not have a valid action path. (missing name of the repository or workflow)",
Expand Down Expand Up @@ -392,7 +379,6 @@ def lint(filename):


def main(input_args=None):

# Pull the arguments from the command line
if not input_args:
input_args = sys.argv[1:]
Expand Down
63 changes: 61 additions & 2 deletions lint-workflow/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,63 @@
enabled_rules = [
'src.rules.name_exists.RuleNameExists',
'src.rules.name_capitalized.RuleNameCapitalized'
"src.rules.name_exists.RuleNameExists",
"src.rules.name_capitalized.RuleNameCapitalized",
"src.rules.pinned_job_runner.RuleJobRunnerVersionPinned",
"src.rules.job_environment_prefix.RuleJobEnvironmentPrefix",
"src.rules.step_hex.RuleStepUsesPinned",
]


approved_actions = [
"act10ns/slack",
"actions/cache",
"actions/checkout",
"actions/delete-package-versions",
"actions/download-artifact",
"actions/github-script",
"actions/labeler",
"actions/setup-dotnet",
"actions/setup-java",
"actions/setup-node",
"actions/setup-python",
"actions/stale",
"actions/upload-artifact",
"android-actions/setup-android",
"Asana/create-app-attachment-github-action",
"Azure/functions-action",
"Azure/get-keyvault-secrets",
"Azure/login",
"azure/webapps-deploy",
"bitwarden/sm-action",
"checkmarx/ast-github-action",
"chrnorm/deployment-action",
"chrnorm/deployment-status",
"chromaui/action",
"cloudflare/pages-action",
"convictional/trigger-workflow-and-wait",
"crazy-max/ghaction-import-gpg",
"crowdin/github-action",
"dawidd6/action-download-artifact",
"dawidd6/action-homebrew-bump-formula",
"digitalocean/action-doctl",
"docker/build-push-action",
"docker/setup-buildx-action",
"docker/setup-qemu-action",
"dorny/test-reporter",
"dtolnay/rust-toolchain",
"futureware-tech/simulator-action",
"hashicorp/setup-packer",
"macauley/action-homebrew-bump-cask",
"microsoft/setup-msbuild",
"ncipollo/release-action",
"peter-evans/close-issue",
"ruby/setup-ruby",
"samuelmeuli/action-snapcraft",
"snapcore/action-build",
"sonarsource/sonarcloud-github-action",
"stackrox/kube-linter-action",
"Swatinem/rust-cache",
"SwiftDocOrg/github-wiki-publish-action",
"SwiftDocOrg/swift-doc",
"tj-actions/changed-files",
"yogevbd/enforce-label-action",
]
Loading

0 comments on commit 34a4319

Please sign in to comment.