Skip to content

GitHub Integration with courses at Purdue

History and Overview

This is based on work integrating GitHub, Brightspace and Gradescope to control code submissions, do preliminary checks using the Gradescope autograder, and facilitate additional manual grading using Gradescope rubrics for ABE 65100 Environmental Informatics.

Gradescope and GitHub Classroom has been used since Spring 2020 to facilitate programming assignments and assessment in ABE 65100 Environmental Informatics. This has allowed me to manage two sections of the course (on-line and in-person) simultaneously and scale each section to handle a larger number of students. Using GitHub forces students to learn how to manage their code revisions, GitHub Classroom facilitates the distribution of templates for each assignment that integrate instructions with code templates. These are managed by the instructor through a GitHub repository, which allows updates to the assignment templates and instructions before and during the class. The Gradescope autograder provides immediate feedback to students on elements of the assignment that can be tested using code. The immediate feedback allows students to test components of their code as they develop them, and also facilitates consistency in assessment, since every student's code is evaluated against the same standards. Additional aspects of the assignment rubric can be evaluated manually within Gradescope after submission, and final grades can be pushed to the Brightspace grade book.

These instructions are designed to help with integrating new courses and for updating an existing class for a new semester.

Note

At this time, Purdue does not support GitHub Classroom with their local GitHub instance. Thus the course assignments and student work is all maintained on github.com under my personal account (this does not required a paid subscription for students or myself to work). I maintain the autograder code on the Purdue GitHub instance (github.itap.purdue.edu), as it provides a higher level of security than the free GitHub account, and it keeps the most important course code in the same place as my research code.

Course integration overview

For ABE 65100 Environmental Informatics, which is primarily a programming course, this setup allows me to do the following:

  • Manage course with Brightspace - Brightspace is where lecture and reading materials are assigned, distributed and where course grades are made available. A central location is best for keeping students informed.
  • Build and distribute assignments with GitHub and GitHub Classroom - GitHub allows me to keep assignment documentation, required data files and a program template in one location that GitHub Classroom makes accessible for the students. GitHub Classroom uses my assignment as a template, and when a student checks out the assignment they get a new repository that is fully populated with the contents of the original. If the template needs to be updated, they can pull the updates into their own repository. I can flag issues in the source repository that should be resolved before the next iteration of the class.
  • Use GitHub templates - Templates can be designed to forces students to solve the assignment within defined limits, and can be used to encourage and enforce good practices for new programmers. For example, templates can be designed so that students practice encapsulation by writing stand-alone functions that can then be used together to complete a more complex task. Forcing students to write consistent functions also makes it much easier to write autograding code that can evaluate their assignments by loading and testing their functions.

  • Build autograder code to do a preliminary evaluation of submitted code - By having the students work from a code template, I can design a testing script that loads defined functions, and evaluates the responses from those function to a set of input parameters. For example, if the assignment is for students to write a square root function, I can have the autograder check the accuracy of values returned for any positive number, and check that the code fails gracefully when given a negative value. The autograder can also skip functions that do things that are difficult to assess, such as generate a figure. By loading functions defined in the template, I also give students the flexibility to define subfunctions for their functions. Loading the main function will load any subfunctions automatically. Having students submit repositories for grading means that any extra code files they create will be available to the autograder. While the template stifles some creativity, it makes the assignments more consistent, but students can still be creative in how they write the function. Finally, as the autograder code is in a GitHub repository, and changes I make to the autograder (to fix bugs or add flexibility) is automatically available to the autograding system.

  • Manage grading and grading rubrics with Gradescope - I like this grading interface better than Brightspace, plus my grading rubric can incorporate the points awarded by the autograder. Students get immediate feedback on their code and can resubmit as many times as they want to improve their autograder score. Late submissions can also be autograded, and point deductions can be made if desired. The autograder will update itself from GitHub, so fixes to the autograder can be applied to previously submitted code and apply automatically to later submissions.

Required course materials

