"Fossies" - the Fresh Open Source Software Archive

Member "buildbot-2.3.1/buildbot/reporters/bitbucket.py" (23 May 2019, 4744 Bytes) of package /linux/misc/buildbot-2.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "bitbucket.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.0.1_vs_2.1.0.

    1 # This file is part of Buildbot.  Buildbot is free software: you can
    2 # redistribute it and/or modify it under the terms of the GNU General Public
    3 # License as published by the Free Software Foundation, version 2.
    4 #
    5 # This program is distributed in the hope that it will be useful, but WITHOUT
    6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    7 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    8 # details.
    9 #
   10 # You should have received a copy of the GNU General Public License along with
   11 # this program; if not, write to the Free Software Foundation, Inc., 51
   12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   13 #
   14 # Copyright Buildbot Team Members
   15 
   16 from urllib.parse import urlparse
   17 
   18 from twisted.internet import defer
   19 
   20 from buildbot.process.results import SUCCESS
   21 from buildbot.reporters import http
   22 from buildbot.util import httpclientservice
   23 from buildbot.util.logger import Logger
   24 
   25 log = Logger()
   26 
   27 # Magic words understood by Butbucket REST API
   28 BITBUCKET_INPROGRESS = 'INPROGRESS'
   29 BITBUCKET_SUCCESSFUL = 'SUCCESSFUL'
   30 BITBUCKET_FAILED = 'FAILED'
   31 
   32 _BASE_URL = 'https://api.bitbucket.org/2.0/repositories'
   33 _OAUTH_URL = 'https://bitbucket.org/site/oauth2/access_token'
   34 _GET_TOKEN_DATA = {
   35     'grant_type': 'client_credentials'
   36 }
   37 
   38 
   39 class BitbucketStatusPush(http.HttpStatusPushBase):
   40     name = "BitbucketStatusPush"
   41 
   42     @defer.inlineCallbacks
   43     def reconfigService(self, oauth_key, oauth_secret,
   44                         base_url=_BASE_URL,
   45                         oauth_url=_OAUTH_URL,
   46                         **kwargs):
   47         oauth_key, oauth_secret = yield self.renderSecrets(oauth_key, oauth_secret)
   48         yield super().reconfigService(**kwargs)
   49 
   50         if base_url.endswith('/'):
   51             base_url = base_url[:-1]
   52 
   53         self._http = yield httpclientservice.HTTPClientService.getService(
   54             self.master, base_url,
   55             debug=self.debug, verify=self.verify)
   56 
   57         self.oauthhttp = yield httpclientservice.HTTPClientService.getService(
   58             self.master, oauth_url, auth=(oauth_key, oauth_secret),
   59             debug=self.debug, verify=self.verify)
   60 
   61     @defer.inlineCallbacks
   62     def send(self, build):
   63         results = build['results']
   64         oauth_request = yield self.oauthhttp.post("",
   65                                                   data=_GET_TOKEN_DATA)
   66         if oauth_request.code == 200:
   67             content_json = yield oauth_request.json()
   68             token = content_json['access_token']
   69         else:
   70             content = yield oauth_request.content()
   71             log.error("{code}: unable to authenticate to Bitbucket {content}",
   72                       code=oauth_request.code, content=content)
   73             return
   74 
   75         if build['complete']:
   76             status = BITBUCKET_SUCCESSFUL if results == SUCCESS else BITBUCKET_FAILED
   77         else:
   78             status = BITBUCKET_INPROGRESS
   79 
   80         for sourcestamp in build['buildset']['sourcestamps']:
   81             sha = sourcestamp['revision']
   82             body = {
   83                 'state': status,
   84                 'key': build['builder']['name'],
   85                 'name': build['builder']['name'],
   86                 'url': build['url']
   87             }
   88 
   89             owner, repo = self.get_owner_and_repo(sourcestamp['repository'])
   90 
   91             self._http.updateHeaders({'Authorization': 'Bearer ' + token})
   92 
   93             bitbucket_uri = '/' + \
   94                 '/'.join([owner, repo, 'commit', sha, 'statuses', 'build'])
   95 
   96             response = yield self._http.post(bitbucket_uri, json=body)
   97             if response.code != 201:
   98                 content = yield response.content()
   99                 log.error("{code}: unable to upload Bitbucket status {content}",
  100                           code=response.code, content=content)
  101 
  102     @staticmethod
  103     def get_owner_and_repo(repourl):
  104         """
  105         Takes a git repository URL from Bitbucket and tries to determine the owner and repository name
  106         :param repourl: Bitbucket git repo in the form of
  107                     git@bitbucket.com:OWNER/REPONAME.git
  108                     https://bitbucket.com/OWNER/REPONAME.git
  109                     ssh://git@bitbucket.com/OWNER/REPONAME.git
  110         :return: owner, repo: The owner of the repository and the repository name
  111         """
  112         parsed = urlparse(repourl)
  113 
  114         if parsed.scheme:
  115             path = parsed.path[1:]
  116         else:
  117             # we assume git@host:owner/repo.git here
  118             path = parsed.path.split(':', 1)[-1]
  119 
  120         if path.endswith('.git'):
  121             path = path[:-4]
  122         while path.endswith('/'):
  123             path = path[:-1]
  124 
  125         parts = path.split('/')
  126 
  127         assert len(parts) == 2, 'OWNER/REPONAME is expected'
  128 
  129         return parts