コード例 #1
0
def handle_msg(msg, suffix, config):
    """
    Function to handle incomming message from datagrepper
    :param Dict msg: Incoming message
    :param String suffix: Incoming suffix
    :param Dict config: Config dict
    """
    issue = None
    pr = None
    # Github '.issue.' is used for both PR and Issue
    # Check for that edge case
    if suffix == 'github.issue.comment':
        if 'pull_request' in msg['msg']['issue'] and msg['msg']['action'] != 'deleted':
            # pr_filter turns on/off the filtering of PRs
            pr = issue_handlers[suffix](msg, config, pr_filter=False)
            if not pr:
                return
            # Issues do not have suffix and reporter needs to be reformatted
            pr.suffix = suffix
            pr.reporter = pr.reporter.get('fullname')
            setattr(pr, 'match', matcher(pr.content, pr.comments))
        else:
            issue = issue_handlers[suffix](msg, config)
    elif suffix in issue_handlers:
        issue = issue_handlers[suffix](msg, config)
    elif suffix in pr_handlers:
        pr = pr_handlers[suffix](msg, config, suffix)

    if not issue and not pr:
        return
    if issue:
        d_issue.sync_with_jira(issue, config)
    elif pr:
        d_pr.sync_with_jira(pr, config)
コード例 #2
0
def initialize_pr(config, testing=False, repo_name=None):
    """
    Initial initialization needed to sync any upstream \
    repo with JIRA. Goes through all PRs and \
    checks if they're already on JIRA / Need to be \
    created.

    :param Dict config: Config dict for JIRA
    :param Bool testing: Flag to indicate if we are testing. Default false
    :param String repo_name: Optional individual repo name. If defined we will only sync the provided repo
    :returns: Nothing
    """
    log.info("Running initialization to sync all PRs from upstream to jira")
    log.info("Testing flag is %r", config['sync2jira']['testing'])
    mapping = config['sync2jira']['map']
    for upstream in mapping.get('pagure', {}).keys():
        if 'pullrequest' not in mapping.get('pagure', {}).get(upstream, {}).get('sync', []):
            continue
        if repo_name is not None and upstream != repo_name:
            continue
        for pr in u_pr.pagure_prs(upstream, config):
            if pr:
                d_pr.sync_with_jira(pr, config)
    log.info("Done with pagure PR initialization.")

    for upstream in mapping.get('github', {}).keys():
        if 'pullrequest' not in mapping.get('github', {}).get(upstream, {}).get('sync', []):
            continue
        if repo_name is not None and upstream != repo_name:
            continue
        # Try and except for github API limit
        try:
            for pr in u_pr.github_prs(upstream, config):
                try:
                    if pr:
                        d_pr.sync_with_jira(pr, config)
                except Exception:
                    log.error("   Failed on %r", pr)
                    raise
        except Exception as e:
            if "API rate limit exceeded" in e.__str__():
                # If we've hit out API limit:
                # Sleep for 1 hour and call our function again
                log.info("Hit Github API limit. Sleeping for 1 hour...")
                sleep(3600)
                if not testing:
                    initialize_pr(config)
                return
            else:
                if not config['sync2jira']['develop']:
                    # Only send the failure email if we are not developing
                    report_failure(config)
                    raise
    log.info("Done with github PR initialization.")
コード例 #3
0
def listen(config):
    """
    Listens to activity on upstream repos on pagure and github \
    via fedmsg, and syncs new issues there to the JIRA instance \
    defined in 'fedmsg.d/sync2jira.py'

    :param Dict config: Config dict
    :returns: Nothing
    """
    if not config['sync2jira'].get('listen'):
        log.info("`listen` is disabled.  Exiting.")
        return

    log.info("Waiting for a relevant fedmsg message to arrive...")
    for _, _, topic, msg in fedmsg.tail_messages(**config):
        idx = msg['msg_id']
        suffix = ".".join(topic.split('.')[3:])
        log.debug("Encountered %r %r %r", suffix, topic, idx)

        if suffix not in issue_handlers and suffix not in pr_handlers:
            continue

        log.debug("Handling %r %r %r", suffix, topic, idx)

        issue = None
        pr = None
        # Github '.issue.' is used for both PR and Issue
        # Check for that edge case
        if suffix == 'github.issue.comment':
            if 'pull_request' in msg['msg'][
                    'issue'] and msg['msg']['action'] != 'deleted':
                # pr_filter turns on/off the filtering of PRs
                pr = issue_handlers[suffix](msg, config, pr_filter=False)
                if not pr:
                    continue
                # Issues do not have suffix and reporter needs to be reformatted
                pr.suffix = suffix
                pr.reporter = pr.reporter.get('fullname')
                setattr(pr, 'match', matcher(pr.content, pr.comments))
            else:
                issue = issue_handlers[suffix](msg, config)
        elif suffix in issue_handlers:
            issue = issue_handlers[suffix](msg, config)
        elif suffix in pr_handlers:
            pr = pr_handlers[suffix](msg, config, suffix)

        if not issue and not pr:
            continue
        if issue:
            d_issue.sync_with_jira(issue, config)
        elif pr:
            d_pr.sync_with_jira(pr, config)
