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()
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
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
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
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)
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)