示例#1
0
def main():
    homepage = memcache.get("homepage")
    if IS_DEV_APPSERVER or homepage is None:
        issues = Issue.query(Issue.state == "open").order(-Issue.updated_at).iter()
        homepage = render_template('index.html', session=session, issues=issues)
        memcache.set("homepage", value=homepage, time=60)
    return homepage
示例#2
0
def update_pr(pr_number):
    logging.debug("Updating pull request %i" % pr_number)
    pr = Issue.get_or_create(pr_number)
    issue_response = raw_github_request(PULLS_BASE + '/%i' % pr_number,
                                        oauth_token=oauth_token, etag=pr.etag)
    if issue_response is None:
        logging.debug("PR %i hasn't changed since last visit; skipping" % pr_number)
        return "Done updating pull request %i (nothing changed)" % pr_number
    pr.pr_json = json.loads(issue_response.content)
    pr.etag = issue_response.headers["ETag"]
    pr.state = pr.pr_json['state']
    pr.user = pr.pr_json['user']['login']
    pr.updated_at = \
        parse_datetime(pr.pr_json['updated_at']).astimezone(tz.tzutc()).replace(tzinfo=None)

    for issue_number in pr.parsed_title['jiras']:
        try:
            link_issue_to_pr("SPARK-%s" % issue_number, pr)
        except:
            logging.exception("Exception when linking to JIRA issue SPARK-%s" % issue_number)
        try:
            start_issue_progress("SPARK-%s" % issue_number)
        except:
            logging.exception(
                "Exception when starting progress on JIRA issue SPARK-%s" % issue_number)

    pr.put()  # Write our modifications back to the database

    subtasks = [".update_pr_comments", ".update_pr_review_comments", ".update_pr_files"]
    for task in subtasks:
        taskqueue.add(url=url_for(task, pr_number=pr_number), queue_name='fresh-prs')

    return "Done updating pull request %i" % pr_number
示例#3
0
def update_pr(pr_number):
    logging.debug("Updating pull request %i" % pr_number)
    pr = Issue.get_or_create(pr_number)
    issue_response = raw_github_request(get_pulls_base() + '/%i' % pr_number,
                                        oauth_token=oauth_token, etag=pr.etag)
    if issue_response is None:
        logging.debug("PR %i hasn't changed since last visit; skipping" % pr_number)
        return "Done updating pull request %i (nothing changed)" % pr_number
    pr.pr_json = json.loads(issue_response.content)
    pr.etag = issue_response.headers["ETag"]
    pr.state = pr.pr_json['state']
    pr.user = pr.pr_json['user']['login']
    pr.updated_at = \
        parse_datetime(pr.pr_json['updated_at']).astimezone(tz.tzutc()).replace(tzinfo=None)

    for issue_number in pr.parsed_title['jiras']:
        try:
            link_issue_to_pr("%s-%s" % (app.config['JIRA_PROJECT'], issue_number), pr)
        except:
            logging.exception("Exception when linking to JIRA issue %s-%s" %
                              (app.config['JIRA_PROJECT'], issue_number))
        try:
            start_issue_progress("%s-%s" % (app.config['JIRA_PROJECT'], issue_number))
        except:
            logging.exception(
                "Exception when starting progress on JIRA issue %s-%s" %
                (app.config['JIRA_PROJECT'], issue_number))

    pr.put()  # Write our modifications back to the database

    subtasks = [".update_pr_comments", ".update_pr_review_comments", ".update_pr_files"]
    for task in subtasks:
        taskqueue.add(url=url_for(task, pr_number=pr_number), queue_name='fresh-prs')

    return "Done updating pull request %i" % pr_number
def main():
    issues = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    issues_by_component = defaultdict(list)
    for issue in issues:
        for component in issue.components:
            issues_by_component[component].append(issue)
    # Display the groups in the order listed in Issues._components
    grouped_issues = [(c[0], issues_by_component[c[0]]) for c in Issue._components]
    return build_response('index.html', grouped_issues=grouped_issues)
