Prepared 16 September 2026 for Koushik Sen (GitHub ksenxx), organization Berkeley-CS-264.
GitHub retired GitHub Classroom on 28 August 2026; classroom.github.com now redirects to the retirement notice. GitHub names two successors: Codio (commercial, LMS integration) and Classroom 50 (free, open source, from the CS50 / Fifty Foundation team). Classroom 50 was chosen because it costs nothing, keeps all data inside your own GitHub organization, and reproduces the GitHub Classroom workflow: per-student private repositories created from a template, invite links, autograding through GitHub Actions, a submissions dashboard, CSV score export and inline feedback pull requests.
Classroom 50 has no server. Every piece of state is ordinary GitHub data in your organization:
| Concept | Where it lives on GitHub |
|---|---|
| Classrooms, assignments, scores | Private repository Berkeley-CS-264/classroom50 (cs264/classroom.json, assignments.json, roster.csv, scores.json) |
| Who is enrolled / who is staff | GitHub teams classroom50-cs264, -teacher, -hta, -ta |
| A student's submission | Commits and Releases in Berkeley-CS-264/cs264-hw1-<username> |
| The assignment list students read when accepting | GitHub Pages site of the classroom50 repository |
| Step | Result |
|---|---|
Verify ksenxx owns Berkeley-CS-264 | Yes, role admin (owner) |
Widen the gh CLI token to the scopes Classroom 50 needs (admin:org, repo, workflow) | Done (you authorized device code 7374-8780) |
Install gh teacher and gh student extensions on this machine | Done |
Create the fine-grained service token classroom50-Berkeley-CS-264 (resource owner: the org; all repositories; Contents, Actions, Workflows, Administration read/write; org Members read; expires 16 Sep 2027) | Created in your Chrome session; stored as the encrypted Actions secret CLASSROOM50_SERVICE_TOKEN on Berkeley-CS-264/classroom50. Not written to disk. |
gh teacher init Berkeley-CS-264: lock down org member privileges (base permission none, no repo deletion/transfer/visibility change by members), enable Actions, $0 Actions overage cap, allow Actions to open PRs, create the private classroom50 repo with 5 workflows | Steps 1 to 8 done |
init step 5 (org branch rulesets) and step 9 (GitHub Pages on the private repo) | Blocked by the Free plan (HTTP 403 "Upgrade to GitHub Team" and HTTP 422 "Your current plan does not support GitHub Pages"). See section 3. |
Create classroom cs264 ("CS 264: Implementation of Programming Languages", term Fall-2026) and its four teams | Done; ksenxx added to the teacher team |
Register assignment hw1 from template Berkeley-CS-264/cs264-hw1 | Done; the student team was granted read on the private template |
Autograding for hw1 | Python 3.12 runner; step 1 installs pysmt and z3-solver (0 points); step 2 runs python3 -m pytest -q against the template's tests/ (100 points); passing threshold 50% |
Berkeley-CS-264 is on GitHub Free for organizations. Classroom 50 publishes the assignment list that gh student accept and the accept link read from the private classroom50 repository through GitHub Pages, and GitHub only allows Pages on private repositories for organizations on the Team or Enterprise plan. Consequences today:
classroom50 failed ("Ensure GitHub Pages has been enabled"), so students cannot accept hw1 yet.ksenxx account had no GitHub Education application when I checked. I pre-filled the teacher application in your Chrome (role Teacher, school University of California, Berkeley, email ksen@berkeley.edu), but after you replied "submitted" the page github.com/settings/education/benefits still showed Start an application rather than a pending application, so it likely did not go through. Please open that page, click Start an application, allow the browser location prompt, click Continue, and upload proof of faculty status (a photo of your Cal ID or an appointment letter). Approval usually takes a few days, sometimes up to two weeks.
After approval, in this order:
Berkeley-CS-264 to GitHub Team using the education benefit (no charge).gh teacher init Berkeley-CS-264 --yes gh teacher audit Berkeley-CS-264
gh workflow run probe-token.yaml --repo Berkeley-CS-264/classroom50 (a green run means every permission is in place).If you would rather not wait for verification, the Team plan can also be paid for directly (per user per month) from the organization's billing page; the education benefit can replace it later.
All of these run on this machine, where gh is authenticated as ksenxx. The same actions are available in the web app at classroom50.org once the plan is upgraded.
# one student by GitHub username (sends the org invitation and enrolls them) gh teacher roster add Berkeley-CS-264 cs264 <username> --first-name Ada --last-name Lovelace --email ada@berkeley.edu # whole class from a CSV with header: username,first_name,last_name,email,section gh teacher roster import Berkeley-CS-264 cs264 roster.csv # students whose GitHub usernames you do not know yet: invite by email, one address per line gh teacher roster invite Berkeley-CS-264 cs264 --file emails.txt gh teacher roster sync Berkeley-CS-264 cs264 --write # later: record who accepted gh teacher roster list Berkeley-CS-264 cs264
GitHub limits organizations on the Free plan (or younger than one month) to 50 invitations per day, 500 otherwise.
gh teacher staff add Berkeley-CS-264 cs264 <username> --role ta # or --role hta for a head TA
gh teacher assignment add Berkeley-CS-264 cs264 hw2 \ --name "Homework 2" \ --template Berkeley-CS-264/cs264-hw2 \ --due 2026-10-15T23:59:00-07:00 \ --runtime reports/cs264-classroom/hw1-runtime.json \ --tests reports/cs264-classroom/hw1-tests.json
The template repository must have the Template repository flag set (as cs264-hw1 already does) and must not contain .github/workflows/autograde.yaml. To add a due date to hw1, re-run its assignment add with --due, re-passing --template, --runtime and --tests (a re-add rebuilds the whole entry).
gh workflow run collect-scores.yaml --repo Berkeley-CS-264/classroom50 # refresh cs264/scores.json gh teacher download Berkeley-CS-264 cs264 hw1 # clone every student repo locally
The default grades every push to main; each run bills at least one Actions minute against the organization's quota (2,000 minutes per month on Free, 3,000 on Team) and the $0 overage cap set today means grading simply stops when the quota is exhausted. To grade only explicit submissions:
gh teacher assignment submission-mode Berkeley-CS-264 cs264 hw1 --tag
A copy-ready handout is in reports/cs264-classroom/student-instructions.md. In short:
gh extension install foundation50/gh-student gh student login gh student accept Berkeley-CS-264 cs264 hw1 # creates Berkeley-CS-264/cs264-hw1-<username> # ... work, commit ... gh student submit # or plain git push to main
Browser alternative: classroom50.org/Berkeley-CS-264/cs264/assignments/hw1/accept. Scores appear as a Release on the student's repository (tag submit/<timestamp>-<sha>) and as a commit status.
cs264-hw1, including its history. Never commit a solution (or a commit that once contained one) to a template repository.classroom50/cs264/autograders/hw1/ is served by the organization's Pages site. Keep reference solutions out of it, and use failure-details: actual-only on tests whose expected output would give the answer away.hw1 runs the template's own tests/. Students receive those tests, so they can see exactly what is checked. For hidden tests, put them under cs264/autograders/hw1/ in the classroom50 repository and run python3 -m pytest -q "$CLASSROOM50_BUNDLE_DIR".gh teacher rotate-service-token Berkeley-CS-264.reports/cs264-classroom/index.html: this reportreports/cs264-classroom/student-instructions.md: handout for studentsreports/cs264-classroom/hw1-runtime.json, hw1-tests.json: the grading configuration registered for hw1, reusable for later homeworks