Merge ~the-meulengracht/snappy-hwe-snaps/+git/jenkins-jobs:master into ~snappy-hwe-team/snappy-hwe-snaps/+git/jenkins-jobs:master

Proposed by Philip Meulengracht
Status: Merged
Approved by: Alfonso Sanchez-Beato
Approved revision: d20dc2f3493ffbf7c1e1bbaf516dfe1689cfbf64
Merged at revision: 016fa6aca8bf2a9774f1fb3b629ece831ca2c6e1
Proposed branch: ~the-meulengracht/snappy-hwe-snaps/+git/jenkins-jobs:master
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/jenkins-jobs:master
Diff against target: 491 lines (+71/-69)
11 files modified
3rdparty/repo (+1/-1)
jobs/infrastructure/credentials-1-launchpad.py (+2/-1)
jobs/infrastructure/prepare-0-install.sh (+31/-29)
tools/automerge-mps.py (+1/-1)
tools/delete-ci-repo.py (+1/-3)
tools/se_utils/__init__.py (+17/-9)
tools/shyaml (+1/-1)
tools/trigger-ci.py (+1/-1)
tools/unstage-from-manifest.py (+1/-2)
tools/update-merge-proposal.py (+2/-10)
tools/vote-on-merge-proposal.py (+13/-11)
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
System Enablement Bot continuous-integration Approve
Review via email: mp+422731@code.launchpad.net

Description of the change

This MP contains the following:
 - Support for focal
 - Migration to python3

To post a comment you must log in.
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Thanks for this! I've a couple of comments.

Also, I have run flake8 on the python scripts, that should help to find issues in the migration to python3. See https://paste.ubuntu.com/p/cBMsq89xvZ/ . I think most things are harmless, except maybe:

./tools/vote-on-merge-proposal.py:76:10: E999 SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?

