1111
1212
1313def arg_parse ():
14- """ simple argparser """
15- parser = argparse .ArgumentParser (description = 'gh_workflow_runs_delete.py - delete github action logs and artifacts' )
16- parser .add_argument ('-d' ,'--debug' ,help = 'debug mode' ,action = "store_true" ,default = False )
17- parser .add_argument ('-r' ,'--reponame' ,help = 'repositoryname' ,default = None )
18- parser .add_argument ('-u' ,'--username' ,help = 'username' ,default = None )
19- parser .add_argument ('-t' ,'--token' ,help = 'token' ,default = None )
20- parser .add_argument ('-c' ,'--commits' ,help = 'number of commits to keep' ,default = 1 )
21- parser .add_argument ('--branchlist' ,help = 'list of branches' ,default = False )
22- parser .add_argument ('-a' ,'--delete-all' ,help = 'delete all logs' ,action = "store_true" ,default = False )
14+ """simple argparser"""
15+ parser = argparse .ArgumentParser (
16+ description = "gh_workflow_runs_delete.py - delete github action logs and artifacts"
17+ )
18+ parser .add_argument (
19+ "-d" ,"--debug" ,help = "debug mode" ,action = "store_true" ,default = False
20+ )
21+ parser .add_argument ("-r" ,"--reponame" ,help = "repositoryname" ,default = None )
22+ parser .add_argument ("-u" ,"--username" ,help = "username" ,default = None )
23+ parser .add_argument ("-t" ,"--token" ,help = "token" ,default = None )
24+ parser .add_argument ("-c" ,"--commits" ,help = "number of commits to keep" ,default = 1 )
25+ parser .add_argument ("--branchlist" ,help = "list of branches" ,default = False )
26+ parser .add_argument (
27+ "-a" ,"--delete-all" ,help = "delete all logs" ,action = "store_true" ,default = False
28+ )
2329args = parser .parse_args ()
2430
2531debug = args .debug
@@ -31,104 +37,122 @@ def arg_parse():
3137auth = None
3238delete_all = args .delete_all
3339if not reponame :
34- print (' reponame (-r) is missing' )
40+ print (" reponame (-r) is missing" )
3541sys .exit (0 )
3642if username and token :
3743auth = (username ,token )
3844else :
39- print (' authentication incomplete (either user or token are missing)' )
45+ print (" authentication incomplete (either user or token are missing)" )
4046sys .exit (0 )
4147
4248return (debug ,auth ,reponame ,branchlist ,commit_num ,delete_all )
4349
4450
4551def branchlist_get (debug ,auth ,reponame ):
46- """ get list of branches from github """
47- print_debug (debug ,' branchlist_get()' )
48- branch_list = [' scheduled' ]
49- url = f' https://api.github.com/repos/{ reponame } /branches'
52+ """get list of branches from github"""
53+ print_debug (debug ," branchlist_get()" )
54+ branch_list = [" scheduled" ]
55+ url = f" https://api.github.com/repos/{ reponame } /branches"
5056resp = requests .get (url = url ,auth = auth ,timeout = 20 )
5157for branch in resp .json ():
52- if ' name' in branch :
53- branch_list .append (branch [' name' ])
58+ if " name" in branch :
59+ branch_list .append (branch [" name" ])
5460
5561return branch_list
5662
5763
5864def wfruns_get (debug ,auth ,reponame ):
59- """ get list of runs """
60- print_debug (debug ,' wfruns_get()' )
65+ """get list of runs"""
66+ print_debug (debug ," wfruns_get()" )
6167perpage = 100
62- url = f' https://api.github.com/repos/{ reponame } /actions/runs?per_page={ perpage } '
68+ url = f" https://api.github.com/repos/{ reponame } /actions/runs?per_page={ perpage } "
6369resp = requests .get (url = url ,auth = auth ,timeout = 20 )
6470
6571pagenum = 0
66- if 'total_count' in resp .json ():
67- pagenum = math .ceil (resp .json ()['total_count' ]/ perpage )
68- print_debug (debug ,f'totalcount:{ resp .json ()["total_count" ]} , perpage:{ perpage } , pages:{ pagenum } ' )
72+ if "total_count" in resp .json ():
73+ pagenum = math .ceil (resp .json ()["total_count" ]/ perpage )
74+ print_debug (
75+ debug ,
76+ f'totalcount:{ resp .json ()["total_count" ]} , perpage:{ perpage } , pages:{ pagenum } ' ,
77+ )
6978
7079workflow_list = []
7180if pagenum :
7281for ele in range (1 ,pagenum + 1 ):
73- print_debug (debug ,f' fetching page:{ ele } ' )
74- url = f' https://api.github.com/repos/{ reponame } /actions/runs?per_page={ perpage } &page={ ele } '
82+ print_debug (debug ,f" fetching page:{ ele } " )
83+ url = f" https://api.github.com/repos/{ reponame } /actions/runs?per_page={ perpage } &page={ ele } "
7584resp = requests .get (url = url ,auth = auth ,timeout = 20 )
76- if ' workflow_runs' in resp .json ():
77- workflow_list .extend (resp .json ()[' workflow_runs' ])
85+ if " workflow_runs" in resp .json ():
86+ workflow_list .extend (resp .json ()[" workflow_runs" ])
7887
7988# json_store('ids.json', workflow_list)
8089return workflow_list
8190
8291
8392def wfruns_group (debug ,action_list ):
84- """ group action list by branch """
85- print_debug (debug ,' wfruns_group()' )
86- actions_dic = {' scheduled' : {}}
93+ """group action list by branch"""
94+ print_debug (debug ," wfruns_group()" )
95+ actions_dic = {" scheduled" : {}}
8796for workflow in action_list :
88- if 'head_branch' in workflow and 'head_sha' in workflow and 'head_commit' in workflow and 'id' in workflow :
89- uts = int (calendar .timegm (parse (workflow ['head_commit' ]['timestamp' ]).timetuple ()))
97+ if (
98+ "head_branch" in workflow
99+ and "head_sha" in workflow
100+ and "head_commit" in workflow
101+ and "id" in workflow
102+ ):
103+ uts = int (
104+ calendar .timegm (parse (workflow ["head_commit" ]["timestamp" ]).timetuple ())
105+ )
90106# print(workflow['id'], workflow['head_branch'], workflow['head_sha'], workflow['head_commit']['timestamp'], uts)
91107# add branchname to dictionary
92- if workflow [' head_branch' ]not in actions_dic :
93- actions_dic [workflow [' head_branch' ]]= {}
108+ if workflow [" head_branch" ]not in actions_dic :
109+ actions_dic [workflow [" head_branch" ]]= {}
94110
95- if workflow [' event' ]== ' schedule' :
111+ if workflow [" event" ]== " schedule" :
96112# special handling for scheduled workflows
97- cdate ,_junk = workflow ['created_at' ].split ('T' ,1 )
98- if cdate not in actions_dic ['scheduled' ]:
99- actions_dic ['scheduled' ][cdate ]= {'commit' :workflow ['head_sha' ],'id_list' : []}
100- actions_dic ['scheduled' ][cdate ]['id_list' ].append (workflow ['id' ])
113+ cdate ,_junk = workflow ["created_at" ].split ("T" ,1 )
114+ if cdate not in actions_dic ["scheduled" ]:
115+ actions_dic ["scheduled" ][cdate ]= {
116+ "commit" :workflow ["head_sha" ],
117+ "id_list" : [],
118+ }
119+ actions_dic ["scheduled" ][cdate ]["id_list" ].append (workflow ["id" ])
101120else :
102121# add uts to branch-tree
103- if uts not in actions_dic [workflow ['head_branch' ]]:
104- actions_dic [workflow ['head_branch' ]][uts ]= {'commit' :workflow ['head_sha' ],'id_list' : []}
105- actions_dic [workflow ['head_branch' ]][uts ]['id_list' ].append (workflow ['id' ])
122+ if uts not in actions_dic [workflow ["head_branch" ]]:
123+ actions_dic [workflow ["head_branch" ]][uts ]= {
124+ "commit" :workflow ["head_sha" ],
125+ "id_list" : [],
126+ }
127+ actions_dic [workflow ["head_branch" ]][uts ]["id_list" ].append (
128+ workflow ["id" ]
129+ )
106130
107131return actions_dic
108132
109133
110134def json_load (file_name ):
111- """ load json structure from file """
112- with open (file_name ,encoding = ' utf8' )as json_file :
135+ """load json structure from file"""
136+ with open (file_name ,encoding = " utf8" )as json_file :
113137data = json .load (json_file )
114138return data
115139
116140
117141def json_store (file_name_ ,data_ ):
118- """ store structure as json to file """
119- with open (file_name_ ,'w' ,encoding = ' utf-8' )as out_file :
142+ """store structure as json to file"""
143+ with open (file_name_ ,"w" ,encoding = " utf-8" )as out_file :
120144json .dump (data_ ,out_file ,ensure_ascii = False ,indent = 4 )
121145
122146
123147def print_debug (debug ,text ):
124- """ little helper to print debug messages """
148+ """little helper to print debug messages"""
125149if debug :
126- print (f' { datetime .now ()} :{ text } ' )
150+ print (f" { datetime .now ()} :{ text } " )
127151
128152
129153def idlist_filter (debug ,action_dic ,branch_list ,commit_number ,delete_all ):
130- """ select ids to be deleted """
131- print_debug (debug ,f' idlist_filter({ commit_number } )' )
154+ """select ids to be deleted"""
155+ print_debug (debug ,f" idlist_filter({ commit_number } )" )
132156id_list = []
133157for branch in action_dic :
134158delete = False
@@ -140,22 +164,22 @@ def idlist_filter(debug, action_dic, branch_list, commit_number, delete_all):
140164# skip latest n commits
141165delete = True
142166# print_debug(debug, '{0}, {1}, {2}, {3}'.format(branch, timestamp, idx, delete))
143- for id_ in action_dic [branch ][timestamp ][' id_list' ]:
167+ for id_ in action_dic [branch ][timestamp ][" id_list" ]:
144168if delete :
145169id_list .append (id_ )
146170return id_list
147171
148172
149173def idlist_delete (debug ,auth ,reponame ,id_list ):
150- """ delete worflow logs """
151- print_debug (debug ,f' idlist_delete({ id_list } )' )
174+ """delete worflow logs"""
175+ print_debug (debug ,f" idlist_delete({ id_list } )" )
152176for id_ in id_list :
153- print_debug (debug ,f' delete id:{ id_ } ' )
154- url = f' https://api.github.com/repos/{ reponame } /actions/runs/{ id_ } '
177+ print_debug (debug ,f" delete id:{ id_ } " )
178+ url = f" https://api.github.com/repos/{ reponame } /actions/runs/{ id_ } "
155179_resp = requests .delete (url = url ,auth = auth ,timeout = 20 )
156180
157181
158- if __name__ == ' __main__' :
182+ if __name__ == " __main__" :
159183
160184 (DEBUG ,AUTH ,REPONAME ,BRANCHLIST ,COMMIT_NUMBER ,DELETE_ALL )= arg_parse ()
161185