Salut les zesteurs !
Etant donne que je suis feignant mais que je veux participer a la redaction d'articles concernant le dev', j'ai bricoler un petit script python permettant de generer des bases de rapport de release.
Grosso modo, le script se connecte a l'API github en mode public (limite de 60 requêtes par heures et par IP donc) et interroge pour avoir la liste des milestones puis une liste des tickets de la milestone choisies.
Un rapport en MD est ensuite généré.
C'est une version tres cru pour le moment, mais comme ce n'est qu'un simple outil a utilisation "de temps en temps"… J'ai teste sur Python 2.7 et tout roule. (besoin de la dépendance requests
installable avec pip)
Voici le script (qui peut être largement rendu plus propre, je suis toujours débutant en python XD ) !
Et nouveau, une version javascript sur jsbin : http://jsbin.com/weqakariqo/16/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | # -*- coding: utf-8 -*- import codecs import json import requests import sys # Script inspired from https://gist.github.com/unbracketed/3380407 def get_milestones(): jalons = [] r = requests.get("https://api.github.com/repos/zestedesavoir/zds-site/milestones") jalons += parse_milestones(r) # more pages? examine the 'link' header returned if 'link' in r.headers: pages = dict( [(rel[6:-1], url[url.index('<')+1:-1]) for url, rel in [link.split(';') for link in r.headers['link'].split(',')]]) while 'last' in pages and 'next' in pages: r = requests.get(pages['next']) jalons += parse_milestones(r) if pages['next'] == pages['last']: break return jalons; def parse_milestones(req): if not req.status_code == 200: raise Exception(req.status_code) milestones = [] for milestone in req.json(): milestones.append(milestone) return milestones def get_issues(milestone_id): r = requests.get("https://api.github.com/repos/zestedesavoir/zds-site/issues?milestone={}&state=all". format(milestone_id)) [o, cb, ce, cu] = parse_issues(r) openissues = [] # still open issue closed_bug = [] # closed bug issue closed_evo = [] # closed evolution issue closed_unk = [] # closed not bug or evo issue openissues += o closed_bug += cb closed_evo += ce closed_unk += cu # more pages? examine the 'link' header returned while 'link' in r.headers: pages = dict( [(rel[6:-1], url[url.index('<')+1:-1]) for url, rel in [link.split(';') for link in r.headers['link'].split(',')]]) if 'next' in pages: r = requests.get(pages['next']) [o, cb, ce, cu] = parse_issues(r) openissues += o # still open issue closed_bug += cb # closed bug issue closed_evo += ce # closed evolution issue closed_unk += cu # closed not bug or evo issue else: break # exit the while loop return (openissues, closed_bug, closed_evo, closed_unk); def parse_issues(req): if not req.status_code == 200: raise Exception(req.status_code) openissues = [] # still open issue closed_bug = [] # closed bug issue closed_evo = [] # closed evolution issue closed_unk = [] # closed not bug or evo issue for issue in req.json(): # check open issues if issue['state'] == "open": openissues.append(issue) # check closed issue elif issue['state'] == "closed": labels = [] for l in issue['labels']: labels.append(l["name"].lower()) if "bug" in labels: closed_bug.append(issue) elif "evolution" in labels: closed_evo.append(issue) else: closed_unk.append(issue) return openissues, closed_bug, closed_evo, closed_unk def dump_issues(milestone, openissues, closed_bug, closed_evo, closed_unk): # output all tables to a file with codecs.open("output", "w", "utf-8") as out: out.write(u"Rapport pour le jalon **[{}](https://github.com/zestedesavoir/zds-site/milestones/{})** *({})*\n\n" .format(milestone["title"], milestone["title"], milestone["description"])) out.write(u"{} tickets sont compris dans ce jalon ({} ouverts et {} fermés)\n\n". format(len(openissues)+len(closed_bug)+len(closed_evo)+len(closed_unk), len(openissues), len(closed_bug)+len(closed_evo)+len(closed_unk))) out.write(u"# Ticket toujours ouvert\n\n") out.write(mdarray(openissues)) out.write(u"# Ticket fermé\n\n") out.write(u"## Corrections de bug\n\n") out.write(mdarray(closed_bug)) out.write(u"## Evolutions\n\n") out.write(mdarray(closed_evo)) out.write(u"## Non défini\n\n") out.write(mdarray(closed_unk)) def mdarray(tableau): if len(tableau) == 0: return u"Aucun ticket\n\n" ret = "Ticket # | Titre | Label(s)\n" ret += "---------|-------|---------\n" for issue in tableau: labels = "" for label in issue["labels"]: labels += label["name"] + ", " labels = labels[:-2] ret += u"[#{}]({}) | {} | {}\n" \ .format(issue["number"], issue["html_url"], issue["title"], labels) ret += "\n" return ret ############################################################### milestones = get_milestones() # print the milestones for i in range(0, len(milestones)): print "{}. {}".format(i+1, milestones[i]['title']) jalon_id = 0 while not jalon_id: try: jalon_id = raw_input("Quel milestone voulez-vous generer (id) (q=quitter) ? ") jalon_id = int(jalon_id) if jalon_id > len(milestones): print "{} ne fait pas parti des milestones connues".format(jalon_id) jalon_id = 0 except: if jalon_id.lower() == "q": sys.exit("Bye Bye !") print "{} n'est pas un nombre !".format(jalon_id) jalon_id = 0 print "Recuperation des tickets..." [openissues, closed_bug, closed_evo, closed_unk] = get_issues(milestones[jalon_id-1]["number"]) dump_issues(milestones[jalon_id-1], openissues, closed_bug, closed_evo, closed_unk) |