Anyway, it is a good opportunity to clean-up these warnings, although maybe you can ignore the "line too long" ones.

Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM, thanks for the changes!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/3rdparty/repo b/3rdparty/repo
index f9eb9e8..c069798 100644
--- a/3rdparty/repo
+++ b/3rdparty/repo
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
22
3# repo default configuration3# repo default configuration
4#4#
diff --git a/jobs/infrastructure/credentials-1-launchpad.py b/jobs/infrastructure/credentials-1-launchpad.py
index 59dd706..61e36de 100644
--- a/jobs/infrastructure/credentials-1-launchpad.py
+++ b/jobs/infrastructure/credentials-1-launchpad.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2#2#
3# Copyright (C) 2016 Canonical Ltd3# Copyright (C) 2016 Canonical Ltd
4#4#
@@ -82,5 +82,6 @@ def get_launchpad(cred_path, launchpadlib_dir=None):
82 authorization_engine=authorization_engine,82 authorization_engine=authorization_engine,
83 launchpadlib_dir=launchpadlib_dir)83 launchpadlib_dir=launchpadlib_dir)
8484
85
85if __name__ == '__main__':86if __name__ == '__main__':
86 get_launchpad("{credentials_path}")87 get_launchpad("{credentials_path}")
diff --git a/jobs/infrastructure/prepare-0-install.sh b/jobs/infrastructure/prepare-0-install.sh
index d50e5a9..afffe90 100644
--- a/jobs/infrastructure/prepare-0-install.sh
+++ b/jobs/infrastructure/prepare-0-install.sh
@@ -16,6 +16,9 @@
1616
17set -ex17set -ex
1818
19JENKINS_JOBS_GIT_REPO="{jobs-git-repo}"
20JENKINS_JOBS_GIT_REPO_BRANCH="{jobs-git-repo-branch}"
21
19# Use correct home and preserve environment variables when calling `sudo ...`22# Use correct home and preserve environment variables when calling `sudo ...`
20SUDO="sudo -E -H"23SUDO="sudo -E -H"
2124
@@ -26,24 +29,27 @@ $SUDO apt-get install --yes software-properties-common
26# build tools as used in Launchpad29# build tools as used in Launchpad
27$SUDO add-apt-repository --yes ppa:launchpad/buildd-staging30$SUDO add-apt-repository --yes ppa:launchpad/buildd-staging
28$SUDO add-apt-repository --yes ppa:jenkaas-hackers/tools31$SUDO add-apt-repository --yes ppa:jenkaas-hackers/tools
29$SUDO add-apt-repository --yes ppa:snappy-hwe-team/ci-tools32
33version=$(lsb_release -sc)
34if [ "$version" = "xenial" ]; then
35 $SUDO add-apt-repository --yes ppa:snappy-hwe-team/ci-tools
36fi
3037
31$SUDO apt-get update38$SUDO apt-get update
3239
33echo "postfix postfix/mailname string $(hostname)" | $SUDO debconf-set-selections40echo "postfix postfix/mailname string $(hostname)" | $SUDO debconf-set-selections
34echo "postfix postfix/main_mailer_type string 'Internet Site'" | $SUDO debconf-set-selections41echo "postfix postfix/main_mailer_type string 'Internet Site'" | $SUDO debconf-set-selections
3542
43# install shared packages
36$SUDO apt-get install --yes \44$SUDO apt-get install --yes \
37 git \45 git \
38 python \46 python3 \
39 python-launchpadlib \47 python3-launchpadlib \
40 python-bzrlib \48 python3-lockfile \
41 python-lockfile \49 python3-yaml \
42 python-yaml \50 python3-jenkins \
43 python-jenkins \51 python3-requests \
44 python-requests \52 python3-git \
45 python-git \
46 python-pip \
47 python3-debian \53 python3-debian \
48 python3-pip \54 python3-pip \
49 tarmac \55 tarmac \
@@ -58,7 +64,6 @@ $SUDO apt-get install --yes \
58 jq \64 jq \
59 postfix \65 postfix \
60 abootimg \66 abootimg \
61 android-tools-fsutils \
62 golang-go \67 golang-go \
63 dpkg-dev \68 dpkg-dev \
64 devscripts \69 devscripts \
@@ -66,31 +71,28 @@ $SUDO apt-get install --yes \
66 bzr \71 bzr \
67 dh-systemd \72 dh-systemd \
68 expect \73 expect \
69 tcl \74 tcl {install_packages}
70 {install_packages}75
76# install additional packages based on distro
77if [ "$version" != "xenial" ]; then
78 $SUDO apt-get install --yes \
79 android-sdk-libsparse-utils \
80 android-sdk-ext4-utils
81else
82 $SUDO apt-get install --yes \
83 android-tools-fsutils
84fi
7185
72# Install snaps86# Install snaps
73$SUDO snap install snapcraft87$SUDO snap install snapcraft
74$SUDO snap install yq88$SUDO snap install yq
7589
76# Install additional sofware from the python package database90export http_proxy="{http_proxy}"
77$SUDO pip2 install --upgrade pip91export https_proxy="{https_proxy}"
78$SUDO pip2 install jenkins-job-builder pid
7992
80# documentation-builder is normally available as a snap but we can't93# documentation-builder is normally available as a snap but we can't
81# use snaps yet on our agents.94# use snaps yet on our agents.
82$SUDO pip3 install --upgrade pip95$SUDO pip3 install --upgrade pip
96$SUDO pip3 install --ignore-installed PyYAML
97$SUDO pip3 install jenkins-job-builder pid
83$SUDO pip3 install ubuntudesign.documentation-builder98$SUDO pip3 install ubuntudesign.documentation-builder
84
85# Now http & https proxy is not needed, it will in fact interfere with curl
86# below
87
88unset http_proxy
89unset https_proxy
90
91# Fetch and install latest repo; we still can't use snaps reliably on our
92# agents so we go with the upstream release.
93$SUDO mkdir -p /usr/local/bin
94curl $JENKINS_JOBS_GIT_REPO/plain/3rdparty/repo?h=$JENKINS_JOBS_GIT_REPO_BRANCH | $SUDO tee /usr/local/bin/repo
95$SUDO mv $HOME/repo /usr/local/bin/repo
96$SUDO chmod +x /usr/local/bin/repo
diff --git a/tools/automerge-mps.py b/tools/automerge-mps.py
index 2e1e0b6..150da07 100755
--- a/tools/automerge-mps.py
+++ b/tools/automerge-mps.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3#3#
4# Copyright (C) 2016 Canonical Ltd4# Copyright (C) 2016 Canonical Ltd
diff --git a/tools/delete-ci-repo.py b/tools/delete-ci-repo.py
index 35c762d..3a04613 100755
--- a/tools/delete-ci-repo.py
+++ b/tools/delete-ci-repo.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2#2#
3# Copyright (C) 2017 Canonical Ltd3# Copyright (C) 2017 Canonical Ltd
4#4#
@@ -14,8 +14,6 @@
14# You should have received a copy of the GNU General Public License14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.15# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17from launchpadlib.launchpad import Launchpad
18
19from argparse import ArgumentParser17from argparse import ArgumentParser
2018
21import se_utils19import se_utils
diff --git a/tools/se_utils/__init__.py b/tools/se_utils/__init__.py
index 64cc0cc..e78eb6b 100644
--- a/tools/se_utils/__init__.py
+++ b/tools/se_utils/__init__.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3#3#
4# Copyright (C) 2016 Canonical Ltd4# Copyright (C) 2016 Canonical Ltd
@@ -18,7 +18,6 @@
18import atexit18import atexit
19import sys19import sys
20import time20import time
21import logging
22import os21import os
23import re22import re
24import yaml23import yaml
@@ -28,11 +27,13 @@ from lazr.restfulclient.errors import HTTPError
28from launchpadlib.launchpad import Launchpad27from launchpadlib.launchpad import Launchpad
29from launchpadlib.credentials import UnencryptedFileCredentialStore28from launchpadlib.credentials import UnencryptedFileCredentialStore
3029
30
31class LaunchpadVote():31class LaunchpadVote():
32 APPROVE = 'Approve'32 APPROVE = 'Approve'
33 DISAPPROVE = 'Disapprove'33 DISAPPROVE = 'Disapprove'
34 NEEDS_FIXING = 'Needs Fixing'34 NEEDS_FIXING = 'Needs Fixing'
3535
36
36ACCESS_TOKEN_POLL_TIME = 1037ACCESS_TOKEN_POLL_TIME = 10
37WAITING_FOR_USER = """Open this link:38WAITING_FOR_USER = """Open this link:
38{}39{}
@@ -58,7 +59,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine):
5859
59 """60 """
60 authorization_url = self.authorization_url(request_token)61 authorization_url = self.authorization_url(request_token)
61 print WAITING_FOR_USER.format(authorization_url)62 print(WAITING_FOR_USER.format(authorization_url))
62 # if we don't flush we may not see the message63 # if we don't flush we may not see the message
63 sys.stdout.flush()64 sys.stdout.flush()
64 while credentials.access_token is None:65 while credentials.access_token is None:
@@ -67,7 +68,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine):
67 credentials.exchange_request_token_for_access_token(68 credentials.exchange_request_token_for_access_token(
68 self.web_root)69 self.web_root)
69 break70 break
70 except HTTPError, e:71 except HTTPError as e:
71 if e.response.status == 403:72 if e.response.status == 403:
72 # The user decided not to authorize this73 # The user decided not to authorize this
73 # application.74 # application.
@@ -79,6 +80,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine):
79 # There was an error accessing the server.80 # There was an error accessing the server.
80 raise e81 raise e
8182
83
82# launchpadlib is not thread/process safe so we are creating launchpadlib84# launchpadlib is not thread/process safe so we are creating launchpadlib
83# cache in /tmp per process which gets cleaned up at the end85# cache in /tmp per process which gets cleaned up at the end
84# see also lp:459418 and lp:102515386# see also lp:459418 and lp:1025153
@@ -97,8 +99,8 @@ def get_launchpad(launchpadlib_dir=None, credential_store_path=None, lp_app=None
97 the default """99 the default """
98 store = UnencryptedFileCredentialStore(credential_store_path)100 store = UnencryptedFileCredentialStore(credential_store_path)
99 authorization_engine = AuthorizeRequestTokenWithConsole(lp_env, lp_app)101 authorization_engine = AuthorizeRequestTokenWithConsole(lp_env, lp_app)
100 lib_dir=launchpad_cachedir102 lib_dir = launchpad_cachedir
101 if launchpadlib_dir != None:103 if launchpadlib_dir is not None:
102 lib_dir = launchpadlib_dir104 lib_dir = launchpadlib_dir
103 return Launchpad.login_with(lp_app, lp_env,105 return Launchpad.login_with(lp_app, lp_env,
104 credential_store=store,106 credential_store=store,
@@ -106,6 +108,7 @@ def get_launchpad(launchpadlib_dir=None, credential_store_path=None, lp_app=None
106 launchpadlib_dir=lib_dir,108 launchpadlib_dir=lib_dir,
107 version='devel')109 version='devel')
108110
111
109# Load configuration for the current agent we're running on. All agents were112# Load configuration for the current agent we're running on. All agents were
110# provisioned when they were setup with a proper configuration. See113# provisioned when they were setup with a proper configuration. See
111# https://wiki.canonical.com/InformationInfrastructure/Jenkaas/UserDocs for114# https://wiki.canonical.com/InformationInfrastructure/Jenkaas/UserDocs for
@@ -121,12 +124,14 @@ def load_config():
121 print("ERROR: No config file found")124 print("ERROR: No config file found")
122 sys.exit(1)125 sys.exit(1)
123126
127
124# Return a configuration option from the agent configuration specified by the128# Return a configuration option from the agent configuration specified by the
125# name argument.129# name argument.
126def get_config_option(name):130def get_config_option(name):
127 config = load_config()131 config = load_config()
128 return config[name]132 return config[name]
129133
134
130def get_branch_handle_from_url(lp_handle, url):135def get_branch_handle_from_url(lp_handle, url):
131 """ Return a branch/repo handle for the given url.136 """ Return a branch/repo handle for the given url.
132 Returns a launchpad branch or git repository handle for the given url.137 Returns a launchpad branch or git repository handle for the given url.
@@ -147,6 +152,7 @@ def get_branch_handle_from_url(lp_handle, url):
147 print('fetching branch: ' + name)152 print('fetching branch: ' + name)
148 return lp_handle.branches.getByUrl(url=name)153 return lp_handle.branches.getByUrl(url=name)
149154
155
150def get_branch_from_mp(merge_proposal):156def get_branch_from_mp(merge_proposal):
151 """Return a link to branch given a link to a merge proposal.157 """Return a link to branch given a link to a merge proposal.
152158
@@ -157,11 +163,12 @@ def get_branch_from_mp(merge_proposal):
157163
158 :param merge_proposal: url of a launchpad merge proposal164 :param merge_proposal: url of a launchpad merge proposal
159 """165 """
160 m = re.search('(.*)\+merge/[0-9]+$', merge_proposal)166 m = re.search(r'(.*)\+merge/[0-9]+$', merge_proposal)
161 if m:167 if m:
162 return m.group(1)168 return m.group(1)
163 return None169 return None
164170
171
165def get_mp_handle_from_url(lp_handle, merge_proposal_link):172def get_mp_handle_from_url(lp_handle, merge_proposal_link):
166 """ Get launchpad handle for merge proposal given a merge proposal URL.173 """ Get launchpad handle for merge proposal given a merge proposal URL.
167174
@@ -173,7 +180,7 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link):
173 print('Unable to get branch link from merge proposal link.')180 print('Unable to get branch link from merge proposal link.')
174 return None181 return None
175182
176 branch = get_branch_handle_from_url(lp_handle, branch_link)183 branch = get_branch_handle_from_url(lp_handle, branch_link)
177 if not branch:184 if not branch:
178 print('Branch {} does not exist'.format(branch_link))185 print('Branch {} does not exist'.format(branch_link))
179 return None186 return None
@@ -187,6 +194,7 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link):
187194
188 return None195 return None
189196
197
190def get_vote_subject(mp):198def get_vote_subject(mp):
191 """Given a mp handle return a subject for the vote message199 """Given a mp handle return a subject for the vote message
192200
@@ -209,4 +217,4 @@ def get_vote_subject(mp):
209 else:217 else:
210 return 'Re: [Merge] {} into {}'.format(218 return 'Re: [Merge] {} into {}'.format(
211 mp.source_branch.display_name,219 mp.source_branch.display_name,
212 mp.target_branch.display_name)
213\ No newline at end of file220\ No newline at end of file
221 mp.target_branch.display_name)
diff --git a/tools/shyaml b/tools/shyaml
index e4618ec..ea3db4f 100755
--- a/tools/shyaml
+++ b/tools/shyaml
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
22
3# Taken from upstream git repository https://github.com/0k/shyaml3# Taken from upstream git repository https://github.com/0k/shyaml
4# at revision d77e30599a0971c51896ef97d21883550e7e99794# at revision d77e30599a0971c51896ef97d21883550e7e9979
diff --git a/tools/trigger-ci.py b/tools/trigger-ci.py
index 65f3b3e..9267a16 100755
--- a/tools/trigger-ci.py
+++ b/tools/trigger-ci.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3#3#
4# Copyright (C) 2016 Canonical Ltd4# Copyright (C) 2016 Canonical Ltd
diff --git a/tools/unstage-from-manifest.py b/tools/unstage-from-manifest.py
index e189492..e3f79ec 100755
--- a/tools/unstage-from-manifest.py
+++ b/tools/unstage-from-manifest.py
@@ -22,7 +22,6 @@
22# store.22# store.
2323
24import sys24import sys
25import yaml
26from tools import yaml_utils25from tools import yaml_utils
2726
2827
@@ -34,7 +33,7 @@ def remove_from_staged(pkg_list_path, manifest_path, out_manifest_path):
34 try:33 try:
35 with open(pkg_list_path) as pkg_list_f:34 with open(pkg_list_path) as pkg_list_f:
36 pkg_list = pkg_list_f.read().splitlines()35 pkg_list = pkg_list_f.read().splitlines()
37 except FileNotFoundError as e:36 except FileNotFoundError:
38 print(pkg_list_path, 'not found, just copying manifest')37 print(pkg_list_path, 'not found, just copying manifest')
39 pkg_list = []38 pkg_list = []
4039
diff --git a/tools/update-merge-proposal.py b/tools/update-merge-proposal.py
index 0054659..261fa6d 100755
--- a/tools/update-merge-proposal.py
+++ b/tools/update-merge-proposal.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3#3#
4# Copyright (C) 2017 Canonical Ltd4# Copyright (C) 2017 Canonical Ltd
@@ -15,14 +15,6 @@
15# You should have received a copy of the GNU General Public License15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.16# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
18import atexit
19import sys
20import time
21import logging
22import os
23import yaml
24import re
25from shutil import rmtree
26from argparse import ArgumentParser18from argparse import ArgumentParser
2719
28import se_utils20import se_utils
@@ -54,7 +46,7 @@ content = content.decode('string_escape')
54if not args['approve'] and not args['disapprove']:46if not args['approve'] and not args['disapprove']:
55 parser.error('neither approved or disapproved the MP')47 parser.error('neither approved or disapproved the MP')
5648
57vote=""49vote = ""
58if args["approve"]:50if args["approve"]:
59 vote = se_utils.LaunchpadVote.APPROVE51 vote = se_utils.LaunchpadVote.APPROVE
60elif args["disapprove"]:52elif args["disapprove"]:
diff --git a/tools/vote-on-merge-proposal.py b/tools/vote-on-merge-proposal.py
index bec6da5..96838a7 100755
--- a/tools/vote-on-merge-proposal.py
+++ b/tools/vote-on-merge-proposal.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python1#!/usr/bin/env python3
2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-2# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3#3#
4# Copyright (C) 2016 Canonical Ltd4# Copyright (C) 2016 Canonical Ltd
@@ -20,7 +20,6 @@ import sys
20import time20import time
21import logging21import logging
22import os22import os
23import yaml
24import re23import re
25from shutil import rmtree24from shutil import rmtree
26from argparse import ArgumentParser25from argparse import ArgumentParser
@@ -29,7 +28,7 @@ from lazr.restfulclient.errors import HTTPError
29from launchpadlib.launchpad import Launchpad28from launchpadlib.launchpad import Launchpad
30from launchpadlib.credentials import UnencryptedFileCredentialStore29from launchpadlib.credentials import UnencryptedFileCredentialStore
31from jlp import get_config_option30from jlp import get_config_option
32from jlp import launchpadutils, jenkinsutils, logger31from jlp import jenkinsutils
3332
34logger = logging.getLogger('jenkins-launchpad-plugin')33logger = logging.getLogger('jenkins-launchpad-plugin')
35stdout_handler = logging.StreamHandler(stream=sys.stdout)34stdout_handler = logging.StreamHandler(stream=sys.stdout)
@@ -73,7 +72,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine):
7372
74 """73 """
75 authorization_url = self.authorization_url(request_token)74 authorization_url = self.authorization_url(request_token)
76 print WAITING_FOR_USER.format(authorization_url)75 print(WAITING_FOR_USER.format(authorization_url))
77 # if we don't flush we may not see the message76 # if we don't flush we may not see the message
78 sys.stdout.flush()77 sys.stdout.flush()
79 while credentials.access_token is None:78 while credentials.access_token is None:
@@ -82,7 +81,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine):
82 credentials.exchange_request_token_for_access_token(81 credentials.exchange_request_token_for_access_token(
83 self.web_root)82 self.web_root)
84 break83 break
85 except HTTPError, e:84 except HTTPError as e:
86 if e.response.status == 403:85 if e.response.status == 403:
87 # The user decided not to authorize this86 # The user decided not to authorize this
88 # application.87 # application.
@@ -110,6 +109,7 @@ def get_launchpad(launchpadlib_dir=None):
110 launchpadlib_dir=launchpadlib_dir,109 launchpadlib_dir=launchpadlib_dir,
111 version='devel')110 version='devel')
112111
112
113def get_branch_handle_from_url(lp_handle, url):113def get_branch_handle_from_url(lp_handle, url):
114 """ Return a branch/repo handle for the given url.114 """ Return a branch/repo handle for the given url.
115 Returns a launchpad branch or git repository handle for the given url.115 Returns a launchpad branch or git repository handle for the given url.
@@ -130,6 +130,7 @@ def get_branch_handle_from_url(lp_handle, url):
130 logger.debug('fetching branch: ' + name)130 logger.debug('fetching branch: ' + name)
131 return lp_handle.branches.getByUrl(url=name)131 return lp_handle.branches.getByUrl(url=name)
132132
133
133def get_branch_from_mp(merge_proposal):134def get_branch_from_mp(merge_proposal):
134 """Return a link to branch given a link to a merge proposal.135 """Return a link to branch given a link to a merge proposal.
135136
@@ -140,11 +141,12 @@ def get_branch_from_mp(merge_proposal):
140141
141 :param merge_proposal: url of a launchpad merge proposal142 :param merge_proposal: url of a launchpad merge proposal
142 """143 """
143 m = re.search('(.*)\+merge/[0-9]+$', merge_proposal)144 m = re.search(r'(.*)\+merge/[0-9]+$', merge_proposal)
144 if m:145 if m:
145 return m.group(1)146 return m.group(1)
146 return None147 return None
147148
149
148def get_mp_handle_from_url(lp_handle, merge_proposal_link):150def get_mp_handle_from_url(lp_handle, merge_proposal_link):
149 """ Get launchpad handle for merge proposal given a merge proposal URL.151 """ Get launchpad handle for merge proposal given a merge proposal URL.
150152
@@ -156,7 +158,7 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link):
156 logger.error('Unable to get branch link from merge proposal link.')158 logger.error('Unable to get branch link from merge proposal link.')
157 return None159 return None
158160
159 branch = get_branch_handle_from_url(lp_handle, branch_link)161 branch = get_branch_handle_from_url(lp_handle, branch_link)
160 if not branch:162 if not branch:
161 logger.debug('Branch {} does not exist'.format(branch_link))163 logger.debug('Branch {} does not exist'.format(branch_link))
162 return None164 return None
@@ -170,11 +172,13 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link):
170172
171 return None173 return None
172174
175
173class LaunchpadVote():176class LaunchpadVote():
174 APPROVE = 'Approve'177 APPROVE = 'Approve'
175 DISAPPROVE = 'Disapprove'178 DISAPPROVE = 'Disapprove'
176 NEEDS_FIXING = 'Needs Fixing'179 NEEDS_FIXING = 'Needs Fixing'
177180
181
178def get_vote_subject(mp):182def get_vote_subject(mp):
179 """Given a mp handle return a subject for the vote message183 """Given a mp handle return a subject for the vote message
180184
@@ -241,6 +245,7 @@ def disapprove_mp(mp, revision, build_url, reason=None):
241 subject=get_vote_subject(mp),245 subject=get_vote_subject(mp),
242 content=content)246 content=content)
243247
248
244# launchpadlib is not thread/process safe so we are creating launchpadlib249# launchpadlib is not thread/process safe so we are creating launchpadlib
245# cache in /tmp per process which gets cleaned up at the end250# cache in /tmp per process which gets cleaned up at the end
246# see also lp:459418 and lp:1025153251# see also lp:459418 and lp:1025153
@@ -265,7 +270,4 @@ reason = ''
265if overal_status == 'PASSED':270if overal_status == 'PASSED':
266 approve_mp(mp, args['revision'], args['build_url'])271 approve_mp(mp, args['revision'], args['build_url'])
267else: # status == False corresponds to NOT 'PASSED'272else: # status == False corresponds to NOT 'PASSED'
268 disapprove_mp(mp,273 disapprove_mp(mp, args['revision'], args['build_url'], reason)
269 args['revision'],
270 args['build_url'],
271 reason)

Subscribers

People subscribed via source and target branches