def send(self, build): props = Properties.fromDict(build['properties']) props.master = self.master results = build['results'] if build['complete']: state = SUCCESSFUL if results == SUCCESS else FAILED description = self.endDescription else: state = INPROGRESS description = self.startDescription key = yield props.render(self.key) description = yield props.render(description) if description else None context = yield props.render(self.context) if self.context else None sourcestamps = build['buildset']['sourcestamps'] for sourcestamp in sourcestamps: try: sha = unicode2NativeString(sourcestamp['revision']) if sha is None: log.msg("Unable to get the commit hash") continue key = unicode2NativeString(key) state = unicode2NativeString(state) url = unicode2NativeString(build['url']) key = unicode2NativeString(key) description = unicode2NativeString(description) context = unicode2NativeString(context) res = yield self.createStatus( sha=sha, state=state, url=url, key=key, description=description, context=context ) if res.code not in (HTTP_PROCESSED,): content = yield res.content() log.msg("{code}: Unable to send Bitbucket Server status: " "{content}".format(code=res.code, content=content)) elif self.verbose: log.msg('Status "{state}" sent for {sha}.'.format( state=state, sha=sha)) except Exception as e: log.err( e, 'Failed to send status "{state}" for ' '{repo} at {sha}'.format( state=state, repo=sourcestamp['repository'], sha=sha ))
def test_reporter_basic(self): yield self.setupReporter() _, builds = yield self.setupBuildResults(SUCCESS) build = builds[0] self._http.expect("post", EXPECTED_API, json={"text": UNICODE_BODY}, code=HTTP_CREATED) build["complete"] = True self.setUpLogging() yield self.cp.buildComplete(("build", 20, "finished"), build) self.assertLogged( unicode2NativeString(u'Comment sent to {}'.format(PR_URL)))
def parseAndRemove(stdout): files = [] for filename in self.getUnversionedFiles(stdout, self.keep_on_purge): filename = unicode2NativeString(self.build.path_module.join(self.workdir, filename)) files.append(filename) if not files: d = defer.succeed(0) else: if self.workerVersionIsOlderThan('rmdir', '2.14'): d = self.removeFiles(files) else: d = self.runRmdir(files, abandonOnFailure=False, timeout=self.timeout) return d
def test_reporter_basic(self): yield self.setupReporter() _, builds = yield self.setupBuildResults(SUCCESS) build = builds[0] self._http.expect( "post", EXPECTED_API, json={"text": UNICODE_BODY}, code=HTTP_CREATED) build["complete"] = True self.setUpLogging() yield self.cp.buildComplete(("build", 20, "finished"), build) self.assertLogged(unicode2NativeString( u'Comment sent to {}'.format(PR_URL)))
def parseAndRemove(stdout): files = [] for filename in self.getUnversionedFiles(stdout, self.keep_on_purge): filename = unicode2NativeString( self.build.path_module.join(self.workdir, filename)) files.append(filename) if not files: d = defer.succeed(0) else: if self.workerVersionIsOlderThan('rmdir', '2.14'): d = self.removeFiles(files) else: d = self.runRmdir(files, abandonOnFailure=False, timeout=self.timeout) return d
def getProjectId(self, sourcestamp): # retrieve project id via cache url = giturlparse(sourcestamp['repository']) if url is None: defer.returnValue(None) project_full_name = u"%s/%s" % (url.owner, url.repo) project_full_name = unicode2NativeString(project_full_name) # gitlab needs project name to be fully url quoted to get the project id project_full_name = urlquote_plus(project_full_name) if project_full_name not in self.project_ids: response = yield self._http.get('/api/v3/projects/%s' % (project_full_name)) proj = yield response.json() if response.code not in (200, ): log.msg( 'Unknown (or hidden) gitlab project' '{repo}: {message}'.format( repo=project_full_name, **proj)) defer.returnValue(None) self.project_ids[project_full_name] = proj['id'] defer.returnValue(self.project_ids[project_full_name])
def send(self, build): props = Properties.fromDict(build['properties']) if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failed', SKIPPED: 'success', EXCEPTION: 'failed', RETRY: 'pending', CANCELLED: 'cancelled' }.get(build['results'], 'failed') description = yield props.render(self.endDescription) else: state = 'running' description = yield props.render(self.startDescription) context = yield props.render(self.context) sourcestamps = build['buildset']['sourcestamps'] for sourcestamp in sourcestamps: sha = sourcestamp['revision'] proj_id = yield self.getProjectId(sourcestamp) if proj_id is None: continue try: branch = unicode2NativeString(sourcestamp['branch']) sha = unicode2NativeString(sha) state = unicode2NativeString(state) target_url = unicode2NativeString(build['url']) context = unicode2NativeString(context) description = unicode2NativeString(description) res = yield self.createStatus( project_id=proj_id, branch=branch, sha=sha, state=state, target_url=target_url, context=context, description=description ) if res.code not in (200, 201, 204): message = yield res.json() message = message.get('message', 'unspecified error') log.msg( 'Could not send status "{state}" for ' '{repo} at {sha}: {message}'.format( state=state, repo=sourcestamp['repository'], sha=sha, message=message)) elif self.verbose: log.msg( 'Status "{state}" sent for ' '{repo} at {sha}.'.format( state=state, repo=sourcestamp['repository'], sha=sha)) except Exception as e: log.err( e, 'Failed to send status "{state}" for ' '{repo} at {sha}'.format( state=state, repo=sourcestamp['repository'], sha=sha ))
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 test_unicode2NativeString(self): rv = util.unicode2NativeString(u'abcd') self.assertEqual((rv, type(rv)), ('abcd', str)) rv = util.unicode2NativeString('efgh') self.assertEqual((rv, type(rv)), ('efgh', str))
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']) if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failed', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) else: state = 'pending' description = yield props.render(self.startDescription) context = yield props.render(self.context) sourcestamps = build['buildset']['sourcestamps'] project = sourcestamps[0]['project'] # default to master if not found branch = sourcestamps[0].get('branch', 'master') if project: repoOwner, repoName = project.split('/') else: repo = sourcestamps[0]['repository'].split('/')[-2:] repoOwner = repo[0] repoName = '.'.join(repo[1].split('.')[:-1]) m = re.match(".*:(.*)", repoOwner) if m is not None: repoOwner = m.group(1) # retrieve project id via cache self.project_ids project_full_name = "%s%%2F%s" % (repoOwner, repoName) project_full_name = unicode2NativeString(project_full_name) if project_full_name not in self.project_ids: proj = yield self._http.get('/api/v3/projects/%s' % (project_full_name)) proj = yield proj.json() self.project_ids[project_full_name] = proj['id'] proj_id = self.project_ids[project_full_name] for sourcestamp in sourcestamps: sha = sourcestamp['revision'] try: branch = unicode2NativeString(branch) sha = unicode2NativeString(sha) state = unicode2NativeString(state) target_url = unicode2NativeString(build['url']) context = unicode2NativeString(context) description = unicode2NativeString(description) res = yield self.createStatus(project_id=proj_id, branch=branch, sha=sha, state=state, target_url=target_url, context=context, description=description) if res.code not in (200, 201, 204): message = yield res.json() message = message.get('message', 'unspecified error') log.msg( 'Could not send status "{state}" for ' '{repoOwner}/{repoName} at {sha}: {message}'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, message=message)) elif self.verbose: log.msg('Status "{state}" sent for ' '{repoOwner}/{repoName} at {sha}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha)) except Exception as e: log.err( e, 'Fail to send status "{state}" for ' '{repoOwner}/{repoName} at {sha}'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha))
def run(self): _log = yield self.addLog('xx') output_str = unicode2NativeString(u'\N{CENT SIGN}', encoding='latin-1') yield _log.addStdout(output_str) yield _log.finish() defer.returnValue(results.SUCCESS)
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 project: repoOwner, repoName = project.split('/') else: repo = sourcestamps[0]['repository'].split('/')[-2:] repoOwner = repo[0] repoName = '.'.join(repo[1].split('.')[:-1]) 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']) if build['complete']: state = { SUCCESS: 'success', WARNINGS: 'success', FAILURE: 'failed', SKIPPED: 'success', EXCEPTION: 'error', RETRY: 'pending', CANCELLED: 'error' }.get(build['results'], 'error') description = yield props.render(self.endDescription) else: state = 'pending' description = yield props.render(self.startDescription) context = yield props.render(self.context) sourcestamps = build['buildset']['sourcestamps'] project = sourcestamps[0]['project'] # default to master if not found branch = sourcestamps[0].get('branch', 'master') if project: repoOwner, repoName = project.split('/') else: repo = sourcestamps[0]['repository'].split('/')[-2:] repoOwner = repo[0] repoName = '.'.join(repo[1].split('.')[:-1]) m = re.match(".*:(.*)", repoOwner) if m is not None: repoOwner = m.group(1) # retrieve project id via cache self.project_ids project_full_name = "%s%%2F%s" % (repoOwner, repoName) project_full_name = unicode2NativeString(project_full_name) if project_full_name not in self.project_ids: proj = yield self._http.get('/api/v3/projects/%s' % (project_full_name)) proj = yield proj.json() self.project_ids[project_full_name] = proj['id'] proj_id = self.project_ids[project_full_name] for sourcestamp in sourcestamps: sha = sourcestamp['revision'] try: branch = unicode2NativeString(branch) sha = unicode2NativeString(sha) state = unicode2NativeString(state) target_url = unicode2NativeString(build['url']) context = unicode2NativeString(context) description = unicode2NativeString(description) res = yield self.createStatus( project_id=proj_id, branch=branch, sha=sha, state=state, target_url=target_url, context=context, description=description ) if res.code not in (200, 201, 204): message = yield res.json() message = message.get('message', 'unspecified error') log.msg( 'Could not send status "{state}" for ' '{repoOwner}/{repoName} at {sha}: {message}'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha, message=message)) elif self.verbose: log.msg( 'Status "{state}" sent for ' '{repoOwner}/{repoName} at {sha}.'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha)) except Exception as e: log.err( e, 'Fail to send status "{state}" for ' '{repoOwner}/{repoName} at {sha}'.format( state=state, repoOwner=repoOwner, repoName=repoName, sha=sha))