The following materials materials are required to make Gradescope autograded assignments work:

  • Assignment template repository - A course organization created on github.com:
    • I use my free GitHub.com account as it works with GitHub Classroom and Gradescope.
    • I typically call them "ABE65100-LEC-Spring-2025" where I use the course number, "LEC" for in person and "DIS" for distance sections, then the semester and year of the offering.
    • At the start of the class this will contain the Assignment template repositories, which include the assignment document, any required data files and a program template. These can be copied from the repository for the previous course offering, or from a separate repository. I prefer the former because I am better at capturing edit made during the course and starting issues directly in the active course repository, rather than in a separate location.
    • As students access the GitHub Classroom link for each assignment, this organization will be populated with their personal assignment repositories.  Initially these will just be copies of the assignment template repository, but any work they do can and should be checked into the repository, which will provide the instructors access to the code if there are any problems. !!! note Students will create their own GitHub accounts for the class, and those account names can be anything, so it is often easier to have them upload their code to the Gradescope assignment when helping them, since then they have to use their Purdue career account.
  • Solution repository - A solution set and autograder repository on github.itap.purdue.edu:
    • This should only be accessible to the instructors, and to Gradescope so that it can pull updates of the autograder files.
    • There should be a Solution repository for every Assignment template repository that is to be autograded.
  • Brightspace course - Merge all sections of the course before incorporating the GitHub Classroom and Gradescope links. Refer to the article How do I merge my courses in Brightspace for help.
  • Gradescope account - Access to Gradescope is supported by Purdue, for help and links to relevant resources visit the Gradescope page at Purdue Innovative Learning.
  • GitHub Classroom account - GitHub classroom is available through GitHub.com and I believe uses the same login credentials.

Designing a new class

This information is based on Keith Cherkauer's notes from on how he has integrated GitHub Classroom and Gradescope into both the in-person and distance versions of his course ABE 65100 Environmental Informatics. Some things may have changed since he first started course development in Spring 2020, but he has not created a new course from scratch since then so may not have updated these notes adequately. Please send suggestions for edits to him directly.

