def __init__(self, config, token_env_var, url='https://api.github.com', users=[], orgs=[], blacklist_repos=[], whitelist_repos=[], blacklist_orgs=[]): self._conf = config self._token_env_var = token_env_var self._token = os.environ[self._token_env_var] self._url = url self._users = users self._orgs = orgs self._blacklist_repos = blacklist_repos self._whitelist_repos = whitelist_repos self._blacklist_orgs = blacklist_orgs if self._url == 'https://api.github.com': self._gh = login(token=self._token) else: self._gh = enterprise_login(url=self._url, token=self._token) self._current_user = self._gh.me() self._login = self._current_user.login logger.info('Authenticated to %s as user %s', self._url, self._login)
def get_github_api(username, password): gh = enterprise_login(url="https://git.uncc.edu", username=username, password=password) gh.session.mount("http://", adapter) gh.session.mount("https://", adapter) return gh
def test_enterprise_login(self): """Show that github3.enterprise_login returns GitHubEnterprise.""" args = ('login', 'password', None, 'https://url.com/', None) with mock.patch.object(github3.GitHubEnterprise, 'login') as login: g = github3.enterprise_login(*args) assert isinstance(g, github3.GitHubEnterprise) login.assert_called_once_with('login', 'password', None, None)
def get_user(token, url="", verify=True): """Authenticate using a GitHub token and return the instance. Args: token (str): The GitHub authentication token that will be used to get user data. base_url (str, optional): The API URL that goes with the given `token`. If you're not using GitHub Enterprise, just leave this parameter blank. verify (bool, optional): If True, require a valid SSL certificate in private If networks. If False, accept all external SSL certificates. Default is True. Returns: :class:`github3.github.GitHub`: The found GitHub connection. """ if url: accessor = github3.enterprise_login(token=token, url=url) accessor.session.verify = verify return accessor return github3.login(token=token)
def test_enterprise_login(self): """Show that github3.enterprise_login returns GitHubEnterprise.""" args = ("login", "password", None, "https://url.com/", None) with unittest.mock.patch.object(github3.GitHubEnterprise, "login") as login: g = github3.enterprise_login(*args) assert isinstance(g, github3.GitHubEnterprise) login.assert_called_once_with("login", "password", None, None)
def _connect(): global git_client if not git_client: git_credentials = read_config() github_url, github_token = git_credentials[0] if github_url == 'github.com': git_client = login(token=github_token) else: git_client = enterprise_login(url=f'https://{github_url}', token=github_token) return git_client
def __init__(self, dryRun=False): self.logger = logging.getLogger(self.__class__.__name__) self.dryRun = dryRun self.repos = None self.gh = github3.enterprise_login( username=config.destination['username'], token=config.destination['apiKey'], url="https://{}".format(config.destination['host']) ) self.org = None self.teams = {} self.remoteRepos = {}
def _get_connection( self, github_config: cs.GhConnectionSettings ) -> Union[github3.GitHub, github3.GitHubEnterprise]: """Get Github connection, create one if does not exist.""" # GitHub Enterprise if github_config.hostname: base_url = f"https://{github_config.hostname}/api/v3" self.connection = github3.enterprise_login( url=base_url, token=github_config.access_token) # GitHub.com else: self.connection = github3.login(token=github_config.access_token) return self.connection
def _get_connection(self) -> Union[github3.GitHub, github3.GitHubEnterprise]: """Get Github connection, create one if does not exist.""" if hasattr(self, "connection"): return self.connection # GitHub Enterprise if self.config.hostname: base_url = f"https://{self.config.hostname}/api/v3" return github3.enterprise_login( url=base_url, token=self.config.access_token ) # GitHub.com else: return github3.login(token=self.config.access_token)
def create_enterprise_session(url, token=None): """ Create a github3.py session for a GitHub Enterprise instance If token is not provided, will attempt to use the GITHUB_API_TOKEN environment variable if present. """ gh_session = github3.enterprise_login(url=url, token=token) if gh_session is None: msg = 'Unable to connect to GitHub Enterprise (%s) with provided token.' raise RuntimeError(msg, url) return gh_session
def get_reviews(token, organization, pr_age, name_filter=''): reviews = collections.defaultdict(set) gh = github3.enterprise_login(token=token, url='https://github.rackspace.com') org = gh.organization(organization) repos = set() for team in (x for x in org.teams() if x.name.startswith(name_filter)): repos.update(team.repositories()) for repo in repos: for pull in (x for x in repo.pull_requests() if x.state == 'open'): assignees = {x.login for x in pull.assignees} if not assignees: continue secs_since_last_update = (NOW - pull.updated_at).total_seconds() # Check the assignee list and ensure it is not solely the author. In the case of # ambiguity, err on the side of caution and alert all parties involved. if {pull.user.login} != assignees and secs_since_last_update > pr_age: for assignee in assignees: reviews[assignee].add((pull.title, pull.html_url)) return reviews
def assign_pr(owner, repo, pr_number, users, token=None, keep_current=True): """ Assign PR to a user. Args: owner (str): name of user or org that owns the repo containing the PR repo (str): name of the repo containing the PR users (iterable): iterable of ssos for users to be assigned token (Optional[str]): token to authenticate to GitHub. If not provided, the `GH_TOKEN` environment variable will be checked. keep_current (bool): if True, leave current assignees in place, otherwise remove and assign *only* provided users. """ creds = _get_credentials(token=token) gh = github3.enterprise_login(url=GH_URL, **creds) repo = gh.repository(owner, repo) pr = repo.issue(pr_number) current_assignees = {u.login for u in pr.assignees} if keep_current else set() pr.edit(assignees=list(current_assignees.union(users)))
def make_github_client(profile): token = profile['token'] url = profile['url'] try: if url: client = github3.enterprise_login(token=token, url=url) else: client = github3.login(token=token) if client is None: raise (Exception()) except Exception as e: sys.stderr.write("\nError performing login to Github!\n") sys.stderr.write("Check the token or url for login of profile %s\n\n" % profile['name']) raise ( e ) ## Re-raise the exception to handle it somewhere else in the stack return client
def fetch_organization_pulls(organization_name): """ Returns a formatted string list of open pull request messages. """ client = enterprise_login(url=GITHUB_URL, token=GITHUB_API_TOKEN) organization = client.organization(organization_name) attachments = [] for repository in organization.repositories(): if REPOSITORIES and repository.name.lower() not in REPOSITORIES: continue unchecked_pulls = fetch_repository_pulls(repository) if unchecked_pulls: attachments.append([ '[{}/{}]'.format(organization_name, repository.name), repository.html_url, format_pull_requests(unchecked_pulls, organization_name, repository) ]) return attachments
def main(): args = parse_args() token = os.getenv('GITHUB_ACCESS_TOKEN') if not token: print( 'Please set the environment variable GITHUB_ACCESS_TOKEN to your git.corp token' ) sys.exit(1) if args.github_instance is None: gh = github3.login(token=token) else: gh = github3.enterprise_login(token=token, url=args.github_instance) user = gh.me() args.username = user.name args.email = user.email if args.username is None: print( 'Please set the username in your github profile to use this tool') sys.exit(1) if args.email is None: args.email = "*****@*****.**" if not args.no_dry_run: print("---\nDRY RUN ACTIVE! NO PUSH WILL BE DONE\n---") print('Repo: {}'.format(args.repository)) print('Command: {}'.format(args.command)) print('Changes will be commited as: {} <{}>'.format( args.username, args.email)) print('---') # get repo repo_org, repo_name = args.repository.split('/', 1) repo = gh.repository(repo_org, repo_name) # make temporary directory and fetch files, let user edit them temp_dir = tempfile.mkdtemp() def get_target_path(fn): return os.path.join(temp_dir, fn) try: before = fetch_files(repo, args.branch, get_target_path, args.files, args.ignore_missing) after = update_files(args.command, get_target_path, args.files, args) # change hash hash = hashlib.md5(json.dumps( after, sort_keys=True).encode('utf-8')).hexdigest() # get a branch with the change hash branch_name = "{}-{}".format(args.target_branch_prefix, hash) try: existing_branch = repo.branch(branch_name) except github3.exceptions.NotFoundError as e: existing_branch = None print("The hash of the changes are: {}".format(hash)) display_diff(before, after) has_changes = args.commit_empty for fn in args.files: if before[fn] == after[fn]: continue if after[fn] is None: has_changes = True break if args.ignore_whitespace_only_changes: if not has_whitespace_only_changes(before[fn], after[fn]): has_changes = True break else: has_changes = True break if has_changes and args.no_dry_run: tree_data, deleted_files = compute_changes(repo, get_target_path, args.files) commit = create_commit(repo, args.branch, tree_data, args.message, args.username, args.email) if args.no_pr: update_head_to_new_commit(repo, args.branch, commit) branch_name = args.branch elif args.allow_duplicates and existing_branch is not None: # There is already a branch with the same name, so use the time branch_name = '{}-{}'.format( args.branch, datetime.now().strftime('%Y%m%d%H%M%S')) create_branch(repo, branch_name, commit) elif not args.allow_duplicates and existing_branch is not None: error_message = "There is already a branch '{}'.\nAssuming there is a PR using this branch... Aborting".format( branch_name) raise RuntimeError(error_message) else: create_branch(repo, branch_name, commit) # slightly hacky way to delete files: calculating a tree in create_commit with removed files is non-trivial. do it in separate commits here for fn in deleted_files: file_content = repo.contents(fn, branch_name) if file_content is not None: repo.delete_file(fn, 'removed file {}'.format(fn), file_content.sha, branch_name, { 'name': args.username, 'email': args.email }, { 'name': args.username, 'email': args.email }) if not args.no_pr: pr_link = create_pull_request(repo, args.branch, branch_name, args.message, args.pull_request_message) print(pr_link) if args.append_pr_to_file is not None: with open(args.append_pr_to_file, "a") as prlogfile: prlogfile.write(pr_link + "\n") elif has_changes and not args.no_dry_run: print("---\nDRY RUN ACTIVE! NO PUSH WILL BE DONE\n---") finally: # cleanup shutil.rmtree(temp_dir, ignore_errors=True)
#!/usr/bin/env python3.7 # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import github3 import sys githubent = github3.enterprise_login( username=sys.argv[1], password=sys.argv[2], url=sys.argv[3]) for d in ["2014", "2015", "2016", "2017", "2018", "2019"]: dateFilter = "created:<"+d+" and created:>"+str(int(d)-1) for r in githubent.search_repositories("is:public and "+dateFilter): print(d+","+r.clone_url)