def _extract_github_params(self, sourcestamp, branch=None): """Parses parameters required to by github License note: Contains copied parts from the original buildbot implementation. """ # branch is updated by the checkoutstep, required for PRs branch = branch or sourcestamp['branch'] project = sourcestamp['project'] repo = sourcestamp['repository'] sha = sourcestamp['revision'] # determine whether the branch refers to a PR m = re.search(r'refs/pull/([0-9]*)/merge', branch) if m: issue = m.group(1) else: issue = None if '/' in project: repo_owner, repo_name = project.split('/') else: giturl = giturlparse(repo) repo_owner, repo_name = giturl.owner, giturl.repo return dict(sha=sha, repo=repo, branch=branch, issue=issue, repo_owner=repo_owner, repo_name=repo_name)
def _extract_github_info(self, sourcestamp): repo_owner = None repo_name = None project = sourcestamp['project'] repository = sourcestamp['repository'] if project and "/" in project: repo_owner, repo_name = project.split('/') elif repository: giturl = giturlparse(repository) if giturl: repo_owner = giturl.owner repo_name = giturl.repo return repo_owner, repo_name
def send(self, build): props = Properties.fromDict(build['properties']) if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failure', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) elif self.startDescription: state = 'pending' description = yield props.render(self.startDescription) else: return context = yield props.render(self.context) sourcestamps = build['buildset'].get('sourcestamps') if not sourcestamps or not sourcestamps[0]: return project = sourcestamps[0]['project'] branch = props['branch'] m = re.search(r"refs/pull/([0-9]*)/merge", branch) if m: issue = m.group(1) else: issue = None if "/" in project: repoOwner, repoName = project.split('/') else: giturl = giturlparse(sourcestamps[0]['repository']) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg( "Updating github status: repoOwner={repoOwner}, repoName={repoName}" .format(repoOwner=repoOwner, repoName=repoName)) for sourcestamp in sourcestamps: sha = sourcestamp['revision'] try: repo_user = unicode2NativeString(repoOwner) repo_name = unicode2NativeString(repoName) sha = unicode2NativeString(sha) state = unicode2NativeString(state) target_url = unicode2NativeString(build['url']) context = unicode2NativeString(context) issue = unicode2NativeString(issue) description = unicode2NativeString(description) yield self.createStatus(repo_user=repo_user, repo_name=repo_name, sha=sha, state=state, target_url=target_url, context=context, issue=issue, description=description) if self.verbose: log.msg('Updated status with "{state}" for ' '{repoOwner}/{repoName} at {sha}, issue {issue}.'. format(state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue)) except Exception as e: log.err( e, 'Failed to update "{state}" for ' '{repoOwner}/{repoName} at {sha}, issue {issue}'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue))
def send(self, build): props = Properties.fromDict(build["properties"]) props.master = self.master if build["complete"]: state = { SUCCESS: "success", WARNINGS: "success", FAILURE: "failure", SKIPPED: "success", EXCEPTION: "error", RETRY: "pending", CANCELLED: "error", }.get(build["results"], "error") else: return if state != "failure": return yield getDetailsForBuild(self.master, build, wantLogs=True, wantSteps=True) tracebacks = list() try: test_log = build["steps"][TESTS_STEP]["logs"][0]["content"]["content"] test_log = "\n".join([line.lstrip("eo") for line in test_log.splitlines()]) tracebacks = TRACEBACK_REGEX.findall(test_log) except IndexError: pass if not tracebacks: tracebacks = list(self._construct_tracebacks_from_stderr(build)) context = yield props.render(self.context) sourcestamps = build["buildset"].get("sourcestamps") if not sourcestamps or not sourcestamps[0]: return changes = yield self.master.data.get(("builds", build["buildid"], "changes")) if len(changes) > 1: return change, = changes m = re.search(r"\((?:GH-|#)(\d+)\)", change["comments"]) if m is None: return issue = m.groups()[-1] project = sourcestamps[0]["project"] if "/" in project: repoOwner, repoName = project.split("/") else: giturl = giturlparse(sourcestamps[0]["repository"]) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg( "Updating github status: repoOwner={repoOwner}, repoName={repoName}".format( repoOwner=repoOwner, repoName=repoName ) ) try: repo_user = unicode2NativeString(repoOwner) repo_name = unicode2NativeString(repoName) sha = unicode2NativeString(change["revision"]) target_url = unicode2NativeString(build["url"]) context = unicode2NativeString(context) yield self.createStatus( build=build, repo_user=repo_user, repo_name=repo_name, sha=sha, state=state, target_url=target_url, context=context, issue=issue, tracebacks=tracebacks, ) if self.verbose: log.msg( "Issued a Pull Request comment for {repoOwner}/{repoName} " 'at {sha}, context "{context}", issue {issue}.'.format( repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context, ) ) except Exception as e: log.err( e, "Failed to issue a Pull Request comment for {repoOwner}/{repoName} " 'at {sha}, context "{context}", issue {issue}.'.format( repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context, ), )
def send(self, build): props = Properties.fromDict(build['properties']) props.master = self.master if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failure', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) elif self.startDescription: state = 'pending' description = yield props.render(self.startDescription) else: return context = yield props.render(self.context) sourcestamps = build['buildset'].get('sourcestamps') if not sourcestamps: return for sourcestamp in sourcestamps: project = sourcestamp['project'] issue = None if 'branch' in props: m = re.search(r"refs/pull/([0-9]*)/merge", props['branch']) if m: issue = m.group(1) repo_owner = None repo_name = None if "/" in project: repo_owner, repo_name = project.split('/') else: giturl = giturlparse(sourcestamp['repository']) if giturl: repo_owner = giturl.owner repo_name = giturl.repo sha = sourcestamp['revision'] response = None # If the scheduler specifies multiple codebases, don't bother updating # the ones for which there is no revision if not sha: log.msg('Skipped status update for codebase {codebase}, ' 'context "{context}", issue {issue}.'.format( codebase=sourcestamp['codebase'], issue=issue, context=context)) continue try: if self.verbose: log.msg( "Updating github status: repo_owner={}, repo_name={}". format(repo_owner, repo_name)) response = yield self.createStatus(repo_user=repo_owner, repo_name=repo_name, sha=sha, state=state, target_url=build['url'], context=context, issue=issue, description=description) if not response: # the implementation of createStatus refused to post update due to missing data continue if not self.isStatus2XX(response.code): raise Exception() if self.verbose: log.msg( 'Updated status with "{state}" for {repo_owner}/{repo_name} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repo_owner=repo_owner, repo_name=repo_name, sha=sha, issue=issue, context=context)) except Exception as e: if response: content = yield response.content() code = response.code else: content = code = "n/a" log.err( e, 'Failed to update "{state}" for {repo_owner}/{repo_name} ' 'at {sha}, context "{context}", issue {issue}. ' 'http {code}, {content}'.format(state=state, repo_owner=repo_owner, repo_name=repo_name, sha=sha, issue=issue, context=context, code=code, content=content))
def send(self, build): props = Properties.fromDict(build['properties']) props.master = self.master if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failure', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) elif self.startDescription: state = 'pending' description = yield props.render(self.startDescription) else: return context = yield props.render(self.context) sourcestamps = build['buildset'].get('sourcestamps') if not sourcestamps or not sourcestamps[0]: return branch = props['branch'] m = re.search(r"refs/pull/([0-9]*)/merge", branch) if m: issue = m.group(1) else: # We only want to comment pull requests, so we exit here return for sourcestamp in sourcestamps: if branch == sourcestamp['branch']: project = sourcestamp['project'] repository = sourcestamp['repository'] sha = sourcestamp['revision'] break if project is None: log.err('Failed to determine the project of PR "{branch}"'.format( branch=branch)) return if "/" in project: repoOwner, repoName = project.split('/') else: giturl = giturlparse(repository) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg("Updating github status: repoOwner={repoOwner}, repoName={repoName}".format( repoOwner=repoOwner, repoName=repoName)) try: repo_user = unicode2NativeString(repoOwner) repo_name = unicode2NativeString(repoName) sha = unicode2NativeString(sha) state = unicode2NativeString(state) target_url = unicode2NativeString(build['url']) context = unicode2NativeString(context) issue = unicode2NativeString(issue) description = unicode2NativeString(description) yield self.createStatus( repo_user=repo_user, repo_name=repo_name, sha=sha, state=state, target_url=target_url, context=context, issue=issue, description=description ) if self.verbose: log.msg( 'Updated status with "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context)) except Exception as e: log.err( e, 'Failed to update "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context))
def send(self, build): props = Properties.fromDict(build['properties']) props.master = self.master if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failure', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) elif self.startDescription: state = 'pending' description = yield props.render(self.startDescription) else: return context = yield props.render(self.context) sourcestamps = build['buildset'].get('sourcestamps') if not sourcestamps or not sourcestamps[0]: return branch = props['branch'] m = re.search(r"refs/pull/([0-9]*)/merge", branch) if m: issue = m.group(1) else: # We only want to comment pull requests, so we exit here return for sourcestamp in sourcestamps: if branch == sourcestamp['branch']: project = sourcestamp['project'] repository = sourcestamp['repository'] sha = sourcestamp['revision'] break if project is None: log.err('Failed to determine the project of PR "{branch}"'.format( branch=branch)) return if "/" in project: repoOwner, repoName = project.split('/') else: giturl = giturlparse(repository) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg( "Updating github status: repoOwner={repoOwner}, repoName={repoName}" .format(repoOwner=repoOwner, repoName=repoName)) try: yield self.createStatus(repo_user=repoOwner, repo_name=repoName, sha=sha, state=state, target_url=build['url'], context=context, issue=issue, description=description) if self.verbose: log.msg( 'Updated status with "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context)) except Exception as e: log.err( e, 'Failed to update "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context))
def send(self, build): props = Properties.fromDict(build['properties']) props.master = self.master if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failure', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) elif self.startDescription: state = 'pending' description = yield props.render(self.startDescription) else: return context = yield props.render(self.context) sourcestamps = build['buildset'].get('sourcestamps') if not sourcestamps or not sourcestamps[0]: return project = sourcestamps[0]['project'] branch = props['branch'] m = re.search(r"refs/pull/([0-9]*)/merge", branch) if m: issue = m.group(1) else: issue = None if "/" in project: repoOwner, repoName = project.split('/') else: giturl = giturlparse(sourcestamps[0]['repository']) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg("Updating github status: repoOwner={repoOwner}, repoName={repoName}".format( repoOwner=repoOwner, repoName=repoName)) for sourcestamp in sourcestamps: sha = sourcestamp['revision'] try: repo_user = repoOwner repo_name = repoName target_url = build['url'] response = yield self.createStatus( repo_user=repo_user, repo_name=repo_name, sha=sha, state=state, target_url=target_url, context=context, issue=issue, description=description ) if not self.isStatus2XX(response.code): raise Exception() if self.verbose: log.msg( 'Updated status with "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context)) except Exception as e: content = yield response.content() log.err( e, 'Failed to update "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}. ' 'http {code}, {content}'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context, code=response.code, content=content))
def send(self, build): props = Properties.fromDict(build["properties"]) props.master = self.master if build["complete"]: state = { SUCCESS: "success", WARNINGS: "success", FAILURE: "failure", SKIPPED: "success", EXCEPTION: "error", RETRY: "pending", CANCELLED: "error", }.get(build["results"], "error") else: return if state != "failure": return yield getDetailsForBuild(self.master, build, wantLogs=True, wantSteps=True) logs, tracebacks = get_logs_and_tracebacks_from_build(build) context = yield props.render(self.context) sourcestamps = build["buildset"].get("sourcestamps") if not (sourcestamps and sourcestamps[0]): return changes = yield self.master.data.get(("builds", build["buildid"], "changes")) if len(changes) != 1: return change = changes[0] change_comments = change["comments"] if not change_comments: return m = re.search(r"\((?:GH-|#)(\d+)\)", change_comments) if m is None: return issue = m.groups()[-1] project = sourcestamps[0]["project"] if "/" in project: repoOwner, repoName = project.split("/") else: giturl = giturlparse(sourcestamps[0]["repository"]) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg( "Updating github status: repoOwner={repoOwner}, repoName={repoName}".format( repoOwner=repoOwner, repoName=repoName ) ) try: repo_user = repoOwner repo_name = repoName sha = change["revision"] target_url = build["url"] context = context yield self.createStatus( build=build, repo_user=repo_user, repo_name=repo_name, sha=sha, state=state, target_url=target_url, context=context, issue=issue, tracebacks=tracebacks, logs=logs, ) if self.verbose: log.msg( "Issued a Pull Request comment for {repoOwner}/{repoName} " 'at {sha}, context "{context}", issue {issue}.'.format( repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context, ) ) except Exception as e: log.err( e, "Failed to issue a Pull Request comment for {repoOwner}/{repoName} " 'at {sha}, context "{context}", issue {issue}.'.format( repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context, ), )
def send(self, build): props = Properties.fromDict(build['properties']) props.master = self.master if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failure', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) elif self.startDescription: state = 'pending' description = yield props.render(self.startDescription) else: return context = yield props.render(self.context) sourcestamps = build['buildset'].get('sourcestamps') if not sourcestamps or not sourcestamps[0]: return project = sourcestamps[0]['project'] branch = props['branch'] m = re.search(r"refs/pull/([0-9]*)/merge", branch) if m: issue = m.group(1) else: issue = None if "/" in project: repoOwner, repoName = project.split('/') else: giturl = giturlparse(sourcestamps[0]['repository']) repoOwner = giturl.owner repoName = giturl.repo if self.verbose: log.msg( "Updating github status: repoOwner={repoOwner}, repoName={repoName}" .format(repoOwner=repoOwner, repoName=repoName)) for sourcestamp in sourcestamps: if sourcestamp['revision'] != '': sha = sourcestamp['revision'] else: try: repo_user = repoOwner repo_name = repoName branch = sourcestamp['branch'] response = yield self.getSha(repo_user=repo_user, repo_name=repo_name, branch=branch) content = yield response.content() info = ast.literal_eval(content) sha = info["object"]["sha"] except Exception as e: sha = '' log.err( e, 'Failed to get sha for {repoOwner}/{repoName} ' 'branch "{branch}"' 'http {code}, {content}'.format(repoOwner=repoOwner, repoName=repoName, branch=branch, code=response.code, content=content)) try: repo_user = repoOwner repo_name = repoName sha = sha state = state target_url = build['url'] context = context issue = issue description = description response = yield self.createStatus(repo_user=repo_user, repo_name=repo_name, sha=sha, state=state, target_url=target_url, context=context, issue=issue, description=description) if not self.isStatus2XX(response.code): raise Exception() if self.verbose: log.msg( 'Updated status with "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context)) except Exception as e: content = yield response.content() log.err( e, 'Failed to update "{state}" for {repoOwner}/{repoName} ' 'at {sha}, context "{context}", issue {issue}. ' 'http {code}, {content}'.format(state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, issue=issue, context=context, code=response.code, content=content))