GitHub Classroom Guide for Teachers
This is a guide for using GitHub Classroom to assist or run your class. We are using GitHub Classroom for a class where the assignments are primarily, if not all, R Markdown files. However, this guide should be applicable to most classes.
Setting up GitHub Classroom:
- If you plan on repeating the class in future semesters, set up a "master" classroom organization. If you are teaching a class titled "Intro to Statistics", we recommend calling this organization intro-statistics-master, or something similar. We use this organization to host all assignments that will be used in the current and future versions of the class. Each assignment should be its own repository. When using GitHub classroom to send out assignments, we can use repositories from this organization as starter code. If changes need to be made for future years, you can change the repository in the organization without affecting the current version of the class. The GIF below shows how to create an organization on GitHub
Go to https://github.com/settings/connections/applications/64a051cf1598b9f0658f and grant GitHub Classroom organizational access to the master organization.
If you want the assignments to be private, you can apply for an educational discount that will grant the organization unlimited repositories. The link for the application is here: https://education.github.com/discount_requests/new. The GIF below shows the beginning of the application process
- Using the same process as above, create an organization for the current version of the class titled something similar to intro-statistics-fall-2017 (or whatever semester and year you're teaching). Grant GitHub Classroom organizational access to the organization. In addition, apply for unlimited private repositories for this class so that individual assignments can be private (preventing potential cheating). Go to https://classroom.github.com/classrooms and click "New classroom" in the upper right corner. Choose the class you are currently teaching. Note that this step will have to be repeated for each semester.
You will also want to create a team for the students. When you are in the viewing mode for the organization, click on the "Teams" panel. Click "New team" and name this team "students".
Add all other teachers and TAs to the organizations as owners.
Go to the current year's version of the classroom organization. Under settings, go to member privileges. Change Base permissions to "none" (if it's not already) and save these changes. This will make it so that students cannot change non-assignment repositories in the organization.
Add students to the organization. You can do in this two ways. The first is by manually adding students via email to the organization as members. This can be quite a pain if you have more than 5 students in your class.
A more (but not fully) automated way to do this is by sending out an assignment. This can be the first assignment of the class, such as a practice homework or bootcamp type assignment. Once you send out (and they accept) the first assignment, they will be added to the organization as outside collaborators. See the next section for instructions on creating and giving access to assignments.
If you want students to be organization members, rather than just outside collaborators, do the following. Go to the People section of the organization and click on Outside collaborators. Click on the gear icon next to each student's name and click invite to organization. In this invitation pop-up window, you should also see an option to add them to the students team--you should do this. Once the students accept the invitation, they should be removed from the outside collaborator panel into the members panel. They will also be added to the students team. While this is still some work, you do have a nice way of checking who has accepted the invitation.
Note the difference between outside collaborators and members. Outside collaborators only have access to repositories that their team membership allows. Outside collaborators cannot create teams or view all the organization's members and teams. If you're only using GitHub Classroom for personal assignments and not for other class materials, it is probably fine to leave everyone as an outside collaborator. However, if you have a private shared repository (such as class material outside of homeworks), you'll probably want to have teams. In this case, I would make all students members of the organization.
(Optional). Create a repository (or multiple repositories) that will contain shared information, such a class syllabus, lectures, homework solutions, etc... This will be done in this year's classroom organization, although you can create it in the master organization, and then fork it over for each new class. Of course, you don't have to do this at the beginning of the class, and can add new repositories as you go along. The idea is that students can clone these repositories at the beginning of the year, and then pull in changes. However, please be aware of the possibility for merge conflicts, and think of ways to reduce them.
If this repository is private, go into the repository, then go to Settings -> Collaborators & teams. Then add the "students" team to have read access to this repo. Done!
Sending out individual assignments
- Make the assignment repo in the master organization. This can include all starter code, data, etc... Be smart about naming your repository. Remember, there are no spaces allowed in GitHub repository names. We recommend using the dash "-" to separate words and numbers. A couple examples of assignment names we have used are "test-assignment" and "unit-1-assignment-1". In the example below we make this a public repository, but you can make it a private repository if you don't want others to see your class assignments.
Go to https://classroom.github.com/classrooms and click on the current class organization. Click new assignment, then create an individual assignment.
Use the repository name as the assignment name. You can skip the "Your assignment repository prefix" box, as this should automatically be filled in with the assignment name.
Unless you want all of the students to see each others' assignments, click Private repository. However, we make this a public repository in the example below.
Add the assignment from your master organization as the starter code. You will probably have to manually type out the organization name for all available repositories to show up.
Copy the invitation link and give students access to the link, either through a mass email and/or posting it somewhere that all the students have access to. Be somewhat careful of not posting this to a publically available place, as anyone with access to the link can then create their own assignment (why they would do this, who knows). Students should now be able to click on this link to set up the repository.
Before I go into the steps on how to do this, I'll mention that this step will probably vary from teacher-to-teacher. If you have a different workflow from us, please feel free to share how you grade assignments from GitHub!
I also want to give the general outline of our grading workflow before I go into the details. The idea is that for each assignment, we will clone all of the students' assignments into our local computer using a shell script. These assignments (which are directories/repositories) will live inside a directory unique to that assignment. So, assignment1 will have an assignment1 directory, and inside of that will be many directories, one for each student's repository. We will then add comments or edit each student's homework assignment locally and save these changes. We then have a shell script that will commit these changes and push each student's repository back to GitHub with a single commit message ("Graded $date $time"). The students can then click on this commit message in their GitHub repository to see a diff and will know what you added.
Here are the steps.
Have a directory for the class in your local computer. Inside of this directory, I would recommend making a directory titled something similar to
homework-grading. The way we will use this directory is that we have a shell script (more on this in the next step) that will create a sub-directory within the
homework-gradingnamed after an assignment prefix. The script then automatically clones all of the students' repos for this assignment into the directory.
Navigate to the
homework-gradingdirectory. The shell scripts we will be using are from https://github.com/konzy/mass_clone. You can either clone this repo, or my forked version https://github.com/jfiksel/mass_clone, into the
homework-gradingdirectory. Currently, my forked version allows you to pull changes in from a student's repository if they have made changes after your initial cloning. At this point, your directory structure should be as follows:
class-fall-2017 │ │ │ └───homework-grading │ │ │ └───mass_clone │ README.me │ clone_all.sh | clone_all_helper_example.sh | push_all.sh
Here are the commands that I used in my terminal to do the above:
clone_all_helper_example.shscript so that your class specific organization and your username replaces the default settings in the organization and username fields
When you are ready to edit all the assignments, go to the terminal and navigate to the
mass_clonerepository. Type in
./clone_all_helper_example.sh. You can then enter in the assignment prefix when prompted (or just type
./clone_all_helper_example.sh assignment-prefix). For example, if we are grading
unit-1-homework-1, then I would type in
./clone_all_helper_example.sh unit-1-homework-1. You will then be prompted to enter your GitHub password. Unfortunately, you will have to enter in the password every time you do this step, even if you have SSH set up (which you should!). Please also note that if you have two factor authentication, you will have to generate a personal access token and use this token instead of your password. You may also have to change the protocol variable in
clone_all_helper_example.shfrom "ssh" to "https", although I'm not sure about this. Your directory structure will now look like this
class-fall-2017 │ │ │ └───homework-grading │ │ │ |────mass_clone | │ README.me | │ clone_all.sh | | clone_all_helper_example.sh | | push_all.sh | | | |────unit-1-homework-1 | | |----unit-1-homework-1-student1 | | |----unit-1-homework-1-student2 | . . . | |----unit-1-homework-1-studentN
And here is a GIF showing how to do the above:
You can either edit all the assignments by typing comments into their documents, or by adding a new file with comments to each student's repository. If there is only one document that students will be editing, then it's possible to open up each student's document, put in your changes, and then save. This is also nice because you can use regular expressions to open up every student's assignment without you clicking. For example, if the document is called homework1.Rmd, and you are inside of the unit-1-homework-1 directory, you can type
open */homework1.Rmd(you can replace open with whatever command you want so that the files open in your preferred editor). You can then work through each student's assignment, saving and then closing their assignment after you are done grading. You may or may not want to put official assignment grade into your comments due to privacy issues.
After saving (you have to save!) your changes and/or new files, navigate to the
mass_clonedirectory. Type in
./push_all.sh assignment-prefix(this is similar to the GIF above). This script will commit all of your changes with the same commit message ("Graded $date $time"), and then push all of the changes back to the students' repositories.
Alternate Grading method using Pull requests
In the previous method of pulling down students’ work, adding a commit to their work, and pushing it back up is a good simple approach. Another way of grading would be for students to take advantage of GitHub's pull requests. In the following steps we will go into how this can be conducted:
- In order to do this, students would need to create a branch off the master to do their assignment.
- Students would then make their changes in the branch
- When they are ready to submit to be graded, they would follow this tutorial on how to create pull requests. Here is example of what a pull request looks like with feedback: example
- The instructors will add comments in this pull request. Depending on how you want to operate, you could allow for additional changes to give the student an opportunity to improve their code and grade. Opinion from @acorbin3 - I know this can be controversial, but at least in the software industry this is how software is development and I feel that us as instructors it’s our job to prepare students to be successful in the industry and that we should simulate this as much as we can.
This doesn’t address the part where we need running and testing the assignments. We can follow the same steps to pull down peoples’ assignments in Grading assignments and run the assignments. There is another approach to set up automated test using TravisCI. Here is a blog post that goes into details on this approach Real-time feedback for students using continuous integration tools. Also here is a recent (2019) success story of this approach in action where they boosted their passing rate from 76 to 90% How GitHub Classroom and Travis CI improved students’ grades