1414
1515ActionVersion = namedtuple ('ActionVersion' , ['name' , 'current' , 'latest' ])
1616
17+ FLAG_COMPARE_EXACT_VERSION = False
18+
1719
1820class GithubActionsTools (object ):
1921 workflows : dict [str , dict [str , Workflow ]] = dict () # repo_name -> [path -> workflow]
@@ -22,12 +24,34 @@ class GithubActionsTools(object):
2224 def __init__ (self , github_token : str ):
2325 self .client = Github (login_or_token = github_token )
2426
27+ @staticmethod
28+ def compare_versions (v1 : str , v2 : str ) -> int :
29+ """Compare two versions, return 1 if v1 > v2, 0 if v1 == v2, -1 if v1 < v2
30+ """
31+ if v1 .startswith ('v' ):
32+ v1 = v1 [1 :]
33+ if v2 .startswith ('v' ):
34+ v2 = v2 [1 :]
35+ v1 = v1 .split ('.' )
36+ v2 = v2 .split ('.' )
37+ compare_count = max (len (v1 ), len (v2 )) if FLAG_COMPARE_EXACT_VERSION else 1
38+ for i in range (compare_count ):
39+ v1_i = int (v1 [i ]) if i < len (v1 ) else 0
40+ v2_i = int (v2 [i ]) if i < len (v2 ) else 0
41+ if v1_i > v2_i :
42+ return 1
43+ if v1_i < v2_i :
44+ return - 1
45+ return 0
46+
2547 @staticmethod
2648 def is_local_repo (repo_name : str ) -> bool :
27- return os .path .exists (repo_name )
49+ return os .path .exists (repo_name ) and os . path . exists ( os . path . join ( repo_name , '.git' ))
2850
2951 @staticmethod
3052 def list_full_paths (path : str ) -> set [str ]:
53+ if not os .path .exists (path ):
54+ return set ()
3155 return {os .path .join (path , file )
3256 for file in os .listdir (path )
3357 if file .endswith (('.yml' , '.yaml' ))}
@@ -38,6 +62,9 @@ def get_github_workflows(self, repo_name: str) -> Set[str]:
3862 # local
3963 if self .is_local_repo (repo_name ):
4064 return self .list_full_paths (os .path .join (repo_name , '.github' , 'workflows' ))
65+ if repo_name .startswith ('.' ):
66+ click .secho (f'{ repo_name } is not a local repo and does not start with owner/repo' , fg = 'red' , err = True )
67+ exit (1 )
4168 # Remote
4269 repo = self .client .get_repo (repo_name )
4370 self .workflows [repo_name ] = {
@@ -85,7 +112,9 @@ def check_for_updates(self, action_name: str) -> Optional[str]:
85112 repo_name , current_version = action_name .split ('@' )
86113 repo = self .client .get_repo (repo_name )
87114 latest_release = repo .get_latest_release ()
88- return latest_release .tag_name if latest_release .tag_name != current_version else None
115+ if GithubActionsTools .compare_versions (latest_release .tag_name , current_version ):
116+ return latest_release .tag_name
117+ return None
89118
90119 def get_repo_actions_latest (self , repo_name : str ) -> Dict [str , List [ActionVersion ]]:
91120 workflow_paths = self .get_github_workflows (repo_name )
@@ -150,16 +179,21 @@ def _update_workflow_content(
150179
151180@click .group (invoke_without_command = True )
152181@click .option (
153- '-repo' , default = '.' , show_default = True , type = str ,
154- help = 'Repository to analyze, can be a local directory or a {OWNER}/{REPO} format' )
182+ '-- repo' , default = '.' , show_default = True , type = str ,
183+ help = 'Repository to analyze, can be a local directory or a {OWNER}/{REPO} format' , )
155184@click .option (
156185 '--github-token' , default = os .getenv ('GITHUB_TOKEN' ), type = str , show_default = False ,
157186 help = 'GitHub token to use, by default will use GITHUB_TOKEN environment variable' )
187+ @click .option (
188+ '--compare-exact-versions' , is_flag = True , default = False ,
189+ help = "Compare versions using all semantic and not only major versions, e.g., v1 will be upgraded to v1.2.3" , )
158190@click .pass_context
159- def cli (ctx , repo : str , github_token : Optional [str ]):
191+ def cli (ctx , repo : str , github_token : Optional [str ], compare_exact_versions : bool ):
160192 ctx .ensure_object (dict )
193+ global FLAG_COMPARE_EXACT_VERSION
194+ FLAG_COMPARE_EXACT_VERSION = compare_exact_versions
161195 if not github_token :
162- click .secho (GITHUB_ACTION_NOT_PROVIDED_MSG , fg = 'red ' , err = True )
196+ click .secho (GITHUB_ACTION_NOT_PROVIDED_MSG , fg = 'yellow ' , err = True )
163197 ctx .obj ['gh' ] = GithubActionsTools (github_token )
164198 ctx .obj ['repo' ] = repo
165199 if not ctx .invoked_subcommand :
0 commit comments