GitHub Classroom Reusability

Hello!

My Name is Nicole and I’m new to this community. I generally teach automation and Linux Admin/ SE/ DevOps skills, but my program is paused at the moment due to funding, so I’m teaching Java this quarter and thought I would use GitHub Classrooms.

So far I’ve set up assignments with auto-grading and I have them working for both projects with Gradle and straight Class.java commits.

My question is about reusability. I’ve configured some base assignment repositories to work from and can easily modify the class names across all the files in the repo with sed scripts, but when I use a newly configured repository as a template the tests don’t show up in the autograding/test GUI. They run on the students’ code, which is good, but if I wanted to update a test after students have started working, I would have to push the raw text file out to each student’s repository myself, instead of being able to use the automatic pushes I get with the test/ autograding GUI.

So, I have a couple of questions:

  1. Is there a command-line administrative tool that would allow me to check-in changes to all of my students repositories at once?

  2. Is there a good way to ‘import’ tests into an assignment?

  3. Is there a way to ‘clone’ assignments?

I apologize if any of this is covered in documentation or existing discussions, I did search a bit and couldn’t find anything.

Thank you!
-Nicole

I’m just a user of Github classrooms, but here’s what I’ve found from my time using it:

Is there a command-line administrative tool that would allow me to check-in changes to all of my students repositories at once?

As far as I know, no, but there is the Classrooms Assistant desktop application and the regular Github CLI tool. You’re also able to update your students’ repositories using the standard Github tools.

Between the three, I suspect you could build something that would suit your needs (my initial thought is to give a script the assignment URL, it then follows the repo links and checks out each of them, patches in the update, then pushes the updates back to each repo).

Probably more DIY than you were hoping, but also not impossible, I don’t think.

Is there a good way to ‘import’ tests into an assignment?

That might depend on exactly what you’re asking for here.

If you’re referring to after the students have created their own clones of the assignment, then there isn’t anything that I know of to add tests without updating their repositories. Classrooms is ultimately just a somewhat more convenient front end to the core of Github, so the student repositories aren’t really connected any more than repo forks are.

If you’re referring to the template repository itself, you can set up the tests and the autograding in the repo, instead of via the Github GUI, at least for the tests that can be represented in the code (unit tests and whatnot), I’m not certain about the I/O tests, since I don’t use them. Under the hood, autograding is just a regular Github Action. If you look at the student repos, they should have a .github folder. In it, workflows/classroom.yml can house the main workflow(s), and classroom/autograding.json is where you configure the test commands and scoring (this is what’s generated via the Grading part of the Assignment creation GUI).

Updating this for the template repository will only affect assignments accepted after the update, but you can then use this change to update the student repositories using whatever method you find from your previous question.

Is there a way to ‘clone’ assignments?

I haven’t found a way to do this yet, either. My only thought is to just have a generic one that’s then reused, but given how it all works, I could get that getting really unwieldy and super quickly.

However, combining the two things above and basically bypassing the GUI might make that easier to do (perhaps a good opportunity for a third party tool?). Setting up autograding in the template repository is probably the single greatest step toward easier reusability. That alone probably gets you a good 90% of the way. The rest is figuring out how to automate the flow of creating a new assignment and setting its meta options. From a quick perusal of the docs, it looks like Probot might get you the other 10%, or at least would be a good starting point for reverse-engineering something that might work better for you if Probot doesn’t suit your needs for whatever reason.

1 Like

I found using the GUI to setup autograding was unwieldy for all but one or two single tests, so I set up a template repo for myself that contains:

  • the files necessary for running the autograding (in .github/workflows/classroom.yml)
  • an empty tests file (.github/classroom/autograding.json)

When I’m setting up a new assignment I use the autograding template as a starting point, then fill in the tests in the autograding.json. Works fine, in that when the students accept the assignment this setup runs the tests and shows the results in the GitHub Classroom GUI, and it’s a lot less unwieldy that using the GUI.

Doesn’t fully answer your question (or may not even partially answer it), but it’s the best I’ve been able to come up with this term.

1 Like