Assignment Solution and Auto Testing Code

  • For each new assignment in a class, start by creating a working solution code in a form that the autograder can evaluate. That means the solution should:
    • Run from a Linux command line.  You can create a script that will install required modules and packages and start any relevant software (e.g., Python, R, MatLab) but your solution (along with those from the students) cannot require the use of a graphical interface or user inputs (more later) to run - otherwise the grading process cannot be automated.
    • Be built using functions that can be loaded by the autograder and tested separately from the main part of the code.
      • Break down complex assignments into smaller functions that independently handle a limited number of tasks.
      • Each function can then be tested independently and the autograder can provide feedback on which functions are performing correctly and which are having problems.
      • Building everything into a single, large, complex main code makes it difficult to build testing software that can test and report on relevant problems.
      • The best functions should do things that MUST be done in the assignment a specific way and that result in returned values or output files that the autograder can test without running the main code. For example, a function might open a file (name provided as a parameter to the function), and return the data in a structure (dictionary, data frame, array, etc) with specific requirements such as a datetime index and specific column headings. Then the autograder can load and call the function using a filename, grab the returned values and evaluate them. It could check for a specific date, column heading, or value in the table. You could also calculate mean, sum or other statistics of a column. You can in fact test multiple aspects of the returned data structure.
      • While building your solution code this way requires more careful planning on your part, the resulting code is easier to define in the assignment (each function has very specific requirements), easier to convert into a template for the students (which helps them learn the structure), and easier to build testing software that students can actually use to evaluate and fix their own work.
    • The assignment template must clearly define the type and order of parameters sent to the function being written, as well as the type and order of variables being returned from the function. Students who change the order, type or number of variables passed to or from the function will fail the autograder assessment.
    • It is possible to exclude the main code block and any functions not imported by the autograder testing program from the more strict formatting requirements needed for testing.  I use this flexibility so that students can use packages not included with the autograder, and build their code to interact with a normal user.
      • In Python, any code within the conditional statement if __name__ == '__main__': will not be run when a function is imported from the file.  I have students write their main code block within that conditional, and the autograder ignores the code when importing functions.
      • It may also be necessary to import some modules (e.g., cartopy or geopandas) that are needed or helpful for completing the assignment but that are not readily available to the autograder. The autograder creates a virtual environment for each test, and there is no user interaction with that environment so some beta or large modules may not install consistently, and are better to exclude from the testing environment. That limits what can be tested but reduces the aggravation of failed software installs and long wait times.
    • The autograder program for Python (and most other languages) will build on the language specific unittesting library. This document on What is unit testing is a useful overview.
      • In Python, the autograder relies on the unittest module to develop testing algorithms. The autograder code loads functions from the submitted student solution, and runs a sequence of assert statements that can check returned values to see if they are True/False, equal to a value or even equal within a tolerance of a value.
      • Both R and MatLAB have unit testing modules / packages available so should be able to work in a fashion similar to what I have used with Python. As of 01 Jul 2025 I have not developed any assignments in those languages, but here is a link to Unit Testing in R Programming, and an overview of unit testing by MathWorks to get you started.
      • For bash scripts, I am currently not working with functions nor do I make use of a unit test package, so for those assignments my autograder test code runs the submitted script and evaluates its output to the user, files created or modified and any other changes it was expected to make to the environment. 
  • Next you need to generate the autograder code repository.

    • I made use of this Gradescope autograder template GitHub repository for developing my assignment, and will share examples of those I have developed to any instructor who is interested. The repository works for Python, but I have modified it for Bash script testing as well.
      !!! note If you have taught the assignment previously, I find it helps to start developing the assignment template and autograder code using an existing code that already
  • Deploy keys - very important!

    • The deploy_key file described in this process must contain the private key generated that matches the public key given to GitHub.

      • Because of this make sure that the GitHub repository used to store the autograder templates and code does not include the deploy_key file (add it specifically to the repository .gitignore file). It is only needed for generating the autograder zip file with make_assignment.sh.

      • The file gradescope_base/ssh_config and gradescope_base/setup.sh are set by default to connect with github.com. If you use a different enterprise github instance, then both scripts must be edited to point to that repository, or the ssh handshake will fail and your autograder will not be successfully installed.

      • To handle all of this accounting of deploy keys, both public and private parts, I created a new folder for creation and storage of public-private deploy keys. This folder is NOT connected to GitHub, but is located with my assignment development repositories. Within that folder, I use one of the following commands to develop public-private ssh key pairs. The public key is loaded to the autograder GitHub repository as a deploy_key, while the private key is copied into the file called deploy_key in the autograder gradescope_base folder (This file should NEVER be uploaded to GitHub).

        Note

        Old algorithm, use longest version, but accepted everywhere ssh-keygen -f ./assignment-09-key-rsa -t rsa -b 4096

        --or--

        Good algorithm for current applications, accepted by most but not all applications ssh-keygen -f ./assignment-09-key-ecdsa -t ecdsa -b 521

        --or--

        Newest algorithm, best for the future but not universally accepted ssh-keygen -f ./assignment-09-key-ed25519 -t ed25519

      • The deploy_key file (the private ssh key) is included in the autograder zip file, which is uploaded to Gradescope where it is used to automate Gradescope's ability to pull the autograder code directly from the Autograder repository (see note below).

      • Another note - Get the ssh address for the repository by clicking on the clone tab, and requesting the ssh version of the clone link. DO NOT try to make a modified HTML link work - it will lead to hours of aggravation!!

    • Here is a web site I found useful for information on generating ssh keys.

    • GitHub requires a separate deploy (ssh) key set for each repository, so in my case for each assignment.
    • The deploy_key pair is used in this process so that the autograder starts by pulling the latest testing code version from the solution repository, rather than using whatever was originally installed with the Gradescope assignment. This is useful, if changes need to be made to the autograder after the assignment is created. This setup only requires the autograder to be rebuilt when significant changes have been made, and the autograder setup process for each student submitting begins to take too long.
  • To add and link Gradescope to Brightspace

    • Create a link to the external Gradescope tool
    • First time you log into Gradescope, you will need to create account.
    • Will need to create class on Gradescope and link it to Brightspace course - if you access Gradescope through a Brightspace link from the course page, I believe you are lead through this process automatically.

      Note

      The way that Gradescope and Brightspace interact changed before Spring 2025. The training document Using Gradescope LTI 1.3 with Brightspace D2L as an Instructor is the resource for linking Gradescope assignments to a Brightspace course.

  • Organization

    • Need to grant third-part access to both GitHub Classroom and Gradescope, before students can work in the new repository

    • I am currently using two "permanent" GitHub repositories and one "temporary" for each assignment.

    • Assignment repository

      • The first set, which contains the assignments, is stored in a public organization / classroom called Environmental-Informatics.
      • Assignment repositories include a README.md file with the assignment, a .gitignore file setup to keep the repository clean while allowing assignment files to be uploaded, and any data files or template files provided to the students as part of the assignment.
      • I think that more of the assignment will be pushed back to Blackboard/D2L once Gradescope integration in completed. The assignment file in the repository will provide more general guidance. I think that in the future that the README.md in the repository should be left mostly blank perhaps as a template of the required metadata submission for the assignment.
        • Need to provide links to GitHub markdown formatting, such as https://guides.github.com/features/mastering-markdown/, which includes information on embedding images.
        • Also need to see if the GitHub wiki pages are linked with the repository.
        • Could also explore readthedocs, but that might be getting too far beyond the desired skill level of the course.
    • Solution set repository

      • Much of this material is based on https://github.com/mnoukhov/gradescope-autograder-template, but with edits and comments to improve on what I found missing or confusing.
      • This repository contains
        • The solution template, copied to the Assignment repository, once set.
        • The solution code, used to test to test code before bundling and uploading to Gradescope as an assignment autograder bundle, and also copied to the temporary assignment submission testing repository once the autograder has been successfully uploaded to Gradescope.
        • The requirements.txt file, which contains a list of all required Python libraries (always include the gradescope utilities) needed to setup the environment such that it works for the student's assignments.
        • The gradescope_base folder that stores all of the gradescope autograder upload files and setup scripts.
        • The make_assignment.sh script, which once edited for the current assignment, will create the upload bundle ( zip file) for Gradescope.
    • Test solution repository

      • Use the GitHub classroom assignment link to create a local copy of the Assignment repository.
      • Copy the solution code from the Solution repository and replace the template in the current repository (if the submission code name is the same as the template - currently I am using a different template name, so that students do not lose the template in the process of writing their own solution).
      • Push the repository to GitHub.
      • Submit to Gradescope, and confirm that it passes the autograder check.
      • Delete this repository, as it will be available to the students.
      • This process can probably be eliminated if I make the template and the autograder repository use the same file structure - something I did not think of until just now smile.

    Other helpful information

    • Gradescope must be granted access to GitHub for this to work.
    • When it asks, it is granted to your personal account, but not by default to any organizations within your personal account. As I set GitHub classroom up to use the organization Environmental-Informatics, this caused a problem with submission. Selecting GitHub submission through Gradescope resulted in a list only of the code in my personal GitHub page, not in the Environmental-Informatics organization.
    • To make that code viewable, I had to grant Gradescope access to the organization, following these instructions: https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/requesting-organization-approval-for-oauth-apps.
    • Now when I get tot he upload page, I can see everyone's submissions from all assignments. This is going to be a problem. How do I get GitHub classroom to clone the assignment into each student's personal github? Do they see all assignments? They are sorted by last activity, but that still makes it a problem to find your own, plus students can always see everyone's submissions.
    • Filename conventions
    • Python general: Do NOT use a hyphen "-" in filenames as Python has trouble importing from files with that character. The underscore "_" appear to be fine.
    • Some additional sites I found to be helpful
    • Other gradescope autograder repositories
    • For setting up the testing file

