Skip to content

Instantly share code, notes, and snippets.

@shilad
Created September 14, 2019 15:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shilad/0049badb5f6daad6977a4f2759684db8 to your computer and use it in GitHub Desktop.
Save shilad/0049badb5f6daad6977a4f2759684db8 to your computer and use it in GitHub Desktop.
Python script to create grading pull requests. Requires Python3 and PyGithub.
#!/usr/bin/env python3 -O
#
# This script prepares to grade students homework submissions for a particular assignment.
# To do so, it creates a branch on each student's fork equivalent to the original assignment.
# It then creates a pull request against that branch.
#
# Author: Shilad Sen
#
import logging
import sys
from github import Github, UnknownObjectException, GithubException
def create_grading_pull_request(gh, repo_name):
repo = gh.get_repo(repo_name)
hashes = list(repo.get_commits())
if len(hashes) <= 1:
logging.warning("No commits found on repo %s", repo_name)
return
start_hash = hashes[-1].sha
# Create the branch if it doesn't already exist
branch = None
try:
branch = repo.get_git_ref("heads/start_code")
except UnknownObjectException:
branch = repo.create_git_ref("refs/heads/start_code", start_hash)
pr = repo.create_pull(
title='COMP 127 Grading Pull Request for ' + repo_name,
body='Pull request for grading. You dont need to do anything!',
base='refs/heads/start_code',
head='refs/heads/master',
maintainer_can_modify=True
)
def get_last_shared_hash(gh, user, org, repo):
uhashes = gh.get_history_hashes(user, repo)
ohashes = gh.get_history_hashes(org, repo)
latest = None
for i in range(min(len(uhashes), len(ohashes))):
if uhashes[i] == ohashes[i]:
latest = uhashes[i]
else:
break
return latest
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
import argparse
import getpass
parser = argparse.ArgumentParser(description='Create pull requests for grading repo.')
parser.add_argument('--repo', help='Repository prefix associated with the assignment (e.g. "mac-comp127-f19/127-hw0")', required=True)
parser.add_argument('--student-file', help='File containing student github ids, one id per line', default=None)
parser.add_argument('--student', help='student github name', default=[], action='append')
parser.add_argument('--github-user', help='Your github username', required=True)
parser.add_argument('--github-password', help='Your github password', default=None)
args = parser.parse_args()
students = []
if args.student_file:
with open(args.student_file) as f:
students.extend([line.strip() for line in f])
students.extend(args.student)
students = sorted(set(students))
if not students:
logging.fatal("No students specified")
parser.print_help()
sys.exit(1)
passwd = args.github_password if args.github_password else getpass.getpass('GitHub password:')
gh = Github(args.github_user, passwd)
logging.info("Creating pull requests using github user %s", args.github_user)
logging.info("For changeset in repos prefixed by %s", args.repo)
logging.info("For %d students ranging from %s to %s", len(students), students[0], students[-1])
for student in students:
student_repo = args.repo + '-' + student
try:
create_grading_pull_request(gh, student_repo)
print('created pull request for ' + student)
except UnknownObjectException:
logging.warning("Student repository %s not found for student %s", student_repo, student)
except GithubException as ghe:
if 'pull request already exists' in str(ghe):
print('Pull request already exists for ' + student)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment