@ -1,6 +1,47 @@
@@ -1,6 +1,47 @@
import argparse
import os
import yaml
import json
import urllib3 as urllib
def get_action_update ( action_id ) :
"""
Takes and action id ( bitwarden / gh - actions / version - bump @ 03 ad9a873c39cdc95dd8d77dbbda67f84db43945 )
and checks the action repo for the newest version .
If there is a new version , return the url to the updated version .
"""
path , * hash = action_id . split ( " @ " )
http = urllib . PoolManager ( )
headers = { }
if os . getenv ( " GITHUB_TOKEN " , None ) :
headers [ " Authorization " ] = f " Token { os . environ [ ' GITHUB_TOKEN ' ] } "
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 ] } "
r = http . request ( " GET " , url , headers = headers )
sha = json . loads ( r . data ) [ 0 ] [ " sha " ]
if sha not in hash :
return f " https://github.com/ { path_list [ 0 ] } / { path_list [ 1 ] } /commit/ { sha } "
else :
r = http . request (
" GET " ,
f " https://api.github.com/repos/ { path } /releases/latest " ,
headers = headers ,
)
tag_name = json . loads ( r . data ) [ " tag_name " ]
r = http . request (
" GET " ,
f " https://api.github.com/repos/ { path } /git/ref/tags/ { tag_name } " ,
headers = headers ,
)
sha = json . loads ( r . data ) [ " object " ] [ " sha " ]
if sha not in hash :
return f " https://github.com/ { path } /commit/ { sha } "
def lint ( filename ) :
@ -63,8 +104,9 @@ def lint(filename):
@@ -63,8 +104,9 @@ def lint(filename):
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 the step has a 'uses' key, check value hash.
try :
_ , hash = step [ " uses " ] . split ( " @ " )
@ -86,9 +128,17 @@ def lint(filename):
@@ -86,9 +128,17 @@ def lint(filename):
findings . append (
f " - Step { str ( i ) } of job key ' { job_key } ' does not have a valid action hash. (missing ' @ ' character) "
)
# If the step has a 'uses' key, check the action id repo for an update.
update_available = get_action_update ( step [ " uses " ] )
if update_available :
findings . append (
f " - Step { str ( i ) } of job key ' { job_key } ' uses an outdated action, consider updating it ' { update_available } ' . "
)
# If the step has a 'run' key and only has one command, check if it's a single line.
if " run " in step :
if step [ " run " ] . count ( ' \n ' ) == 1 :
if step [ " run " ] . count ( " \n " ) == 1 :
findings . append (
f " - Run in step { str ( i ) } of job key ' { job_key } ' should be a single line. "
)