classroom50

gh-student

A gh CLI extension targeted at students. Written in Go using go-gh and cobra.

End-user documentation lives in the wiki — install, walkthrough, and full command reference:

Document new features on the wiki (source: wiki/), not in this README. This file is for contributors building and testing the extension locally.

Local development

First-time setup:

cd cli/gh-student
go mod tidy

Build and register as a gh extension from your local checkout:

go build .
gh extension install .

Re-run go build . after code changes; gh extension install . only needs to run once.

To debug REST calls, set GH_DEBUG=api (honored by go-gh) to log every request and response.

Local checks

Install Go and golangci-lint once:

brew install go golangci-lint

Run all CI checks locally before pushing:

golangci-lint fmt && go mod tidy && golangci-lint run && go build ./... && go test ./...

If that exits 0, CI will pass. golangci-lint fmt applies both gofmt and goimports (configured in .golangci.yaml) so import grouping stays consistent across files. The same checks run in gh-student-ci.yaml.

VSCode users: install the Go extension and add this to .vscode/settings.json for format-and-lint on save:

{
  "go.lintTool": "golangci-lint",
  "go.lintOnSave": "package",
  "go.formatTool": "gofmt"
}

Layout

main.go defines the cobra root command and registers subcommands. Each subcommand lives in its own file (whoami.go, accept.go, …) exposing a <name>Cmd() factory function. To add a new command, copy an existing file and follow the same pattern: factory returns *cobra.Command, write to cmd.OutOrStdout(), wrap errors with fmt.Errorf("ctx: %w", err).

Accept and submit lean on three shared modules:

Submit is intentionally minimal: submitCmd refreshes the template repo’s .gitignore and .github/ (both optional, fetched from the template ref recorded in .classroom50.yaml), then commits + pushes to main. The autograde shim itself is set once at accept time and never refreshed — actual grading logic lives in the teacher’s config repo (the org-level runner-side bootstrap .github/scripts/runner.py, the optional classroom default <classroom>/autograder.py, and optional per-assignment overrides under <classroom>/autograders/<slug>/autograder.py), all fetched from the teacher’s Pages site at workflow runtime. The runner workflow auto-tags the pushed commit and publishes a release at the submit tag.

Distribution

Currently install-from-source only. Cross-platform binary releases via cli/gh-extension-precompile are deferred until this extension lives in its own repository (gh extension install <owner>/<repo> resolves the binary by repo name, which only matches once gh-student is the repo).