← all case studies
go-github + octokit

Mock the GitHub API locally — octokit pagination, go-github CRUD, signed webhooks

octokit.paginate walks the mock’s Link headers page by page — go-github drives the same CRUD in Go.

Set up

One service block in stunt.yaml, then stunt up. The webhook_url is your test process — that's where signed deliveries land.

services:
  github:
    adapter: ./adapters/github-style
stunt catalog add github-style
stunt up
# go-github: client.BaseURL = mock URL, token ghp_pat_token_mock
# octokit: new Octokit({ baseUrl, auth: "ghp_pat_token_mock" })

What the suite proves

Asserted by the conformance suites in stunt's CI — not marketing copy. Every check below is a passing assertion:

  • 01Issues.Create assigns numbers; state transitions (open → closed) round-trip
  • 02go-github parses Link headers into resp.NextPage and walks them
  • 03octokit.paginate follows the Link header URL itself — every page, through the SDK’s own pagination machinery
  • 04Comments create + list round-trip
  • 05Webhook deliveries carry X-Hub-Signature-256 computed with the per-hook secret

Bugs the harness caught

The Link headers pointed at the real api.github.com

The mock’s pagination Link headers embedded hardcoded absolute URLs to api.github.com. go-github never noticed — it only parses the page params — but octokit.paginate FOLLOWS the URL, and walked straight off the mock into the real GitHub, 401ing. Only driving a client that actually follows the header caught it; Link targets now build from the serving host.

One mock serves both SDK families, and the octokit suite runs through the real stunt binary — boot, runtime file, ports — so the CLI is exercised too.