def main(args): print('\n\n' + 'Changing branch protection'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter ) num_fail = 0 for repo in repositories: try: branch = repo.get_branch(args.branch) if args.protect: branch.edit_protection( user_push_restrictions=[''] ) elif branch.protected: branch.remove_protection() else: pass print(f'{Fore.GREEN}Repo: {repo.full_name}') except Exception as e: print(f'{Fore.RED}Repo: {repo.full_name}') pprint.pprint(vars(repo)) print(f'{Fore.RED}{e}') num_fail += 1 print('\nSummary:') print(f'\tTotal number of repositories: {len(repositories)}') print(f'\tTotal number failed: {num_fail}') if num_fail > 0: raise Exception(f'{Fore.RED}Couldn\'t change branch protections')
def main(args): print('\n\n' + 'Creating student repositories'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) try: create_repo_from_template( token=args.token, template_repo_fullname=args.template_repo_fullname, org_name=args.org_name, repo_name=args.repo_name, description='Student repository', private=args.private) g = github.Github(login_or_token=args.token) repo = g.get_repo(full_name_or_id=f'{args.org_name}/{args.repo_name}') for col in args.admin_collaborators: repo.add_to_collaborators(col, permission='admin') for col in args.write_collaborators: repo.add_to_collaborators(col, permission='push') for team in g.get_organization(args.org_name).get_teams(): if team.name == args.team_name: team.set_repo_permission(repo=repo, permission='push') except Exception as e: print(e) repo_is_template.main([ '--token', args.token, '--repo_fullname', args.template_repo_fullname ])
def main(args): print('\n\n' + 'Verifying access to secrets'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) available_secrets = get_available_secrets(token=args.token, repo_fullname=args.repo_fullname) required_secrets, all_required_secrets = get_required_secrets( token=args.token, repo_fullname=args.repo_fullname) print(f'\n{Fore.GREEN}Repo {args.repo_fullname}\n' f'{Fore.GREEN}has access to:\n\t{Fore.GREEN}' + f'\n\t{Fore.GREEN}'.join(available_secrets)) missing = all_required_secrets.difference(available_secrets) if len(missing) > 0: print( f'\n{Fore.RED}Repo {args.repo_fullname}\n' f'{Fore.RED}doesn\'t have access to the following secrets:\n\t{Fore.RED}' + f'\n\t{Fore.RED}'.join(missing)) for path, secrets in required_secrets.items(): print(f'\nWorkflow {path}\nrequires access to:') for secret_ in secrets: if secret_ in available_secrets: print(f'{Fore.GREEN}\t{secret_}') else: print(f'{Fore.RED}\t{secret_}') print(Style.RESET_ALL) if len(missing) > 0: exit(1)
def main(args): print('\n\n' + 'Deleting workflow runs'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) g = github.Github(login_or_token=args.token) repo = g.get_repo(full_name_or_id=args.repo_fullname) workflow_dict = {} for run in repo.get_workflow_runs(): workflow_name = repo.get_workflow(id_or_name=str(run.raw_data['workflow_id'])).name workflow_dict.setdefault(workflow_name, []) workflow_dict[workflow_name].append(run) for workflow_name, runs in workflow_dict.items(): if len(runs) > 1: if args.delete_only_failed_runs: failed_runs = list( filter( lambda run: run.conclusion == 'failure' and run.status == 'completed', runs ), ) for run in failed_runs: if args.workflow_name_filter is not None: if args.workflow_name_filter in workflow_name: delete_workflow_run(run.url, args.token) else: runs.sort(key=lambda run: run.created_at, reverse=True) for run in runs[1:]: if args.workflow_name_filter is not None: if args.workflow_name_filter in workflow_name: delete_workflow_run(run.url, args.token) else: delete_workflow_run(run.url, args.token)
def main(args): print('\n\n' + 'Triggering workflows'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) num_success = 0 num_fail = 0 repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter ) print('Triggering workflows in repos:') for repo in repositories: success = repo.create_repository_dispatch(event_type=args.event_type) if success: num_success += 1 print(f'{Fore.GREEN}\t{repo.name}') else: num_fail += 1 print(f'{Fore.RED}\tFAILED {repo.name}') print('\nSummary:') print(f'\tNumber of successful repository_dispatch events: {num_success}') print(f'\tNumber of failed: {num_fail}') if num_fail != 0: raise Exception(f'{Fore.RED}Couldn\'t trigger all workflows')
def main(args): print('\n\n' + 'Deleting test repositories'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) delete_repos( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter )
def main(args): print('\n\n' + 'Changing access permissions'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter) apply_changes(repositories=repositories, new_permission=args.new_permission_level) confirm_changes(repositories=repositories, new_permission=args.new_permission_level)
def main(args): print('\n\n' + 'Deleting workflows'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter) for repo in repositories: print(f'Deleting workflows from repo: {repo.full_name}') deleted = github_utils.delete_all_workflows(repo, branch=args.branch) for path in deleted: print(f'\tRemoved: {path}') print('\nSummary:') print(f'\tTotal number of repositories updated: {len(repositories)}')
def main(args): print('\n\n' + 'Verifying that repo is a template'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) res = requests.get( url=f'https://api.github.com/repos/{args.repo_fullname}', headers={ 'Authorization': f'token {args.token}', 'Accept': 'application/vnd.github.baptiste-preview+json' }) is_template = json.JSONDecoder().decode(res.text)['is_template'] if is_template: print(f'{Fore.GREEN} Repo is a template: {args.repo_fullname}') else: raise Exception( f'{Fore.RED} Repo is not a template: {args.repo_fullname}')
def update_with_github_api(files_to_update, template_repo_fullname, token, org_name, repo_filter, branch): github_utils.verify_token(token) template_repo = github_utils.get_repo(fullname=template_repo_fullname, token=token) template_files = get_relevant_template_files( files_to_update=files_to_update, template_repo=template_repo) repositories = github_utils.get_students_repositories( token=token, org_name=org_name, repo_filter=repo_filter) print('Syncing repositories:') for repo in repositories: print(f'{Fore.GREEN}\t{repo.full_name}') for file in template_files: github_utils.copy_file_to_repo(file=file, repo=repo, branch=branch) print('\nSummary:') print(f'\tTotal number of repositories updated: {len(repositories)}')
def main(args): print('\n\n' + 'Verifying files_to_update.txt'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) g = github.Github(login_or_token=args.token) template_repo = g.get_repo(full_name_or_id=args.template_repo_fullname) file = template_repo.get_contents('settings/files_to_update.txt') paths_to_update = set(file.decoded_content.decode('utf-8').splitlines()) template_files = list( github_utils.get_files_from_repo(repo=template_repo, path='')) template_paths = set(map(lambda file: file.path, template_files)) print(f'From repository: {template_repo.full_name}') for path in paths_to_update.intersection(template_paths): print(f'{Fore.GREEN}\tFound: {path}') for path in template_paths.difference(paths_to_update): print(f'{Fore.YELLOW}\tNot included: {path}') for path in paths_to_update.difference(template_paths): print(f'{Fore.RED}\tMissing: {path}') raise Exception(f'{Fore.RED}Missing or incorrect paths')
def main(args): print('\n\n' + 'Creating test repositories'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) usernames = student_usernames(n=args.num_repos) try: for name in usernames: repo_name = f'{args.repo_filter}-{name}' create_repo_from_template( token=args.token, template_repo_fullname=args.template_repo_fullname, org_name=args.org_name, repo_name=repo_name, description='Repository for testing classroom features at scale', private=args.private ) except Exception as e: print(e) repo_is_template.main(['--token', args.token, '--repo_fullname', args.template_repo_fullname])
def main(args): print('\n\n' + 'Creating protected branches'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter) num_fail = 0 for repo in repositories: try: create_or_update_ref(repo=repo, branch_name=args.branch) add_push_restrictions(repo=repo, branch_name=args.branch) print(f'{Fore.GREEN}Repo: {repo.full_name}') except Exception as e: print(f'{Fore.RED}Repo: {repo.full_name}') pprint.pprint(vars(repo)) print(f'{Fore.RED}{e}') num_fail += 1 print('\nSummary:') print(f'\tTotal number of repositories: {len(repositories)}') print(f'\tTotal number failed: {num_fail}') if num_fail > 0: raise Exception(f'{Fore.RED}Couldn\'t create protected branches')
def main(args): print('\n\n' + 'Changing default protection'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter ) num_fail = 0 for repo in repositories: print(f'Repo: {repo.full_name}') try: set_default_branch(token=args.token, repo_full_name=repo.full_name, branch_name=args.branch) except Exception as e: print(e) num_fail += 1 print('\nSummary:') print(f'\tTotal number of repositories: {len(repositories)}') print(f'\tTotal number failed: {num_fail}') if num_fail > 0: raise Exception(f'{Fore.RED}Couldn\'t change default branches')
def main(args): print('\n\n' + 'Submitting files to Moss'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) moss = mosspy.Moss(args.user_id, language=args.l) moss.setIgnoreLimit(args.m) moss.setCommentString(args.c) moss.setNumberOfMatchingFiles(args.n) moss.setExperimentalServer(opt=int(args.x)) moss.setDirectoryMode(mode=int(args.d)) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter) if args.base_files_repo_fullname != '': repo = github_utils.get_repo(fullname=args.base_files_repo_fullname, token=args.token) add_base_files(moss=moss, base_files=args.paths, repo=repo) print(f'Org: {args.org_name}') add_paths(moss=moss, paths=args.paths, repositories=repositories) report_url = moss.send() print(f'Report url: {report_url}') save_report(moss=moss, report_name=args.report_name, report_url=report_url)
def main(args): print('\n\n' + 'Creating grading branches and pull requests'.center(80, '=')) args = parser.parse_args(args) print('Args:\n' + ''.join(f'\t{k}: {v}\n' for k, v in vars(args).items())) github_utils.verify_token(args.token) repositories = github_utils.get_students_repositories( token=args.token, org_name=args.org_name, repo_filter=args.repo_filter) num_fail = 0 for repo in repositories: try: create_or_update_ref(repo=repo, base=args.base) add_push_restrictions(repo=repo, base=args.base) print(f'{Fore.GREEN}Repo: {repo.full_name}') except Exception as e: print(f'{Fore.RED}Repo: {repo.full_name}') pprint.pprint(vars(repo)) print(f'{Fore.RED}{e}') num_fail += 1 try: repo.create_pull(title=args.pull_request_title, body=args.pull_request_body, base=args.base, head=args.head, maintainer_can_modify=False, draft=False) except Exception as e: print(f'\t{Fore.RED}Pull request already exists') for pull in repo.get_pulls(): print(f'\t{pull}') print(e) print('\nSummary:') print(f'\tTotal number of repositories: {len(repositories)}') print(f'\tTotal number failed: {num_fail}') if num_fail > 0: raise Exception(f'{Fore.RED}Couldn\'t create protected branches')