示例#5
0
def update_all_jiras_for_open_prs():
    """
    Used to bulk-load information from JIRAs for all open PRs.  Useful when upgrading
    from an earlier version of spark-prs.
    """
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    jira_issues = set(itertools.chain.from_iterable(pr.parsed_title['jiras'] for pr in prs))
    for issue in jira_issues:
        taskqueue.add(url="/tasks/update-jira-issue/SPARK-%i" % issue, queue_name='jira-issues')
    return "Queued JIRA issues for update: " + str(jira_issues)
示例#6
0
def update_pr_files(pr_number):
    pr = Issue.get(pr_number)
    files_response = paginated_github_request(PULLS_BASE + "/%i/files" % pr_number,
                                              oauth_token=oauth_token, etag=pr.files_etag)
    if files_response is None:
        return "Files for PR %i are up-to-date" % pr_number
    else:
        pr.files_json, pr.files_etag = files_response
        pr.put()  # Write our modifications back to the database
        return "Done updating files for PR %i" % pr_number
示例#7
0
def update_all_jiras_for_open_prs():
    """
    Used to bulk-load information from JIRAs for all open PRs.  Useful when upgrading
    from an earlier version of spark-prs.
    """
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    jira_issues = set(itertools.chain.from_iterable(pr.parsed_title["jiras"] for pr in prs))
    for issue in jira_issues:
        taskqueue.add(url="/tasks/update-jira-issue/SPARK-%i" % issue, queue_name="jira-issues")
    return "Queued JIRA issues for update: " + str(jira_issues)
示例#8
0
def users(username):
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    prs_authored = [p for p in prs if p.user == username]
    prs_commented_on = [
        p for p in prs if username in dict(p.commenters) and p.user != username
    ]
    return build_response('user.html',
                          username=username,
                          prs_authored=prs_authored,
                          prs_commented_on=prs_commented_on)
示例#9
0
def update_pr_files(pr_number):
    pr = Issue.get(pr_number)
    files_response = paginated_github_request(get_pulls_base() + "/%i/files" % pr_number,
                                              oauth_token=oauth_token, etag=pr.files_etag)
    if files_response is None:
        return "Files for PR %i are up-to-date" % pr_number
    else:
        pr.files_json, pr.files_etag = files_response
        pr.put()  # Write our modifications back to the database
        return "Done updating files for PR %i" % pr_number
示例#10
0
def main():
    issues = Issue.query(
        Issue.state == "open").order(-Issue.updated_at).fetch()
    issues_by_component = defaultdict(list)
    for issue in issues:
        for component in issue.components:
            issues_by_component[component].append(issue)
    # Display the groups in the order listed in Issues._components
    grouped_issues = [(c[0], issues_by_component[c[0]])
                      for c in Issue._components]
    return build_response('index.html', grouped_issues=grouped_issues)
示例#11
0
def update_pr_review_comments(pr_number):
    pr = Issue.get(pr_number)
    pr_comments_response = paginated_github_request(PULLS_BASE + '/%i/comments' % pr_number,
                                                    oauth_token=oauth_token)
    # TODO: after fixing #32, re-enable etags here: etag=self.pr_review_comments_etag)
    if pr_comments_response is None:
        return "Review comments for PR %i are up-to-date" % pr_number
    else:
        pr.pr_comments_json, pr.pr_comments_etag = pr_comments_response
        pr.cached_commenters = pr._compute_commenters()
        pr.put()  # Write our modifications back to the database
        return "Done updating review comments for PR %i" % pr_number
示例#12
0
def update_pr_review_comments(pr_number):
    pr = Issue.get(pr_number)
    pr_comments_response = paginated_github_request(get_pulls_base() + '/%i/comments' % pr_number,
                                                    oauth_token=oauth_token)
    # TODO: after fixing #32, re-enable etags here: etag=self.pr_review_comments_etag)
    if pr_comments_response is None:
        return "Review comments for PR %i are up-to-date" % pr_number
    else:
        pr.pr_comments_json, pr.pr_comments_etag = pr_comments_response
        pr.cached_commenters = pr._compute_commenters()
        pr.put()  # Write our modifications back to the database
        return "Done updating review comments for PR %i" % pr_number
