loopabull-tasks/playbooks/roles/flag_ci_pr/files/flag_ci_pr.py
Pierre-Yves Chibon 8baf2bfc88 Don't crash when the PR id is invalid
Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
2019-09-05 12:56:10 +02:00

130 lines
3.6 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This script takes as input the fedmsg messages published under the topic
``ci.pipeline.allpackages-pr.complete`` and flag the corresponding PR in
dist-git with the result of the tests.
Authors: Pierre-Yves Chibon <pingou@pingoured.fr>
"""
from __future__ import unicode_literals
import hashlib
import json
import os
import sys
import requests
from requests.packages.urllib3.util import retry
def main(msg, pipeline_state='complete', seed='empty'):
""" Check if the build was successful and if so, flag the commit in
pagure.
:param str msg: the fedmsg message body
:param str pipeline_state: state of the testing, one of 'complete'
or 'running'
"""
timeout = (30, 30)
retries = 3
requests_session = requests.Session()
retry_conf = retry.Retry(
total=retries, connect=retries, read=retries, backoff_factor=1)
retry_conf.BACKOFF_MAX = 5
requests_session.mount(
'http://', requests.adapters.HTTPAdapter(max_retries=retry_conf))
requests_session.mount(
'https://', requests.adapters.HTTPAdapter(max_retries=retry_conf))
if pipeline_state not in ['complete', 'running']:
print("Pipeline state is not 'complete' or 'running'.")
return
commit_hash_text = ''
# test complete messages
if pipeline_state == 'complete':
done_states = {
'SUCCESS': {'api': 'success', 'human': 'passed'},
'UNSTABLE': {'api': 'failure', 'human': 'failed'},
'FAILURE': {'api': 'error', 'human': 'errored'},
}
state = msg['status']
if state not in done_states:
print('Build is not in one of the expected status, ignoring')
return
status = done_states[state]['api']
human_status = done_states[state]['human']
if 'commit_hash' in msg:
commit_hash_text = ' for %s' % msg['commit_hash'][:8]
# test running messages
elif pipeline_state == 'running':
status = 'pending'
human_status = 'running'
pr_id = str(msg['rev']).partition('PR-')[2]
if not pr_id:
print(
'Invalid revision: %s, could not extract the PR id from it' %
msg['rev'])
return
data = {
'username': 'Fedora CI',
'status': status,
'comment': 'Package tests%s: %s' % (commit_hash_text, human_status),
'url': msg['build_url'],
'uid': hashlib.md5(pr_id + seed).hexdigest()
}
pagure_url = 'https://src.fedoraproject.org'
env_var = 'API_TOKEN'
target_url = '/'.join([
'api',
'0',
msg['namespace'],
msg['repo'],
'pull-request',
pr_id,
'flag'
])
flag_url = pagure_url + '/' + target_url
print('Flagging commit at: %s' % flag_url)
headers = {
"Authorization": "token " + os.environ.get(env_var),
'User-Agent': 'loopabull@fedora-infra',
}
print('payload: %s' % data)
req = requests_session.request(
method='POST',
url=flag_url,
headers=headers,
data=data,
)
print('Request to %s returned: %s' % (pagure_url, req.status_code))
if not req.ok:
print(req.text)
return 1
else:
print('All clear')
print('User-URL: %s' % pagure_url + '/' + '/'.join([
msg['namespace'],
msg['repo'],
'pull-request',
pr_id,
]))
if __name__ == '__main__':
msg = sys.argv[1]
msg = json.loads(msg)
sys.exit(main(msg, sys.argv[2], sys.argv[3]))