[tools] master update
Mark J. Cox
mark at openssl.org
Wed Feb 5 15:48:28 UTC 2020
The branch master has been updated
via 216776e13b1673a13fccb525f2ec0c0d821f7525 (commit)
via daa4fdc5eba7a9d7c10bee7ece40b9397eb7d8ca (commit)
via 55a4f13f049861dfd06476d6d6e4cf1ac8a93c49 (commit)
from cbda6bd72e4abbe16a4a260312b1289a0e9e4764 (commit)
- Log -----------------------------------------------------------------
commit 216776e13b1673a13fccb525f2ec0c0d821f7525
Author: Mark J. Cox <mark at awe.com>
Date: Wed Feb 5 11:22:24 2020 +0000
Neews python 3.7+ (or do a different date parser)
commit daa4fdc5eba7a9d7c10bee7ece40b9397eb7d8ca
Author: Mark J. Cox <mark at awe.com>
Date: Wed Feb 5 11:20:25 2020 +0000
Style changes undo yapf blank lines, and fix typo function name
commit 55a4f13f049861dfd06476d6d6e4cf1ac8a93c49
Author: Mark J. Cox <mark at awe.com>
Date: Wed Feb 5 10:49:33 2020 +0000
Add a tool for checking and changing labels
-----------------------------------------------------------------------
Summary of changes:
.gitignore | 3 +
github-approve-label-workflow/README.md | 18 +++
.../github-approve-label-workflow.py | 165 +++++++++++++++++++++
3 files changed, 186 insertions(+)
create mode 100644 github-approve-label-workflow/README.md
create mode 100644 github-approve-label-workflow/github-approve-label-workflow.py
diff --git a/.gitignore b/.gitignore
index e3a688e..5c45ae8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,5 +36,8 @@ ghpass.txt
/OpenSSL-Query/inc
/OpenSSL-Query/pm_to_blib
+# in case someone forgets and commits their token
+github-approve-label-workflow/token.txt
+
# Generic
*~
diff --git a/github-approve-label-workflow/README.md b/github-approve-label-workflow/README.md
new file mode 100644
index 0000000..8442b58
--- /dev/null
+++ b/github-approve-label-workflow/README.md
@@ -0,0 +1,18 @@
+Do we have any open openssl PR requests that have the label
+"approval: done" that are over 24 hours old? If so if there
+have been no other comments added since then we can automatically
+move them to "approval: ready to merge"
+
+You need a token to make label changes and to ensure you don't
+hit rate limiting if you just want a dry run. Get one from
+https://github.com/settings/tokens/new select 'repo' only
+then put it in token.txt (prefix with the string "token ", i.e.
+echo "token 12903413aaaaaa" > token.txt
+
+to see what it would do:
+
+python github-approve-label-workflow --debug --token token.txt
+
+or to also actually change any labels
+
+python github-approve-label-workflow --debug --token token.txt --commit
diff --git a/github-approve-label-workflow/github-approve-label-workflow.py b/github-approve-label-workflow/github-approve-label-workflow.py
new file mode 100644
index 0000000..99713f7
--- /dev/null
+++ b/github-approve-label-workflow/github-approve-label-workflow.py
@@ -0,0 +1,165 @@
+#! /usr/bin/env python
+# requires python 3.7+
+#
+# Do we have any open PR's that have label "Approval: done"
+# that are over 24 hours without any other comments?
+#
+# get a token.... https://github.com/settings/tokens/new -- just repo is fine
+# pop it in token.txt or you'll get a bad API limit
+#
+# note that we'd use pyGithub but we can't as it doesn't fully handle the timeline objects
+# as of Feb 2020
+#
+# mark at openssl.org Feb 2020
+#
+import requests
+import json
+from datetime import datetime, timezone
+from optparse import OptionParser
+
+api_url = "https://api.github.com/repos/openssl/openssl"
+
+def convertdate(date):
+ # python fromisoformat needs a TZ in hours/minutes
+ return datetime.fromisoformat(date.replace('Z', '+00:00'))
+
+# Get all the open pull requests, filtering by approval: done label
+
+def getpullrequests():
+ url = api_url + "/pulls?per_page=100&page=1" # defaults to open
+ res = requests.get(url, headers=headers)
+ repos = res.json()
+ prs = []
+ while 'next' in res.links.keys():
+ res = requests.get(res.links['next']['url'], headers=headers)
+ repos.extend(res.json())
+
+ # Let's filter by label if we're just looking to move things, we can parse
+ # everything for statistics in another script
+
+ try:
+ for pr in repos:
+ if 'labels' in pr:
+ for label in pr['labels']:
+ if label['name'] == 'approval: done':
+ prs.append(pr['number'])
+ except:
+ print("failed", repos['message'])
+ return prs
+
+# Change the labels on an issue from approval: done to approval: ready to merge
+
+def movelabeldonetoready(issue):
+ url = api_url + "/issues/" + str(issue) + "/labels/approval:%20done"
+ res = requests.delete(url, headers=headers)
+ if (res.status_code != 200):
+ print("Error removing label", res.status_code, res.content)
+ return
+ url = api_url + "/issues/" + str(issue) + "/labels"
+ newlabel = {"labels": ["approval: ready to merge"]}
+ res = requests.post(url, data=json.dumps(newlabel), headers=headers)
+ if (res.status_code != 200):
+ print("Error adding label", res.status_code, res.content)
+
+# Check through an issue and see if it's a candidate for moving
+
+def checkpr(pr):
+ url = api_url + "/issues/" + str(pr) + "/timeline?per_page=100&page=1"
+ res = requests.get(url, headers=headers)
+ repos = res.json()
+ while 'next' in res.links.keys():
+ res = requests.get(res.links['next']['url'], headers=headers)
+ repos.extend(res.json())
+
+ comments = []
+ approvallabel = {}
+ readytomerge = 0
+
+ for event in repos:
+ try:
+ if (event['event'] == "commented"):
+ comments.append(convertdate(event["updated_at"]))
+ if debug:
+ print("debug: commented at ",
+ convertdate(event["updated_at"]))
+ if (event['event'] == "committed"):
+ comments.append(convertdate(event["author"]["date"]))
+ if debug:
+ print("debug: created at ",
+ convertdate(event["author"]["date"]))
+ elif (event['event'] == "labeled"):
+ if debug:
+ print("debug: labelled with ", event['label']['name'],
+ "at", convertdate(event["created_at"]))
+ approvallabel[event['label']['name']] = convertdate(
+ event["created_at"])
+ elif (event['event'] == "unlabeled"):
+ if (debug):
+ print("debug: unlabelled with ", event['label']['name'],
+ "at", convertdate(event["created_at"]))
+ if event['label'][
+ 'name'] in approvallabel: # have to do this for if labels got renamed in the middle
+ del approvallabel[event['label']['name']]
+ elif (event['event'] == "reviewed"
+ and event['state'] == "approved"):
+ if debug:
+ print("debug: approved at",
+ convertdate(event['submitted_at']))
+ except:
+ return (repos['message'])
+
+ if 'approval: ready to merge' in approvallabel:
+ return ("issue already has label approval: ready to merge")
+ if 'approval: done' not in approvallabel:
+ return ("issue did not get label approval: done")
+ approvedone = approvallabel['approval: done']
+
+ if max(comments) > approvedone:
+ return ("issue had comments after approval: done label was given")
+
+ now = datetime.now(timezone.utc)
+ hourssinceapproval = (now - approvedone).total_seconds() / 3600
+ if debug:
+ print("Now: ", now)
+ print("Last comment: ", max(comments))
+ print("Approved since: ", approvedone)
+ print("hours since approval", hourssinceapproval)
+
+ if (hourssinceapproval < 24):
+ return ("not yet 24 hours since labelled approval:done hours:" +
+ str(int(hourssinceapproval)))
+
+ if (options.commit):
+ print("Moving issue ", pr, " to approval: ready to merge")
+ movelabeldonetoready(pr)
+ else:
+ print("use --commit to actually change the labels")
+ return (
+ "this issue was candidate to move to approval: ready to merge hours:" +
+ str(int(hourssinceapproval)))
+
+# main
+
+parser = OptionParser()
+parser.add_option("-d","--debug",action="store_true",help="be noisy",dest="debug")
+parser.add_option("-t","--token",help="file containing github authentication token for example 'token 18asdjada...'",dest="token")
+parser.add_option("-c","--commit",action="store_true",help="actually change the labels",dest="commit")
+(options, args) = parser.parse_args()
+if (options.token):
+ fp = open(options.token, "r")
+ git_token = fp.readline().strip('\n')
+else:
+ git_token = "" # blank token is fine, but you can't change labels and you hit API rate limiting
+debug = options.debug
+# since timeline is a preview feature we have to enable access to it with an accept header
+headers = {
+ "Accept": "application/vnd.github.mockingbird-preview",
+ "Authorization": git_token
+}
+
+if debug:
+ print("Getting list of PRs")
+prs = getpullrequests()
+print("There were", len(prs), "open PRs with approval:done ")
+for pr in prs:
+ print(pr, checkpr(pr))
More information about the openssl-commits
mailing list