示例#13
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    json_dicts = []
    for pr in prs:
        try:
            last_jenkins_comment_dict = None
            if pr.last_jenkins_comment:
                last_jenkins_comment_dict = {
                    'body': pr.last_jenkins_comment['body'],
                    'user': {'login': pr.last_jenkins_comment['user']['login']},
                    'html_url': pr.last_jenkins_comment['html_url'],
                    'date': [pr.last_jenkins_comment['created_at']],
                }
            d = {
                'parsed_title': pr.parsed_title,
                'number': pr.number,
                'updated_at': str(pr.updated_at),
                'user': pr.user,
                'state': pr.state,
                'components': pr.components,
                'lines_added': pr.lines_added,
                'lines_deleted': pr.lines_deleted,
                'lines_changed': pr.lines_changed,
                'is_mergeable': pr.is_mergeable,
                'commenters': [{'username': u, 'data': d} for (u, d) in pr.commenters],
                'last_jenkins_outcome': pr.last_jenkins_outcome,
                'last_jenkins_comment': last_jenkins_comment_dict,
            }
            # Use the first JIRA's information to populate the "Priority" and "Issue Type" columns:
            jiras = pr.parsed_title["jiras"]
            if jiras:
                first_jira = JIRAIssue.get_by_id("%s-%i" % (app.config['JIRA_PROJECT'], jiras[0]))
                if first_jira:
                    d['jira_priority_name'] = first_jira.priority_name
                    d['jira_priority_icon_url'] = first_jira.priority_icon_url
                    d['jira_issuetype_name'] = first_jira.issuetype_name
                    d['jira_issuetype_icon_url'] = first_jira.issuetype_icon_url
                    d['jira_shepherd_display_name'] = first_jira.shepherd_display_name
                # If a pull request is linked against multiple JIRA issues, then the target
                # versions should be union of the individual issues' target versions:
                target_versions = set()
                for jira_number in jiras:
                    jira = JIRAIssue.get_by_id("%s-%i" % (app.config['JIRA_PROJECT'], jira_number))
                    if jira:
                        target_versions.update(jira.target_versions)
                if target_versions:
                    d['jira_target_versions'] = natsorted(target_versions)
            json_dicts.append(d)
        except:
            logging.error("Exception while processing PR #%i", pr.number)
            raise
    response = Response(json.dumps(json_dicts), mimetype='application/json')
    return response
