Update Jenkins script to use python-jenkins

This commit is contained in:
Raoul Snyman 2017-10-26 13:33:22 -07:00
parent d34918a5e2
commit 93e0a35489
1 changed files with 62 additions and 56 deletions

View File

@ -31,25 +31,16 @@ You probably want to create an alias. Add this to your ~/.bashrc file and then l
You can look up the token in the Branch-01-Pull job configuration or ask in IRC.
"""
import os
import re
import sys
import time
from optparse import OptionParser
from argparse import ArgumentParser
from subprocess import Popen, PIPE
import warnings
from requests.exceptions import HTTPError
from jenkins import Jenkins
JENKINS_URL = 'https://ci.openlp.io/'
REPO_REGEX = r'(.*/+)(~.*)'
# Allows us to black list token. So when we change the token, we can display a proper message to the user.
OLD_TOKENS = []
# Disable the InsecureRequestWarning we get from urllib3, because we're not verifying our own self-signed certificate
warnings.simplefilter('ignore')
class OpenLPJobs(object):
@ -85,13 +76,22 @@ class JenkinsTrigger(object):
:param token: The token we need to trigger the build. If you do not have this token, ask in IRC.
"""
def __init__(self, token):
def __init__(self, username, password, can_use_colour):
"""
Create the JenkinsTrigger instance.
"""
self.token = token
self.build_numbers = {}
self.can_use_colour = can_use_colour and not os.name.startswith('nt')
self.repo_name = get_repo_name()
self.jenkins_instance = Jenkins(JENKINS_URL)
self.server = Jenkins(JENKINS_URL, username=username, password=password)
def fetch_build_numbers(self):
"""
Get the next build number from all the jobs
"""
for job_name in OpenLPJobs.Jobs:
job_info = self.server.get_job_info(job_name)
self.build_number[job_name] = job_info['nextBuildNumber']
def trigger_build(self):
"""
@ -102,8 +102,7 @@ class JenkinsTrigger(object):
# We just want the name (not the email).
name = ' '.join(raw_output.decode().split()[:-1])
cause = 'Build triggered by %s (%s)' % (name, self.repo_name)
self.jenkins_instance.job(OpenLPJobs.Branch_Pull).build({'BRANCH_NAME': self.repo_name, 'cause': cause},
token=self.token)
self.server.build_job(OpenLPJobs.Branch_Pull, {'BRANCH_NAME': self.repo_name, 'cause': cause})
def print_output(self):
"""
@ -129,6 +128,20 @@ class JenkinsTrigger(object):
# Open the url
Popen(('xdg-open', url), stderr=PIPE)
def _get_build_info(self, job_name, build_number):
"""
Get the build info from the server. This method will check the queue and wait for the build.
"""
queue_info = self.server.get_queue_info()
tries = 0
while queue_info and tries < 50:
tries += 1
time.sleep(0.5)
queue_info = self.server.get_queue_info()
if tries >= 50:
raise Exception('Build has not started yet, it may be stuck in the queue.')
return self.server.get_build_info(job_name, build_number)
def __print_build_info(self, job_name):
"""
This helper method prints the job information of the given ``job_name``
@ -136,21 +149,21 @@ class JenkinsTrigger(object):
:param job_name: The name of the job we want the information from. For example *Branch-01-Pull*. Use the class
variables from the :class:`OpenLPJobs` class.
"""
build_info = self._get_build_info(job_name, self.build_number[job_name])
print('{} ... '.format(build_info['url']), end='', flush=True)
is_success = False
job = self.jenkins_instance.job(job_name)
while job.info['inQueue']:
time.sleep(1)
build = job.last_build
build.wait()
if build.info['result'] == 'SUCCESS':
while build_info['building'] is True:
time.sleep(0.5)
build_info = self.server.get_build_info(job_name, self.build_number[job_name])
result_string = build_info['result']
if self.can_use_colour and result_string == 'SUCCESS':
# Make 'SUCCESS' green.
result_string = '%s%s%s' % (Colour.GREEN_START, build.info['result'], Colour.GREEN_END)
result_string = '%s%s%s' % (Colour.GREEN_START, result_string, Colour.GREEN_END)
is_success = True
else:
elif self.can_use_colour:
# Make 'FAILURE' red.
result_string = '%s%s%s' % (Colour.RED_START, build.info['result'], Colour.RED_END)
url = build.info['url']
print('[%s] %s' % (result_string, url))
result_string = '%s%s%s' % (Colour.RED_START, result_string, Colour.RED_END)
print('[{}]'.format(result_string))
return is_success
@ -186,36 +199,29 @@ def get_repo_name():
def main():
usage = 'Usage: python %prog TOKEN [options]'
"""
Run the script
"""
parser = ArgumentParser()
parser.add_argument('-d', '--disable-output', action='store_false', default=True, help='Disable output')
parser.add_argument('-b', '--open-browser', action='store_true', default=False,
help='Opens the jenkins page in your browser')
parser.add_argument('-c', '--enable-colour', action='store_false', default=True,
help='Enable coloured output. Disabled on Windows')
parser.add_argument('-u', '--username', required=True, help='Your Jenkins username')
parser.add_argument('-p', '--password', required=True, help='Your Jenkins password or personal token')
args = parser.parse_args()
parser = OptionParser(usage=usage)
parser.add_option('-d', '--disable-output', dest='enable_output', action='store_false', default=True,
help='Disable output.')
parser.add_option('-b', '--open-browser', dest='open_browser', action='store_true', default=False,
help='Opens the jenkins page in your browser.')
options, args = parser.parse_args(sys.argv)
if len(args) == 2:
if not get_repo_name():
print('Not a branch. Have you pushed it to launchpad? Did you cd to the branch?')
return
token = args[-1]
if token in OLD_TOKENS:
print('Your token is not valid anymore. Get the most recent one.')
return
jenkins_trigger = JenkinsTrigger(token)
try:
jenkins_trigger.trigger_build()
except HTTPError:
print('Wrong token.')
return
# Open the browser before printing the output.
if options.open_browser:
jenkins_trigger.open_browser()
if options.enable_output:
jenkins_trigger.print_output()
else:
parser.print_help()
if not get_repo_name():
print('Not a branch. Have you pushed it to launchpad? Did you cd to the branch?')
return
jenkins_trigger = JenkinsTrigger(username=args.username, password=args.password)
jenkins_trigger.trigger_build()
# Open the browser before printing the output.
if args.open_browser:
jenkins_trigger.open_browser()
if not args.disable_output:
jenkins_trigger.print_output()
if __name__ == '__main__':