Beispiel #1
0
def get_installation_id_from_github_repository(github_repository_id):
    # Get repository ID that references the github ID.
    try:
        repository = Repository().get_repository_by_external_id(github_repository_id, 'github')
    except DoesNotExist:
        return None

    # Get Organization from this repository
    organization = GitHubOrg()
    try:
        organization.load(repository.get_repository_organization_name())
    except DoesNotExist:
        return None

    # Get this organization's installation ID
    return organization.get_organization_installation_id()
Beispiel #2
0
def get_github_repositories_by_org(project):
    """
    Gets organization with the project_id specified and all its repositories from Github API

    :param project: The Project object
    :type project: Project
    :return: [] of organizations and its repositories
    [{
        'organization_name': ..
        ...
        'repositories': [{
            'repository_github_id': ''
            'repository_name': ''
            'repository_type': ''
            'repository_url': ''
        }]
    }]
    :rtype: array
    """

    organization_dicts = []
    # Get all organizations connected to this project
    cla.log.info("Retrieving GH organization details using ID: {}".format(project.get_project_external_id))
    github_organizations = GitHubOrg().get_organization_by_sfid(project.get_project_external_id())
    cla.log.info("Retrieved {} GH organizations using ID: {}".format(
        len(github_organizations), project.get_project_external_id))

    # Iterate over each organization
    for github_organization in github_organizations:
        installation_id = github_organization.get_organization_installation_id()
        # Verify installation_id exist
        if installation_id is not None:
            try:
                installation = GitHubInstallation(installation_id)
                # Prepare organization in dict
                organization_dict = github_organization.to_dict()
                organization_dict['repositories'] = []
                # Get repositories from Github API
                github_repos = installation.repos

                cla.log.info("Retrieved {} repositories using GH installation id: {}".format(
                    github_repos, installation_id))
                if github_repos is not None:
                    for repo in github_repos:
                        # Convert repository entities from lib to a dict.
                        repo_dict = {
                            'repository_github_id': repo.id,
                            'repository_name': repo.full_name,
                            'repository_type': 'github',
                            'repository_url': repo.html_url
                        }
                        # Add repository to organization repositories list
                        organization_dict['repositories'].append(repo_dict)
                # Add organization dict to list
                organization_dicts.append(organization_dict)
            except Exception as e:
                cla.log.warning('Error connecting to Github to fetch repository details, error: {}'.format(e))
    return organization_dicts
Beispiel #3
0
def get_github_repositories_by_org(project):
    """
    Gets organization with the project_id specified and all its repositories from Github API

    :param project: The Project object
    :type project: Project
    :return: [] of organizations and its repositories
    [{
        'organization_name': ..
        ...
        'repositories': [{
            'repository_github_id': ''
            'repository_name': ''
            'repository_type': ''
            'repository_url': ''
        }]
    }]
    :rtype: array
    """

    organization_dicts = []
    # Get all organizations connected to this project
    github_organizations = GitHubOrg().get_organization_by_sfid(
        project.get_project_external_id())
    # Iterate over each organization
    for github_organization in github_organizations:
        installation_id = github_organization.get_organization_installation_id(
        )
        # Verify installation_id exist
        if installation_id is not None:
            installation = GitHubInstallation(installation_id)
            # Prepare organization in dict
            organization_dict = github_organization.to_dict()
            organization_dict['repositories'] = []
            # Get repositories from Github API
            github_repos = installation.repos
            if github_repos is not None:
                for repo in github_repos:
                    # Convert repository entities from lib to a dict.
                    repo_dict = {
                        'repository_github_id': repo.id,
                        'repository_name': repo.full_name,
                        'repository_type': 'github',
                        'repository_url': repo.html_url
                    }
                    # Add repository to organization repositories list
                    organization_dict['repositories'].append(repo_dict)
            # Add organization dict to list
            organization_dicts.append(organization_dict)
    return organization_dicts