示例#14
0
def update_pr_comments(pr_number):
    pr = Issue.get(pr_number)
    comments_response = paginated_github_request(get_issues_base() +
                                                 '/%i/comments' % pr_number,
                                                 oauth_token=oauth_token)
    # TODO: after fixing #32, re-enable etags here: etag=self.comments_etag)
    if comments_response is None:
        return "Comments for PR %i are up-to-date" % pr_number
    else:
        pr.comments_json, pr.comments_etag = comments_response
        pr.cached_commenters = pr._compute_commenters()
        pr.cached_last_jenkins_outcome = None
        pr.last_jenkins_outcome  # force recomputation of Jenkins outcome
        pr.put()  # Write our modifications back to the database

        # Delete out-of-date comments from AmplabJenkins and SparkQA.
        jenkins_comment_to_preserve = pr.last_jenkins_comment
        sparkqa_token = app.config["SPARKQA_GITHUB_OAUTH_KEY"]
        amplabjenkins_token = app.config["AMPLAB_JENKINS_GITHUB_OAUTH_KEY"]
        sparkqa_start_comments = {}  # Map from build ID to build start comment
        build_start_regex = r"Test build #(\d+) has started"
        build_end_regex = r"Test build #(\d+) (has finished|timed out)"
        for comment in (pr.comments_json or []):
            author = comment["user"]["login"]
            # Delete all comments from AmplabJenkins unless they are the comments that should be
            # displayed on the Spark PR dashboard. If we do not know which comment to preserve, then
            # do not delete any comments from AmplabJenkins.
            if jenkins_comment_to_preserve \
                    and author == "AmplabJenkins" \
                    and comment["url"] != jenkins_comment_to_preserve["url"]:
                raw_github_request(comment["url"],
                                   oauth_token=amplabjenkins_token,
                                   method="DELETE")
            elif author == "SparkQA":
                # Only delete build start notification comments from SparkQA and only delete them
                # after we've seen the corresponding build finished message.
                start_regex_match = re.search(build_start_regex,
                                              comment["body"])
                if start_regex_match:
                    sparkqa_start_comments[start_regex_match.groups()
                                           [0]] = comment
                else:
                    end_regex_match = re.search(build_end_regex,
                                                comment["body"])
                    if end_regex_match:
                        start_comment = sparkqa_start_comments.get(
                            end_regex_match.groups()[0])
                        if start_comment:
                            raw_github_request(start_comment["url"],
                                               oauth_token=sparkqa_token,
                                               method="DELETE")
        return "Done updating comments for PR %i" % pr_number
示例#15
0
def build_response(template, max_age=60, **kwargs):
    navigation_bar = [
        # (href, id, label, badge_value)
        ('/', 'index', 'Open PRs', int(Issue.query(Issue.state == "open").count())),
    ]
    if g.user and "admin" in g.user.roles:
        navigation_bar.append(('/admin', 'admin', 'Admin', None))
    default_context = {
        'profiler_includes': profiler_includes(),
        'navigation_bar': navigation_bar,
        'user': g.user,
    }
    rendered = render_template(template, **(dict(default_context.items() + kwargs.items())))
    response = make_response(rendered)
    response.cache_control.max_age = max_age
    return response
示例#16
0
def build_response(template, max_age=60, **kwargs):
    navigation_bar = [
        # (href, id, label, badge_value)
        ('/', 'index', 'Open PRs',
         int(Issue.query(Issue.state == "open").count())),
    ]
    if g.user and "admin" in g.user.roles:
        navigation_bar.append(('/admin', 'admin', 'Admin', None))
    default_context = {
        'profiler_includes': profiler_includes(),
        'navigation_bar': navigation_bar,
        'user': g.user,
    }
    rendered = render_template(
        template, **(dict(default_context.items() + kwargs.items())))
    response = make_response(rendered)
    response.cache_control.max_age = max_age
    return response
示例#17
0
def update_pr_comments(pr_number):
    pr = Issue.get(pr_number)
    comments_response = paginated_github_request(get_issues_base() + '/%i/comments' % pr_number,
                                                 oauth_token=oauth_token)
    # TODO: after fixing #32, re-enable etags here: etag=self.comments_etag)
    if comments_response is None:
        return "Comments for PR %i are up-to-date" % pr_number
    else:
        pr.comments_json, pr.comments_etag = comments_response
        pr.cached_commenters = pr._compute_commenters()
        pr.cached_last_jenkins_outcome = None
        pr.last_jenkins_outcome  # force recomputation of Jenkins outcome
        pr.put()  # Write our modifications back to the database

        # Delete out-of-date comments from AmplabJenkins and SparkQA.
        jenkins_comment_to_preserve = pr.last_jenkins_comment
        sparkqa_token = app.config["SPARKQA_GITHUB_OAUTH_KEY"]
        amplabjenkins_token = app.config["AMPLAB_JENKINS_GITHUB_OAUTH_KEY"]
        sparkqa_start_comments = {}  # Map from build ID to build start comment
        build_start_regex = r"Test build #(\d+) has started"
        build_end_regex = r"Test build #(\d+) (has finished|timed out)"
        for comment in (pr.comments_json or []):
            author = comment["user"]["login"]
            # Delete all comments from AmplabJenkins unless they are the comments that should be
            # displayed on the Spark PR dashboard. If we do not know which comment to preserve, then
            # do not delete any comments from AmplabJenkins.
            if jenkins_comment_to_preserve \
                    and author == "AmplabJenkins" \
                    and comment["url"] != jenkins_comment_to_preserve["url"]:
                raw_github_request(comment["url"], oauth_token=amplabjenkins_token, method="DELETE")
            elif author == "SparkQA":
                # Only delete build start notification comments from SparkQA and only delete them
                # after we've seen the corresponding build finished message.
                start_regex_match = re.search(build_start_regex, comment["body"])
                if start_regex_match:
                    sparkqa_start_comments[start_regex_match.groups()[0]] = comment
                else:
                    end_regex_match = re.search(build_end_regex, comment["body"])
                    if end_regex_match:
                        start_comment = sparkqa_start_comments.get(end_regex_match.groups()[0])
                        if start_comment:
                            raw_github_request(start_comment["url"], oauth_token=sparkqa_token,
                                               method="DELETE")
        return "Done updating comments for PR %i" % pr_number
