~mrazik/jenkins-launchpad-plugin/fail-if-no-bug

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
#!/usr/bin/env python

import sys
from argparse import ArgumentParser
from launchpad import LaunchpadTrigger
import launchpadutils
from settings import LOCK_NAME, logger
from jlp import SocketLock
import re


def main():
    parser = ArgumentParser(description="Vote on a Launchpad merge proposal.")
    parser.add_argument('-s', '--status')
    parser.add_argument('-u', '--build-url', required=True,
                        help="URL of the Jenkins job")
    parser.add_argument('-r', '--revision', required=True,
                        help="merge proposal candidate revision")
    parser.add_argument('-b', '--branch',
                        help="Launchpad branch proposed for merging")
    parser.add_argument('-p', '--merge-proposal', required=True,
                        help="URL of the merge proposal to update")
    parser.add_argument('-g', '--fail-if-no-bug',
                        default=False,
                        action='store_true',
                        help="Fail the landing if there is no bug linked" +
                             "to this merge proposal")

    args = vars(parser.parse_args())
    launchpad = LaunchpadTrigger()
    if not args['branch']:
        # if branch was not specified try to get it from merge proposal
        args['branch'] = launchpadutils.get_branch_from_mp(
            args['merge_proposal'])
        if not args['branch']:
            parser.error('Error: unable to get branch from merge proposal.\n' +
                         'Please specify manually using -- branch.')
    mp = launchpad.get_merge_proposal(args['branch'], args['merge_proposal'])
    if not mp:
        parser.error('merge proposal related to this branch was not found')

    # this is the status from tests
    overal_status = args['status']
    # by default reason is empty as it is usually just a failed build
    reason = ''

    #override the status to FAILED and set reason if no commit message is set
    match = re.match('^(.*)/job/([^/]*)/.*$', args['build_url'])
    if match:
        jenkins_url = match.group(1)
        jenkins_job = match.group(2)
        if not launchpad.is_commit_message_set(mp, jenkins_job, jenkins_url):
            overal_status = 'FAILED'
            reason = "No commit message was specified in the merge " + \
                     "proposal. Click on the following link and set the " + \
                     "commit message (if you want a jenkins rebuild you " +\
                     "need to trigger it yourself):\n" + \
                     args['merge_proposal'] + "/+edit-commit-message\n"
            logger.debug('Commit message not set. Failing CI.')
    else:
        logger.debug('Unable to get job name from build_url.' +
                     'Skipping check for empty commit message')

    #if --fail-if-no-bug is used and the source branch is not linked to
    #any bug report, change the state to failed
    if args['fail_if_no_bug'] and launchpad.get_bug_count(mp) == 0:
        overal_status = 'FAILED'
        reason = reason + \
            "No bug is linked to the proposed branch and project " + \
            "is configured to fail testing in such cases. " + \
            "Please link a bug report to the proposed branch: " + \
            mp.source_branch.web_link + "/+linkbug\n"

    if overal_status == 'PASSED':
        launchpad.approve_mp(mp, args['revision'], args['build_url'])
    else:  # status == False corresponds to NOT 'PASSED'
        launchpad.disapprove_mp(mp,
                                args['revision'],
                                args['build_url'],
                                reason)
    sys.exit(0)


if __name__ == "__main__":
    # this is here because launchpadlib is not thread safe (yet)
    # see also lp:459418 and lp:1025153
    logger.debug('Going to acquire launchpad lock for voteOnMergeProposal')
    with SocketLock(LOCK_NAME):
        logger.debug('Lock acquired for voteOnMergeProposal')
        sys.exit(main())