Extending the GitHub Classroom CLI

The GitHub Classroom extension for the GitHub CLI brings classroom management into the terminal, but no tool can cover every teaching workflow out of the box. Since the extension is open source, you can add commands that fit your own classroom needs and contribute them back. Here is a practical walkthrough of what that process involves.

Before You Start

The extension is written in Go, so contributions arrive as pull requests from your personal fork. The repository's contribution guidelines walk through the setup steps. Before writing any code, decide which feature you want to build. The current command set includes:

  • accepted-assignments: List student accepted assignments
  • assignment: Show assignment details
  • assignment-grades: Download a CSV of grades for an assignment
  • assignments: List assignments for a classroom
  • clone: Clone starter code or student submissions
  • list: List classrooms
  • view: Show classroom details

If you have a new feature in mind, open an issue describing the command request before you begin. For those looking for existing work, filter the open issues by the enhancement or bug labels, assign yourself, and link your pull request to the issue you pick up.

Check the Data Path

Before you build anything, confirm the data you need is reachable through the GitHub Classroom REST API. The API documentation lists available endpoints. For example, the assignment-grades command relies on the /assignment/:id/grades endpoint, and the helper library in pkg/classroom/http.go provides a simpler way to query those endpoints.

func GetAssignmentGrades(client api.RESTClient, assignmentID int) ([]AssignmentGrade, error) {
    var response []AssignmentGrade
    err := client.Get(fmt.Sprintf("assignments/%v/grades", assignmentID), &response)
    if err != nil {
        return nil, err
    }
    return response, nil
}

If no public endpoint exposes the data you need, do not start hacking around it. Open an issue describing the information required for the feature. The maintainers will triage it to unblock you.

Creating the Package

Each command lives in its own Go package. The assignment-grades command, for instance, sits in a package called grades. To begin your own command, create a new package directory and its files from the fork root:

mkdir ./cmd/gh-classroom/$my-feature-name && cd ./cmd/gh-classroom/$my-feature-name
touch $my-feature-name.go $my-feature-name-test.go

Each new file starts with a package $my-feature-name declaration so the files belong to the same package.

Implementation and Testing

Existing commands in the cmd/gh-classroom directory double as reference implementations. Study their structure and their test files when you write your own code. Run the test suite from the fork root with the project's standard commands:

go test -v ./…
golangci-lint run

All tests must pass and new code needs full coverage before reviewers will consider merging it.

Registering the Command

A new package does nothing on its own: it must be wired into the CLI's root package. At cmd/gh-classroom/root/root.go, the AddCommand helper registers each command, which is how the CLI knows it exists. The registration logic follows the pattern of other commands in that file.

cmd.AddCommand(assignmentgrades.NewCmdAssignmentGrades(f))

Sending Your Work Upstream

After your code is merged-ready, commit and push to your fork. Read the contribution guidelines prior to opening your pull request so your changes align with project conventions. Then open a pull request against the github/gh-classroom repository.

The Review Cycle

Maintainers will respond with comments, requested changes, or approval. Note that a feature request is not guaranteed to be accepted; some ideas may not fit the project direction. Reviews aim to be timely, but community-maintained projects can take a moment to get back to you.

Shipping Your Command

Once the pull request is merged and an administrator triggers a release, the GitHub Action in the repository handles the release build. To install it, upgrade your extension with gh extension upgrade classroom. Your new command will then show up in the output of gh classroom -h.

The Classroom CLI will only keep covering the range of teaching styles if people build the pieces they need. If you hit an issue or have questions along the way, open an issue in the gh-classroom repository.