示例#18
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    json_dicts = []
    for pr in prs:
        last_jenkins_comment_dict = None
        if pr.last_jenkins_comment:
            last_jenkins_comment_dict = {
                'body': pr.last_jenkins_comment['body'],
                'user': {
                    'login': pr.last_jenkins_comment['user']['login']
                },
                'html_url': pr.last_jenkins_comment['html_url'],
            }
        d = {
            'parsed_title': pr.parsed_title,
            'number': pr.number,
            'updated_at': str(pr.updated_at),
            'user': pr.user,
            'state': pr.state,
            'components': pr.components,
            'lines_added': pr.lines_added,
            'lines_deleted': pr.lines_deleted,
            'lines_changed': pr.lines_changed,
            'is_mergeable': pr.is_mergeable,
            'commenters': [{
                'username': u,
                'data': d
            } for (u, d) in pr.commenters],
            'last_jenkins_outcome': pr.last_jenkins_outcome,
            'last_jenkins_comment': last_jenkins_comment_dict,
        }
        # Use the first JIRA's information to populate the "Priority" and "Issue Type" columns:
        jiras = pr.parsed_title["jiras"]
        if jiras:
            first_jira = JIRAIssue.get_by_id("SPARK-%i" % jiras[0])
            if first_jira:
                d['jira_priority_name'] = first_jira.priority_name
                d['jira_priority_icon_url'] = first_jira.priority_icon_url
                d['jira_issuetype_name'] = first_jira.issuetype_name
                d['jira_issuetype_icon_url'] = first_jira.issuetype_icon_url
        json_dicts.append(d)
    response = Response(json.dumps(json_dicts), mimetype='application/json')
    return response
示例#19
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    json_dicts = []
    for pr in prs:
        last_jenkins_comment_dict = None
        if pr.last_jenkins_comment:
            last_jenkins_comment_dict = {
                'body': pr.last_jenkins_comment['body'],
                'user': {'login': pr.last_jenkins_comment['user']['login']},
                'html_url': pr.last_jenkins_comment['html_url'],
                'date': [pr.last_jenkins_comment['created_at']],
            }
        d = {
            'parsed_title': pr.parsed_title,
            'number': pr.number,
            'updated_at': str(pr.updated_at),
            'user': pr.user,
            'state': pr.state,
            'components': pr.components,
            'lines_added': pr.lines_added,
            'lines_deleted': pr.lines_deleted,
            'lines_changed': pr.lines_changed,
            'is_mergeable': pr.is_mergeable,
            'commenters': [{'username': u, 'data': d} for (u, d) in pr.commenters],
            'last_jenkins_outcome': pr.last_jenkins_outcome,
            'last_jenkins_comment': last_jenkins_comment_dict,
        }
        # Use the first JIRA's information to populate the "Priority" and "Issue Type" columns:
        jiras = pr.parsed_title["jiras"]
        if jiras:
            first_jira = JIRAIssue.get_by_id("SPARK-%i" % jiras[0])
            if first_jira:
                d['jira_priority_name'] = first_jira.priority_name
                d['jira_priority_icon_url'] = first_jira.priority_icon_url
                d['jira_issuetype_name'] = first_jira.issuetype_name
                d['jira_issuetype_icon_url'] = first_jira.issuetype_icon_url
                d['jira_shepherd_display_name'] = first_jira.shepherd_display_name
        json_dicts.append(d)
    response = Response(json.dumps(json_dicts), mimetype='application/json')
    return response
