Warning

This document is for an in-development version of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.

Source code for galaxy.tools.error_reports.plugins.github

"""The module describes the ``github`` error plugin plugin."""

import logging
import sys
if sys.version_info[0] < 3:
    import urllib as urllib
    import urlparse as urlparse
else:
    import urllib.parse as urllib
    urlparse = urllib

from galaxy.util import string_as_bool, unicodify
from .base_git import BaseGitPlugin

log = logging.getLogger(__name__)


[docs]class GithubPlugin(BaseGitPlugin): """Send error report to Github. """ plugin_type = "github"
[docs] def __init__(self, **kwargs): self.app = kwargs['app'] self.redact_user_details_in_bugreport = self.app.config.redact_user_details_in_bugreport self.verbose = string_as_bool(kwargs.get('verbose', False)) self.user_submission = string_as_bool(kwargs.get('user_submission', False)) # Github settings self.github_base_url = kwargs.get('github_base_url', 'https://github.com') self.github_api_url = kwargs.get('github_api_url', 'https://api.github.com') self.git_default_repo_owner = kwargs.get('github_default_repo_owner', False) self.git_default_repo_name = kwargs.get('github_default_repo_name', False) self.git_default_repo_only = string_as_bool(kwargs.get('github_default_repo_only', True)) try: import github self.github = github.Github( kwargs['github_oauth_token'], # Allow running against GH enterprise deployments. base_url=self.github_api_url ) # Connect to the default repository and fill up the issue cache for it repo = self.github.get_repo('{}/{}'.format(self.git_default_repo_owner, self.git_default_repo_name)) self._fill_issue_cache(repo, "default") # We'll also cache labels which we'll use for tagging issues. self.label_cache["default"] = {} self._fill_label_cache(repo, "default") except ImportError: log.error("Please install pygithub to submit bug reports to github") self.github = None
[docs] def submit_report(self, dataset, job, tool, **kwargs): """Submit the error report to sentry """ log.info(self.github) if self.github: # Determine the ToolShed url, initially we connect with HTTP and if redirect to HTTPS is set up, # this will be detected by requests and used further down the line. Also cache this so everything is # as fast as possible log.info(tool.tool_shed) ts_url = self._determine_ts_url(tool) log.info("GitLab error reporting - Determined ToolShed is %s", ts_url) # Find the repo inside the ToolShed ts_repourl = self._get_gitrepo_from_ts(job, ts_url) # Determine the GitLab project URL and the issue cache key github_projecturl = urlparse.urlparse(ts_repourl).path[1:] if (ts_repourl and not self.git_default_repo_only) \ else "/".join((self.git_default_repo_owner, self.git_default_repo_name)) issue_cache_key = self._get_issue_cache_key(job, ts_repourl) # Connect to the repo if github_projecturl not in self.git_project_cache: self.git_project_cache[github_projecturl] = self.github.get_repo('%s' % github_projecturl) gh_project = self.git_project_cache[github_projecturl] # Make sure we keep a cache of the issues, per tool in this case if issue_cache_key not in self.issue_cache: self._fill_issue_cache(gh_project, issue_cache_key) # Retrieve label label = self.get_label('{}/{}'.format(unicodify(job.tool_id), unicodify(job.tool_version)), gh_project, issue_cache_key) # Generate information for the tool error_title = self._generate_error_title(job) # Generate the error message error_message = self._generate_error_message(dataset, job, kwargs) log.info(error_title in self.issue_cache[issue_cache_key]) if error_title not in self.issue_cache[issue_cache_key]: # Create a new issue. self._create_issue(issue_cache_key, error_title, error_message, gh_project, label=label) else: self._append_issue(issue_cache_key, error_title, error_message) return ('Submitted error report to Github. Your issue number is <a href="%s/%s/issues/%s" ' 'target="_blank">#%s</a>.' % (self.github_base_url, github_projecturl, self.issue_cache[issue_cache_key][error_title].number, self.issue_cache[issue_cache_key][error_title].number), 'success')
def _create_issue(self, issue_cache_key, error_title, error_mesage, project, **kwargs): # Create a new issue. self.issue_cache[issue_cache_key][error_title] = project.create_issue( title=error_title, body=error_mesage, # Label it with a tag: tool_id/tool_version labels=[kwargs.get('label')] ) def _append_issue(self, issue_cache_key, error_title, error_message, **kwargs): # Create comment on an issue self.issue_cache[issue_cache_key][error_title].create_comment(error_message) def _fill_issue_cache(self, git_project, issue_cache_key): # We want to ensure that we don't generate a thousand issues when # multiple users report a bug. So, we need to de-dupe issues. In # order to de-dupe, we need to know which are open. So, we'll keep # a cache of open issues and just add to it whenever we create a # new one. self.issue_cache[issue_cache_key] = {} for issue in git_project.get_issues(state='open'): log.info(issue) self.issue_cache[issue_cache_key][issue.title] = issue log.info(self.issue_cache) def _fill_label_cache(self, git_project, issue_cache_key): for label in git_project.get_labels(): log.info(label) self.label_cache[issue_cache_key][label.name] = label log.info(self.label_cache)
[docs] def get_label(self, label, git_project, issue_cache_key): # If we don't have this label, then create it + cache it. if issue_cache_key not in self.label_cache: self.label_cache[issue_cache_key] = {} self._fill_label_cache(git_project, issue_cache_key) if label not in self.label_cache[issue_cache_key]: self.label_cache[issue_cache_key][label] = git_project.create_label(name=label, color='ffffff') return self.label_cache[issue_cache_key][label]
__all__ = ('GithubPlugin', )