Beispiel #4
0
def get_github_repositories_by_org(project):
    """
    Gets organization with the project_id specified and all its repositories from Github API

    :param project: The Project object
    :type project: Project
    :return: [] of organizations and its repositories
    [{
        'organization_name': ..
        ...
        'repositories': [{
            'repository_github_id': ''
            'repository_name': ''
            'repository_type': ''
            'repository_url': ''
            'enabled': ''
        }]
    }]
    :rtype: array
    """

    organization_dicts = []
    # Get all organizations connected to this project
    cla.log.info(
        f'Retrieving GH organization details using ID: {project.get_project_external_id()}'
    )
    github_organizations = GitHubOrg().get_organization_by_sfid(
        project.get_project_external_id())
    cla.log.info(
        f'Retrieved {len(github_organizations)} '
        f'GH organizations using ID: {project.get_project_external_id()}')
    repository_instance = cla.utils.get_repository_instance()

    # Iterate over each organization
    for github_organization in github_organizations:
        installation_id = github_organization.get_organization_installation_id(
        )
        # Verify installation_id exist
        if installation_id is not None:
            try:
                installation = GitHubInstallation(installation_id)
                # Prepare organization in dict
                organization_dict = github_organization.to_dict()
                organization_dict['repositories'] = []
                # Get repositories from Github API
                github_repos = installation.repos

                cla.log.info(
                    f'Retrieved {github_repos} repositories using GH installation id: {installation_id}'
                )
                if github_repos is not None:
                    for repo in github_repos:
                        # enabled flag checks whether repo has been added or removed from org
                        enabled = False
                        record_repo = repository_instance.get_repository_by_external_id(
                            repo.id, "github")
                        if record_repo:
                            enabled = record_repo.get_enabled()
                        # Convert repository entities from lib to a dict.
                        repo_dict = {
                            'repository_github_id': repo.id,
                            'repository_name': repo.full_name,
                            'repository_type': 'github',
                            'repository_url': repo.html_url,
                            'enabled': enabled,
                        }
                        # Add repository to organization repositories list
                        organization_dict['repositories'].append(repo_dict)
                # Add organization dict to list
                organization_dicts.append(organization_dict)
            except Exception as e:
                cla.log.warning(
                    'Error connecting to Github to fetch repository details, error: {}'
                    .format(e))
    return organization_dicts
Beispiel #5
0
    def update_change_request(self, installation_id, github_repository_id,
                              change_request_id):
        # Queries GH for the complete pull request details, see:
        # https://developer.github.com/v3/pulls/#response-1
        pull_request = self.get_pull_request(github_repository_id,
                                             change_request_id,
                                             installation_id)
        cla.log.debug(f'Retrieved pull request: {pull_request}')

        # Get all unique users/authors involved in this PR - returns a list of
        # (commit_sha_string, (author_id, author_username, author_email) tuples
        commit_authors = get_pull_request_commit_authors(pull_request)

        try:
            # Get existing repository info using the repository's external ID,
            # which is the repository ID assigned by github.
            cla.log.debug(
                f'PR: {pull_request.number}, Loading GitHub repository by id: {github_repository_id}'
            )
            repository = Repository().get_repository_by_external_id(
                github_repository_id, "github")
            if repository is None:
                cla.log.warning(
                    f'PR: {pull_request.number}, Failed to load GitHub repository by '
                    f'id: {github_repository_id} in our DB - repository reference is None - '
                    'Is this org/repo configured in the Project Console?'
                    ' Unable to update status.')
                return
        except DoesNotExist:
            cla.log.warning(
                f'PR: {pull_request.number}, could not find repository with the '
                f'repository ID: {github_repository_id}')
            cla.log.warning(
                f'PR: {pull_request.number}, failed to update change request of '
                f'repository {github_repository_id} - returning')
            return

        # Get Github Organization name that the repository is configured to.
        organization_name = repository.get_repository_organization_name()
        cla.log.debug('PR: {}, determined github organization is: {}'.format(
            pull_request.number, organization_name))

        # Check that the Github Organization exists.
        github_org = GitHubOrg()
        try:
            github_org.load(organization_name)
        except DoesNotExist:
            cla.log.warning(
                'PR: {}, Could not find Github Organization with the following organization name: {}'
                .format(pull_request.number, organization_name))
            cla.log.warning(
                'PR: {}, Failed to update change request of repository {} - returning'
                .format(pull_request.number, github_repository_id))
            return

            # Ensure that installation ID for this organization matches the given installation ID
        if github_org.get_organization_installation_id() != installation_id:
            cla.log.warning(
                'PR: {}, the installation ID: {} of this organization does not match '
                'installation ID: {} given by the pull request.'.format(
                    pull_request.number,
                    github_org.get_organization_installation_id(),
                    installation_id))
            cla.log.error(
                'PR: {}, Failed to update change request of repository {} - returning'
                .format(pull_request.number, github_repository_id))
            return

        # Retrieve project ID from the repository.
        project_id = repository.get_repository_project_id()

        # Find users who have signed and who have not signed.
        signed = []
        missing = []

        cla.log.debug(
            f'PR: {pull_request.number}, scanning users - determining who has signed a CLA an who has not.'
        )
        for commit_sha, author_info in commit_authors:
            # Extract the author info tuple details
            author_id = author_info[0]
            author_username = author_info[1]
            author_email = author_info[2]
            cla.log.debug(
                'PR: {}, processing sha: {} from author id: {}, username: {}, email: {}'
                .format(pull_request.number, commit_sha, author_id,
                        author_username, author_email))
            handle_commit_from_user(project_id, commit_sha, author_info,
                                    signed, missing)

        cla.log.debug(
            'PR: {}, updating github pull request for repo: {}, '
            'with signed authors: {} with missing authors: {}'.format(
                pull_request.number, github_repository_id, signed, missing))
        update_pull_request(installation_id,
                            github_repository_id,
                            pull_request,
                            signed=signed,
                            missing=missing)