示例#20
0
def test_pr(number):
    """
    Triggers a parametrized Jenkins build for testing Spark pull requests.
    """
    if not (g.user and g.user.has_capability("jenkins")):
        return abort(403)
    pr = Issue.get_or_create(number)
    commit = pr.pr_json["head"]["sha"]
    target_branch = pr.pr_json["base"]["ref"]
    # The parameter names here were chosen to match the ones used by Jenkins' GitHub pull request
    # builder plugin: https://wiki.jenkins-ci.org/display/JENKINS/Github+pull+request+builder+plugin
    # In the Spark repo, the https://github.com/apache/spark/blob/master/dev/run-tests-jenkins
    # script reads these variables when posting pull request feedback.
    query = {
        'token': app.config['JENKINS_PRB_TOKEN'],
        'ghprbPullId': number,
        'ghprbActualCommit': commit,
        'ghprbTargetBranch': target_branch,
        'ghprbPullTitle': pr.raw_title,
        # This matches the Jenkins plugin's logic; see
        # https://github.com/jenkinsci/ghprb-plugin/blob/master/src/main/java/org/jenkinsci/plugins/ghprb/GhprbTrigger.java#L146
        #
        # It looks like origin/pr/*/merge ref points to the last successful test merge commit that
        # GitHub generates when it checks for mergeability.  This API technically isn't documented,
        # but enough plugins seem to rely on it that it seems unlikely to change anytime soon
        # (if it does, we can always upgrade our tests to perform the merge ourselves).
        #
        # See also: https://developer.github.com/changes/2013-04-25-deprecating-merge-commit-sha/
        'sha1': ("origin/pr/%i/merge" % number) if pr.is_mergeable else commit,
    }
    trigger_url = "%sbuildWithParameters?%s" % (
        app.config["JENKINS_PRB_JOB_URL"], urllib.urlencode(query))
    logging.debug("Triggering Jenkins with url %s" % trigger_url)
    response = urlfetch.fetch(trigger_url, method="POST")
    if response.status_code not in (200, 201):
        logging.error("Jenkins responded with status code %i" %
                      response.status_code)
        return response.content
    else:
        return redirect(app.config["JENKINS_PRB_JOB_URL"])