When I need to update all student repos, I go to the local directory that houses all of the clones for student submissions and use a simple for loop. For example, if you need to update the tests because you left one out, make the changes (in this example, let’s say it’s stored at ~/new-tests.json) and then commit/push in all repos:

for student in `ls`; do \
echo $student && cd $student \
&& git pull \
&& cp ~/new-tests.json .github/classroom/autograding.json \
&& git add .github/classroom/autograding.json \
&& git commit -m "Adding test for the gonkulator" \
&& git push; cd -; done

Of course, you’ll have to have the students pull, but since they shouldn’t have been messing with the autograder file, it should be a simple fast-forward merge.

1 Like

If by “clone”, you mean to clone all submissions, this Ruby script is what I used as the starting point for my cloning tool - https://github.com/dsu-cit/orgclone. If you mean to copy and build a new assignment from the same template in Classroom, I don’t believe any CLI tools exist for GitHub Classroom so you might be stuck manually creating each assignment.

1 Like

Thank you!! That’s exactly what I’m looking for. Would you recommend using Classroom Assistant to download the student repos or scripting a download using something like curl?

At the time, I meant clone to copy and build a new assignment, but having a cloning tool for student repos actually answers my last reply, so that’s perfect!

I do wonder if GitHub Classrooms would consider making an exportable configuration for assignments and classrooms themselves? Once I get the assignments for the quarter configured, I would really like to be able to hand off copies to my colleagues or use a copy to generate a second section of the same class. Even quarter to quarter, being able to export and import a class configuration from the previous quarter would be really nice.

It depends on how your day is balanced. If you are in the CLI most of the day, then something like the orgclone link I shared will save time and effort, but it you find yourself on GitHub Classroom often enough already (creating assignments, for example), then it isn’t likely to save that much time. This becomes especially true if you are working with a TA/grader who is likely less familiar with the CLI and would require more hand-holding then they will with the Classroom Assistant tool.

1 Like

Thank you! You make a very good point. I tend to spend my days on the command line, so I think scripting is the best option for me.

I set my organization and all of my student repos to private so I had some trouble with the Ruby script. Alas, I’m not a Ruby programmer, so I switched to Bash and was able to hack together a curl script for private orgs/ repos based on two internet threads with examples. The one line script uses ssh keys and an authorization token so no password is needed. I’ll leave it here as an option for anyone else who is similarly afflicted with private repos/ orgs and isn’t well versed in Ruby:

export AUTHORIZATION_TOKEN=""
export MY_ORG=""

curl -H "Authorization: token $AUTHORIZATION_TOKEN" \
-s https://api.github.com/orgs/$MY_ORG/repos\?per_page\=200 \
| perl -ne 'print "$1\n" if (/"ssh_url": "([^"]+)/)' \
| xargs -n 1 git clone

# set $AUTHORIZATION_TOKEN and $MY_ORG in your environment or script before running

Your solution of committing new tests and pushing them should do the trick, so besides finding a way to duplicate classrooms, which I still hope is possible long-term, I am good to go!

Thank you so much for your help!

That might start falling apart after a few assignments. I’m not sure how big your section is, but with 30-40 students and 5-10 assignments, the 200 limit would get hit quickly. You’d also be cloning old assignments each time. You’ll probably want to use an assignment prefix on the fetch.

1 Like

Yes! You’re absolutely right. Thank you for pointing out how important the prefix is. I modified the api code a little bit and this seems to work:

export AUTHORIZATION_TOKEN=""
export MY_ORG=""
export PREFIX=""

curl -H "Authorization: token $AUTHORIZATION_TOKEN" \
-s https://api.github.com/search/repositories?q=$PREFIX+in:name+org:$MY_ORG\&per_page=200 \
| perl -ne 'print "$1\n" if (/"ssh_url": "([^"]+)/)' | xargs -n 1 git clone

# Don't forget to set $AUTHORIZATION_TOKEN, $MY_ORG, and $PREFIX

My sections are usually under 40 students, so as long as my prefix is specific enough I shouldn’t ever hit the limit. Is there anything else I should watch out for?

Thanks for all your help!

© 2017 GitHub, Inc.
with by
GitHub Education