コード例 #4
0
def handle_message(config, incoming_json):
    # Constantly refresh the config file when we handle a new message
    config = load_config()

    # Ensure we are only dealing with one issue at a time, get our lock
    with lock:
        if ('pull_request' in incoming_json.keys()):
            pr = u_pr.handle_github_message(config, incoming_json)
            if pr:
                d_pr.sync_with_jira(pr, config)
        elif ('issue' in incoming_json.keys()
              and '/pull/' not in incoming_json['issue']['html_url']):
            issue = u_issue.handle_github_message(config, incoming_json)
            if issue:
                d_issue.sync_with_jira(issue, config)
コード例 #5
0
    def test_sync_with_jira_no_issues_found(self, mock_d_issue,
                                            mock_update_jira_issue):
        """
        This function tests 'sync_with_jira' where no issues are found
        """
        # Set up return values
        self.mock_client.search_issues.return_value = []
        mock_d_issue.get_jira_client.return_value = self.mock_client

        # Call the function
        d.sync_with_jira(self.mock_pr, self.mock_config)

        # Assert everything was called correctly
        mock_update_jira_issue.assert_not_called()
        self.mock_client.search_issues.assert_called_with('Key = JIRA-1234')
        mock_d_issue.get_jira_client.assert_called_with(
            self.mock_pr, self.mock_config)
コード例 #6
0
    def test_sync_with_jira(self, mock_d_issue, mock_update_jira_issue):
        """
        This function tests 'sync_with_jira'
        """
        # Set up return values
        mock_d_issue.get_jira_client.return_value = self.mock_client

        # Call the function
        d.sync_with_jira(self.mock_pr, self.mock_config)

        # Assert everything was called correctly
        mock_update_jira_issue.assert_called_with('mock_existing',
                                                  self.mock_pr,
                                                  self.mock_client)
        self.mock_client.search_issues.assert_called_with('Key = JIRA-1234')
        mock_d_issue.get_jira_client.assert_called_with(
            self.mock_pr, self.mock_config)
コード例 #7
0
    def test_sync_with_jira_testing(self, mock_d_issue,
                                    mock_update_jira_issue):
        """
        This function tests 'sync_with_jira' where no issues are found
        """
        # Set up return values
        mock_client = MagicMock()
        mock_client.search_issues.return_value = []
        self.mock_config['sync2jira']['testing'] = True
        mock_d_issue.get_jira_client.return_value = mock_client

        # Call the function
        d.sync_with_jira(self.mock_pr, self.mock_config)

        # Assert everything was called correctly
        mock_update_jira_issue.assert_not_called()
        mock_client.search_issues.assert_not_called()
        mock_d_issue.get_jira_client.assert_not_called()
    def test_sync_with_jira_merged(self, mock_update_transition, mock_d_issue,
                                   mock_update_jira_issue):
        """
        This function tests 'sync_with_jira'
        """
        # Set up return values
        mock_client = MagicMock()
        mock_client.search_issues.return_value = ['mock_existing']
        mock_d_issue.get_jira_client.return_value = mock_client
        self.mock_pr.suffix = 'merged'

        # Call the function
        d.sync_with_jira(self.mock_pr, self.mock_config)

        # Assert everything was called correctly
        mock_update_jira_issue.assert_called_with('mock_existing',
                                                  self.mock_pr, mock_client)
        mock_client.search_issues.assert_called_with('Key = JIRA-1234')
        mock_d_issue.get_jira_client.assert_called_with(
            self.mock_pr, self.mock_config)
        mock_update_transition.mock.asset_called_with(mock_client,
                                                      'mock_existing',
                                                      self.mock_pr,
                                                      'merged_transition')