示例#21
0
def test_pr(number):
    """
    Triggers a parametrized Jenkins build for testing Spark pull requests.
    """
    if not (g.user and g.user.has_capability("jenkins")):
        return abort(403)
    pr = Issue.get_or_create(number)
    commit = pr.pr_json["head"]["sha"]
    target_branch = pr.pr_json["base"]["ref"]
    # The parameter names here were chosen to match the ones used by Jenkins' GitHub pull request
    # builder plugin: https://wiki.jenkins-ci.org/display/JENKINS/Github+pull+request+builder+plugin
    # In the Spark repo, the https://github.com/apache/spark/blob/master/dev/run-tests-jenkins
    # script reads these variables when posting pull request feedback.
    query = {
        'token': app.config['JENKINS_PRB_TOKEN'],
        'ghprbPullId': number,
        'ghprbActualCommit': commit,
        'ghprbTargetBranch': target_branch,
        'ghprbPullTitle': pr.raw_title.encode('utf-8'),
        # This matches the Jenkins plugin's logic; see
        # https://github.com/jenkinsci/ghprb-plugin/blob/master/src/main/java/org/jenkinsci/plugins/ghprb/GhprbTrigger.java#L146
        #
        # It looks like origin/pr/*/merge ref points to the last successful test merge commit that
        # GitHub generates when it checks for mergeability.  This API technically isn't documented,
        # but enough plugins seem to rely on it that it seems unlikely to change anytime soon
        # (if it does, we can always upgrade our tests to perform the merge ourselves).
        #
        # See also: https://developer.github.com/changes/2013-04-25-deprecating-merge-commit-sha/
        'sha1': ("origin/pr/%i/merge" % number) if pr.is_mergeable else commit,
    }
    trigger_url = "%sbuildWithParameters?%s" % (app.config["JENKINS_PRB_JOB_URL"],
                                                urllib.urlencode(query))
    logging.debug("Triggering Jenkins with url %s" % trigger_url)
    response = urlfetch.fetch(trigger_url, method="POST")
    if response.status_code not in (200, 201):
        logging.error("Jenkins responded with status code %i" % response.status_code)
        return response.content
    else:
        return redirect(app.config["JENKINS_PRB_JOB_URL"])
示例#22
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    json_dicts = []
    for pr in prs:
        last_jenkins_comment_dict = None
        if pr.last_jenkins_comment:
            last_jenkins_comment_dict = {
                "body": pr.last_jenkins_comment["body"],
                "user": {"login": pr.last_jenkins_comment["user"]["login"]},
                "html_url": pr.last_jenkins_comment["html_url"],
            }
        d = {
            "parsed_title": pr.parsed_title,
            "number": pr.number,
            "updated_at": str(pr.updated_at),
            "user": pr.user,
            "state": pr.state,
            "components": pr.components,
            "lines_added": pr.lines_added,
            "lines_deleted": pr.lines_deleted,
            "lines_changed": pr.lines_changed,
            "is_mergeable": pr.is_mergeable,
            "commenters": [{"username": u, "data": d} for (u, d) in pr.commenters],
            "last_jenkins_outcome": pr.last_jenkins_outcome,
            "last_jenkins_comment": last_jenkins_comment_dict,
        }
        # Use the first JIRA's information to populate the "Priority" and "Issue Type" columns:
        jiras = pr.parsed_title["jiras"]
        if jiras:
            first_jira = JIRAIssue.get_by_id("SPARK-%i" % jiras[0])
            if first_jira:
                d["jira_priority_name"] = first_jira.priority_name
                d["jira_priority_icon_url"] = first_jira.priority_icon_url
                d["jira_issuetype_name"] = first_jira.issuetype_name
                d["jira_issuetype_icon_url"] = first_jira.issuetype_icon_url
                d["jira_shepherd_display_name"] = first_jira.shepherd_display_name
        json_dicts.append(d)
    response = Response(json.dumps(json_dicts), mimetype="application/json")
    return response
示例#23
0
def update_pr(number):
    Issue.get_or_create(number).update(app.config['GITHUB_OAUTH_KEY'])
    return "Done updating pull request %i" % number
示例#24
0
def users(username):
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    prs_authored = [p for p in prs if p.user == username]
    prs_commented_on = [p for p in prs if username in dict(p.commenters) and p.user != username]
    return build_response('user.html', username=username, prs_authored=prs_authored,
                          prs_commented_on=prs_commented_on)
示例#25
0
def all_prs_json():
    offset = int(request.args.get('offset'))
    limit = 100
    prs = Issue.query(Issue.number > offset).order(Issue.number).fetch(limit)
    return build_pr_json_response(prs)
示例#26
0
def update_issue(number):
    Issue.get_or_create(number).update(app.config['GITHUB_OAUTH_KEY'])
    return "Done updating issue %i" % number
示例#27
0
def search_stale_prs():
    issueQuery = ndb.AND(Issue.state == "open",
                         Issue.updated_at < datetime.datetime.today() - datetime.timedelta(days=30))
    stalePrs = Issue.query(issueQuery).order(-Issue.updated_at).fetch()
    return search_prs(stalePrs)
