|
|
|
|
@ -5,73 +5,86 @@ import yaml
@@ -5,73 +5,86 @@ import yaml
|
|
|
|
|
|
|
|
|
|
def lint(filename): |
|
|
|
|
|
|
|
|
|
print("#", filename) |
|
|
|
|
findings = [] |
|
|
|
|
|
|
|
|
|
with open(filename) as file: |
|
|
|
|
workflow = yaml.load(file, Loader=yaml.FullLoader) |
|
|
|
|
|
|
|
|
|
# Check for 'name' key for the workflow. |
|
|
|
|
if 'name' not in workflow: |
|
|
|
|
print("- Name key missing for workflow.") |
|
|
|
|
if "name" not in workflow: |
|
|
|
|
findings.append("- Name key missing for workflow.") |
|
|
|
|
# Check for 'name' value to be capitalized in workflow. |
|
|
|
|
elif not workflow['name'][0].isupper(): |
|
|
|
|
print( |
|
|
|
|
"- Name value for workflow is not capitalized. [" + workflow['name'] + "]") |
|
|
|
|
elif not workflow["name"][0].isupper(): |
|
|
|
|
findings.append( |
|
|
|
|
f"- Name value for workflow is not capitalized. [{workflow['name']}]" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# Loop through jobs in workflow. |
|
|
|
|
if 'jobs' in workflow: |
|
|
|
|
jobs = workflow['jobs'] |
|
|
|
|
if "jobs" in workflow: |
|
|
|
|
jobs = workflow["jobs"] |
|
|
|
|
for job_key in jobs: |
|
|
|
|
job = jobs[job_key] |
|
|
|
|
|
|
|
|
|
# Check for 'name' key for job. |
|
|
|
|
if 'name' not in job: |
|
|
|
|
print("- Name key missing for job key '" + job_key + "'.") |
|
|
|
|
if "name" not in job: |
|
|
|
|
findings.append(f"- Name key missing for job key '{job_key}'.") |
|
|
|
|
# Check for 'name' value to be capitallized in job. |
|
|
|
|
elif not job['name'][0].isupper(): |
|
|
|
|
print("- Name value of job key '" + |
|
|
|
|
job_key + "' is not capitalized. [" + job['name'] + "]") |
|
|
|
|
elif not job["name"][0].isupper(): |
|
|
|
|
findings.append( |
|
|
|
|
f"- Name value of job key '{job_key}' is not capitalized. [{job['name']}]" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# If the job has environment variables defined, then make sure they start with an underscore. |
|
|
|
|
if 'env' in job: |
|
|
|
|
for k in job['env'].keys(): |
|
|
|
|
if k[0] != '_': |
|
|
|
|
print("- Environment variable '" + k + "' of job key '" + |
|
|
|
|
job_key + "' does not start with an underscore.") |
|
|
|
|
if "env" in job: |
|
|
|
|
for k in job["env"].keys(): |
|
|
|
|
if k[0] != "_": |
|
|
|
|
findings.append( |
|
|
|
|
f"- Environment variable '{k}' of job key '{job_key}' does not start with an underscore." |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# Loop through steps in job. |
|
|
|
|
steps = job['steps'] |
|
|
|
|
steps = job["steps"] |
|
|
|
|
for i, step in enumerate(steps, start=1): |
|
|
|
|
# Check for 'name' key for step. |
|
|
|
|
if 'name' not in step: |
|
|
|
|
print("- Name key missing for step " + str(i) + |
|
|
|
|
" of job key '" + job_key + "'.") |
|
|
|
|
if "name" not in step: |
|
|
|
|
findings.append( |
|
|
|
|
f"- Name key missing for step {str(i)} of job key '{job_key}'." |
|
|
|
|
) |
|
|
|
|
# Check for 'name' value to be capitalized in step. |
|
|
|
|
elif not step['name'][0].isupper(): |
|
|
|
|
print("- Name value in step " + str(i) + |
|
|
|
|
" of job key '" + job_key + "' is not capitalized. [" + step['name'] + "]") |
|
|
|
|
elif not step["name"][0].isupper(): |
|
|
|
|
findings.append( |
|
|
|
|
f"- Name value in step {str(i)} of job key '{job_key}' is not capitalized. [{step['name']}]" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# If the step has a 'uses' key, check value hash. |
|
|
|
|
if 'uses' in step: |
|
|
|
|
if "uses" in step: |
|
|
|
|
try: |
|
|
|
|
_, hash = step['uses'].split('@') |
|
|
|
|
_, hash = step["uses"].split("@") |
|
|
|
|
|
|
|
|
|
# Check to make sure SHA1 hash is 40 characters. |
|
|
|
|
if len(hash) != 40: |
|
|
|
|
print("- Step " + str(i) + " of job key '" + job_key + |
|
|
|
|
"' does not have a valid action hash. (not 40 characters)") |
|
|
|
|
findings.append( |
|
|
|
|
f"- Step {str(i)} of job key '{job_key}' does not have a valid action hash. (not 40 characters)" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# Attempts to convert the hash to a integer |
|
|
|
|
# which will succeed if all characters are hexadecimal |
|
|
|
|
try: |
|
|
|
|
int(hash, 16) |
|
|
|
|
except ValueError: |
|
|
|
|
print("- Step " + str(i) + " of job key '" + job_key + |
|
|
|
|
"' does not have a valid action hash. (not all hexadecimal characters)") |
|
|
|
|
findings.append( |
|
|
|
|
f"- Step {str(i)} of job key '{job_key}' does not have a valid action hash. (not all hexadecimal characters)" |
|
|
|
|
) |
|
|
|
|
except: |
|
|
|
|
print("- Step " + str(i) + " of job key '" + job_key + |
|
|
|
|
"' does not have a valid action hash. (missing '@' character)") |
|
|
|
|
|
|
|
|
|
print() |
|
|
|
|
findings.append( |
|
|
|
|
f"- Step {str(i)} of job key '{job_key}' does not have a valid action hash. (missing '@' character)" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if len(findings) > 0: |
|
|
|
|
print("#", filename) |
|
|
|
|
for finding in findings: |
|
|
|
|
print(finding) |
|
|
|
|
print() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main(): |
|
|
|
|
|