Skip to content

Commit

Permalink
script: add approval flow for script upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
Spiderpowa committed Oct 1, 2019
1 parent db25fb4 commit 60333a0
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
4 changes: 3 additions & 1 deletion scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ docker image.

## Updating

Your commit must be signed whenever `run_bp.py` is changed. Check the [GitHub Help](https://help.github.com/en/articles/signing-commits) to set it up.
The commit updating the script must be signed whenever `run_bp.py` is changed. Check the [GitHub Help](https://help.github.com/en/articles/signing-commits) to set it up.

After committing the file, several approvers(check `_SCRIPT_APPROVER` and `_SCRIPT_APPROVE_THRESHOLD` in the script) then update their `run_bp.py.APPROVER_GITHUB_ID` with the commit hash of the `run_bp.py`. Note that the approver's commit must be signed to be considered a valid approval.
34 changes: 34 additions & 0 deletions scripts/run_bp.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
_SCRIPT_PATH = 'scripts/run_bp.py'
_SCRIPT_SRC = ('https://raw.githubusercontent.com/'
'%s/%s/%s/%s' % (_SCRIPT_ORG, _SCRIPT_REPO, _SCRIPT_BRANCH, _SCRIPT_PATH))
_SCRIPT_APPROVE_PATH_TMPL = _SCRIPT_PATH + '.%s'
_SCRIPT_APPROVE_SRC_TMPL = ('https://raw.githubusercontent.com/'
'%s/%s/%%s/%s' % (_SCRIPT_ORG, _SCRIPT_REPO, _SCRIPT_APPROVE_PATH_TMPL))
_SCRIPT_APPROVER = ['aitjcize', 'popodidi', 'JM00oo', 'Spiderpowa']
_SCRIPT_APPROVE_THRESHOLD = int(len(_SCRIPT_APPROVER)/2)

_GITHUB_API = 'https://api.github.com'

Expand Down Expand Up @@ -164,6 +169,33 @@ def github_get_commits(path):
return '%s/repos/%s/%s/commits?path=%s&sha=%s' % (_GITHUB_API, _SCRIPT_ORG, _SCRIPT_REPO, path, _SCRIPT_BRANCH)


def github_get_approved_commit(commit, approver):
with urllib.request.urlopen(github_get_commits(_SCRIPT_APPROVE_PATH_TMPL % approver),
timeout=_REQUEST_TIMEOUT) as f:
if f.getcode() != 200:
raise RuntimeError('unable to get approver metadata')
for item in json.loads(f.read()):
if not item['commit']['verification']['verified']:
continue
if item['author']['login'] != approver:
continue
with urllib.request.urlopen(_SCRIPT_APPROVE_SRC_TMPL % (commit, approver),
timeout=_REQUEST_TIMEOUT) as f2:
if f2.getcode() != 200:
raise RuntimeError('unable to get approver file')
if f2.read().decode('utf-8') == commit:
return True
return False


def github_get_approve_status(commit):
approved = 0
for approver in _SCRIPT_APPROVER:
if github_get_approved_commit(commit, approver):
approved += 1
return approved >= _SCRIPT_APPROVE_THRESHOLD


def check_for_update():
"""Check for script update."""
script_path = os.path.abspath(sys.argv[0])
Expand All @@ -184,6 +216,8 @@ def check_for_update():
for item in json.loads(f.read()):
if not item['commit']['verification']['verified']:
continue
if not github_get_approve_status(item['sha']):
continue
tree_url = item['commit']['tree']['url']
for segment in _SCRIPT_PATH.split('/'):
with urllib.request.urlopen(tree_url,
Expand Down

0 comments on commit 60333a0

Please sign in to comment.