Building a new course section from an existing course

  1. Make sure that you merge all Brightspace sections for the current semester into a single Brightspace course before setting up all supplemental connections for the course. Here are the Purdue instructions for merging course sections.

  2. Copy contents of the previous course section into the new Brightspace course. Here are instructions for copying an existing course

  3. Copy the assignment organization contents

    • If you have not already, make a local directory for all Assignment template repositories, I store mine in "~/GitHub/ABE65100/Assignments".
      • Clone all of the assignments to that new local folder, this is the best way I have found to manage courses. As I teach two sections simultaneously, I maintain sepater folders with a full set of assignment repositiores for each course - these are each linked to the organization created for each course offering.
      • The local copies mean that I can make updates to the code locally and decide whether or not to push the updates to the class during the semester. It is also on me to make sure updates to a common assignment are made for both classes.
    • Review the Assignment template repositories from the previous course offering.  Make sure that all flagged issues have been resolved, as the issues will not follow your repository to the location for the next class.
    • Create a github.com organization for the new course section. Use a name that differentiates the current course from the previous offering. For example I use an organization name such as ABE65100-Spring-2021, to keep track of my course materials.
    • New organiztion will carry over nothing, so no assignment repositories, issues, permissions or student submissions - it will be completely empty. This does mean that I can maintain the previous classes repository in GitHub so taht they can continue to access their code even though I am offering a new section.
    • Upload the each of the course assignment repositories to the new organization:

      • First you need to change the remote url connected to your local clone repository. By default, this will be set to the previous offering, but moving forward, you want to only edit the current course assignments.
        • Here are instructions for using the git command line (e.g., from Linux):
          • Use the command git remote -v to obtain the current URL (this will be the address of the previous class GitHub organization.
          • Then use the command git remote set-url origin <NEW_GIT_URL_HERE> to set the URL for the new course GitHub organization.
          • Make sure to use the repository address for SSH and not HTML when using the command line.
        • Here are instructions for using GitHub desktop
      • Next you need to create the new repository with the same name on GitHub.com. I name my repositories "Assignment-01", "Assignment-02", etc, and keep them consistent from offering to offering, which reduces the typing necessary for this process. Leave all of the default settings alone - you want this to be an empty repository, since you will fill it with the existing assignment materials.

        Note

        Unfortunately there is no way to do this outside fo the web interface, however, the create new repository in an organization link will be the same, so copy it from the browser the first time you go there, and then past it back in for each new repository that needs to be created.

      • Once the empty respository for the assignment has been created, you can push the previous assignment repository to the new URL using the command git push --mirror <NEW_GIT_URL_HERE>.

  4. GitHub Classroom

    • There is no default mechanism to copying a course to start a new section. Instead you will need to create a new classroom and link it to the recently created GitHub organization for the new class.
    • Log into GitHub classroom using your github.com credentials.
    • Once logged in, you should see all of your previous classrooms. I also try to name this similar to the previous iterations, so that I can find previous sections as needed.
    • Click on the "+ New classroom" button in the upper right to create a new classroom for the current semester.

      • First screen will show you your existing organizations in GitHub. Select the organization for the current class offering.
      • Update the classroom name if desired, I typically remove the random sequence at the end of the offered name as I make sure to not use the same name for two class offerings.
      • Select "Create classroom".
      • On the next screen, add any TAs and copy the student link, which should be posted into Brightspace so that students can go directly to the course classroom, and not worry about finding the wrong section.
      • Select "Continue".
      • Next page allows you to link the classroom with a learning management system, however, Brightspace is not currently supported, so roster syncing is not possible. I share the link to classroom (from the previous screen) with students so they can self-enroll. Just skip this page by clicking on "Continue".
    • With the classroom created, you can now populate it with assignments.

      Warning

      DO NOT use the "Reuse Assignments" option from a previous class organization. When I did this from a previous course, it populated the new course with copies of every repository in the organization - my assignment templates plus every student submission. Since there is no bulk delete for repositories, I had to rename and then delete the entire organization and start a whole new class.

      • First go the assignment repository in the class organiztion and set it to be a "Templates repository" in the "Settings" panel for the repository on GitHub.

        Screenshot showing the location of the Template repository button in the settings
panel for a GitHub repository Select the repository for the new course offering, and the new classroom.

      • Within GitHub classroom, select the new course and then select "+ New assignment".

      • Then you will need to create new assignments for the new class and copy those assignment links to the assignment in Brightspace

      • This will open the screen below, which will ask for you to enter the assignment title. GitHub classroom helpfully prompts me with previously used titles, which helps make this process easier. I do not set dates here, instead I set those in Graescope and Brightpsace. I also leave all of my assignments set for individuals.

        Screenshot from GitHub classroom of the first page of the build new assignment process

      • On the next page, you need to start typing the repository name and GitHub classroom will provide suggestions. Unfortunatly some people make their repositories public, so I have to type enough of the repository name to get to my own material. I leave all options set to their defaults.

        Screenshot from GitHub classroom of the second page of the build new assignment process

      • Since I do not use the GitHub Classroom autograder, I skip the next page, just selecting "Create assignment".

      • The final page in the process shows information on the assignment just created. The most important part right now is the link to the assignment, which I copy and share in the assignment module in Brightspace. You can get to the link from the course page as well. Students can also get to the assignment by logging into GitHub classroom and selecting the correct assignment name.

        Screenshot from GitHub classroom of the final page of the build new assignment process

  5. Gradescope

    • Log into Gradescope.
    • Go to "Course Settings" for the previous iteration of the course.
    • Scroll to the bottom of that page, and you will find a button to "Duplicate Course".

      Screenshot from Gradescope showing the location of the Duplicate Course button

    • On the Duplicate Course page that opens, you should select the start date of the original course, and the start date of the new course. This will allowed Gradescope to automatically adjust all due dates from the previous course to the new course calendar.

      Screenshot from Gradescope showing the contents of the Duplicate Course page

    • Click on the "Duplicate" button.

    • This will open the settings page for the new class, so you should immediatly update the class name, since by default it keeps the name of the previous offering. Again, I like to include the course semster and the format of the class so that when I run two sections at once, students can find the correct class, even if I post the wrong link.

  6. Brightspace

    • First thing to do in Brightspace is the update the link to the Gradescope course (I like to start with the first assignment).

      • Click on the External Learning Tool module for a Gradescope assignment.

        Screenshot from Brightspace showing the heading for a Gradescope assignment

      • This should open the Gradescope tool interface.

      • The first time it opens, it will ask you if you want to link to an existing course or create a new one. Assuming you already completed the previous steps to create the duplicate course, open the pull down menu and select the name of the new Gradescope course section.

      • This will update the window and ask you if you want to link to an existing assignment or create a new one. Again, click on the drop down menu and select the appropriate assignment. Each time you repeat this process for a new assignment, the list will be shorter, since it will not show assignments that have already been connected. The list will also be in alphabetical order, so I like to number my assignments so they come up in order as I work through my Brightspace modules.

      • Finally, make sure to open the link from Brightspace to the assignment. I have found that as of Spring 2026, the link between Brightspace and Gradescope is not complete until you do this step. My browser window tab goes blank, flashes a few times and then opens the Gradescope assignment page. If I check Gradescope settings for the assignment shows taht it is linked to a Brightspace gradebook item.

        Note

        Note that once you have completed this process for at least one Gradescope assignment, the Gradescope roster sync option will work. Linking with Gradescope is now controlled from Brightspace and not from Gradescope (this changeed in 2025), so there is nothing you can do within Gradescope to establish the link with Brightspace.

    • In Brightspace, I have included the direct assignment link in the descriptive text for each assignment module. That means I have to update it with the new link once the assignment has been created for the current course.

      Screenshot from Brightspace showing the updated link in the assignment descriptive text

    • It's not strictly necessary, since students can get to all assignments when they log into GitHub classroom, but I do think that it is helpful to make all of that information available locally.

Once all of these steps are complete, my new course section is already to go for the semester. It does take a lot of pre-work, but having the submission and autograder process all automated makes the course run much more smoothly and lets me handle a much larger number of students, so I find that the process is worth it.