示例#28
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    json_dicts = []
    for pr in prs:
        try:
            last_jenkins_comment_dict = None
            if pr.last_jenkins_comment:
                last_jenkins_comment_dict = {
                    'body': pr.last_jenkins_comment['body'],
                    'user': {
                        'login': pr.last_jenkins_comment['user']['login']
                    },
                    'html_url': pr.last_jenkins_comment['html_url'],
                    'date': [pr.last_jenkins_comment['created_at']],
                }
            d = {
                'parsed_title':
                pr.parsed_title,
                'number':
                pr.number,
                'updated_at':
                str(pr.updated_at),
                'user':
                pr.user,
                'state':
                pr.state,
                'components':
                pr.components,
                'lines_added':
                pr.lines_added,
                'lines_deleted':
                pr.lines_deleted,
                'lines_changed':
                pr.lines_changed,
                'is_mergeable':
                pr.is_mergeable,
                'commenters': [{
                    'username': u,
                    'data': d
                } for (u, d) in pr.commenters],
                'last_jenkins_outcome':
                pr.last_jenkins_outcome,
                'last_jenkins_comment':
                last_jenkins_comment_dict,
            }
            # Use the first JIRA's information to populate the "Priority" and "Issue Type" columns:
            jiras = pr.parsed_title["jiras"]
            if jiras:
                first_jira = JIRAIssue.get_by_id(
                    "%s-%i" % (app.config['JIRA_PROJECT'], jiras[0]))
                if first_jira:
                    d['jira_priority_name'] = first_jira.priority_name
                    d['jira_priority_icon_url'] = first_jira.priority_icon_url
                    d['jira_issuetype_name'] = first_jira.issuetype_name
                    d['jira_issuetype_icon_url'] = first_jira.issuetype_icon_url
                    d['jira_shepherd_display_name'] = first_jira.shepherd_display_name
                # If a pull request is linked against multiple JIRA issues, then the target
                # versions should be union of the individual issues' target versions:
                target_versions = set()
                for jira_number in jiras:
                    jira = JIRAIssue.get_by_id(
                        "%s-%i" % (app.config['JIRA_PROJECT'], jira_number))
                    if jira:
                        target_versions.update(jira.target_versions)
                if target_versions:
                    d['jira_target_versions'] = natsorted(target_versions)
            json_dicts.append(d)
        except:
            logging.error("Exception while processing PR #%i", pr.number)
            raise
    response = Response(json.dumps(json_dicts), mimetype='application/json')
    return response
示例#29
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    return search_prs(prs)
示例#30
0
def update_issue(number):
    Issue.get_or_create(number).update(app.config['GITHUB_OAUTH_KEY'])
    return "Done updating issue %i" % number
示例#31
0
def search_open_prs():
    prs = Issue.query(Issue.state == "open").order(-Issue.updated_at).fetch()
    return search_prs(prs)
示例#32
0
def all_prs_json():
    offset = int(request.args.get('offset'))
    limit = 100
    prs = Issue.query(Issue.number > offset).order(Issue.number).fetch(limit)
    return build_pr_json_response(prs)
示例#33
0
def update_pr(number):
    Issue.get_or_create(number).update(app.config["GITHUB_OAUTH_KEY"])
    return "Done updating pull request %i" % number
示例#34
0
def search_stale_prs():
    issueQuery = ndb.AND(
        Issue.state == "open", Issue.updated_at <
        datetime.datetime.today() - datetime.timedelta(days=30))
    stalePrs = Issue.query(issueQuery).order(-Issue.updated_at).fetch()
    return search_prs(stalePrs)
示例#35
0
def refresh_all_prs():
    prs = Issue.query(Issue.state == "open")
    for pr in prs:
        taskqueue.add(url=url_for(".update_pr", pr_number=pr.number), queue_name='old-prs')
    return "Enqueued tasks to refresh all open PRs"