Beispiel #6
0
def create_repository(auth_user: AuthUser, # pylint: disable=too-many-arguments
                      repository_project_id,
                      repository_name,
                      repository_organization_name, 
                      repository_type,
                      repository_url,
                      repository_external_id=None):
    """
    Creates a repository and returns the newly created repository in dict format.

    :param repository_project_id: The ID of the repository project.
    :type repository_project_id: string
    :param repository_name: The new repository name.
    :type repository_name: string
    :param repository_type: The new repository type ('github', 'gerrit', etc).
    :type repository_organization_name: string
    :param repository_organization_name: The repository organization name
    :type repository_type: string
    :param repository_url: The new repository URL.
    :type repository_url: string
    :param repository_external_id: The ID of the repository from the repository provider.
    :type repository_external_id: string
    :return: dict representation of the new repository object.
    :rtype: dict
    """

    # Check that organization exists 
    github_organization = GitHubOrg()
    try:
        github_organization.load(str(repository_organization_name))
    except DoesNotExist as err:
        return {'errors': {'organization_name': str(err)}}

    # Check that project is valid. 
    project = Project()
    try:
        project.load(str(repository_project_id))
    except DoesNotExist as err:
        return {'errors': {'repository_project_id': str(err)}}

    # Get SFDC project identifier
    sfdc_id = project.get_project_external_id()

    # Validate user is authorized for this project
    can_access = cla.controllers.project.check_user_authorization(auth_user, sfdc_id)
    if not can_access['valid']:
      return can_access['errors']

    # Validate if exist already repository linked to a contract group
    if repository_external_id is not None:
        # Seach for the repository
        linked_repository = Repository().get_repository_by_external_id(repository_external_id, repository_type)
        # If found return an error
        if linked_repository is not None:
            return {'errors': {'repository_external_id': 'This repository is alredy configured for a contract group.'}}

    repository = Repository()
    repository.set_repository_id(str(uuid.uuid4()))
    repository.set_repository_project_id(str(repository_project_id))
    repository.set_repository_sfdc_id(str(sfdc_id))
    repository.set_repository_name(repository_name)
    repository.set_repository_organization_name(repository_organization_name)
    repository.set_repository_type(repository_type)
    repository.set_repository_url(repository_url)
    if repository_external_id is not None:
        repository.set_repository_external_id(repository_external_id)
    repository.save()
    return repository.to_dict()
    def update_change_request(self, installation_id, github_repository_id,
                              change_request_id):
        pull_request = self.get_pull_request(github_repository_id,
                                             change_request_id,
                                             installation_id)
        # Get all unique users involved in this PR.
        commit_authors = get_pull_request_commit_authors(pull_request)
        # Get existing repository info using the repository's external ID, which is the repository ID assigned by github.

        try:
            repository = Repository().get_repository_by_external_id(
                github_repository_id, "github")
        except DoesNotExist:
            cla.log.error(
                'Could not find repository with the repository ID: %s',
                github_repository_id)
            cla.log.error(
                'Failed to update change request %s of repository %s',
                change_request_id, github_repository_id)
            return

        # Get Github Organization name that the repository is configured to.
        organization_name = repository.get_repository_organization_name()

        # Check that the Github Organization exists.
        github_org = GitHubOrg()
        try:
            github_org.load(organization_name)
        except DoesNotExist:
            cla.log.error(
                'Could not find Github Organization with the following organization name: %s',
                organization_name)
            cla.log.error(
                'Failed to update change request %s of repository %s',
                change_request_id, github_repository_id)
            return

        # Ensure that installation ID for this organization matches the given installation ID
        if github_org.get_organization_installation_id() != installation_id:
            cla.log.error(
                'The installation ID: %s of this organization does not match installation ID: %s given by the pull request.',
                github_org.get_organization_installation_id(), installation_id)
            cla.log.error(
                'Failed to update change request %s of repository %s',
                change_request_id, github_repository_id)
            return

        # Retrieve project ID from the repository.
        project_id = repository.get_repository_project_id()

        # Find users who have signed and who have not signed.
        signed = []
        missing = []
        for commit, commit_author in commit_authors:
            # cla.log.info("Author: " + commit_author)
            if isinstance(commit_author, github.NamedUser.NamedUser):
                # Handle GitHub user.
                cla.log.info("Handle GitHub user")
                handle_commit_from_github_user(project_id, commit,
                                               commit_author, signed, missing)
            elif isinstance(commit_author, github.GitAuthor.GitAuthor):
                # Handle non-github user (just email and name in commit).
                cla.log.info(
                    "Handle non-github user (just email and name in commit)")
                handle_commit_from_git_author(project_id, commit,
                                              commit_author, signed, missing)
            else:
                # Couldn't find any author information.
                cla.log.info("Couldn't find any author information.")
                if commit_author is not None:
                    missing.append((commit.sha, commit_author))
                else:
                    missing.append((commit.sha, None))

        update_pull_request(installation_id,
                            github_repository_id,
                            pull_request,
                            signed=signed,
                            missing=missing)