Skip to content

S60: REST GitHub-compat envelopes (user, labels, base/head, /users/{name})#301

Merged
mfwolffe merged 11 commits into
trunkfrom
s60/rest-github-compat-envelopes
May 17, 2026
Merged

S60: REST GitHub-compat envelopes (user, labels, base/head, /users/{name})#301
mfwolffe merged 11 commits into
trunkfrom
s60/rest-github-compat-envelopes

Conversation

@espadonne
Copy link
Copy Markdown
Contributor

Summary

Bundles four audit findings from the 2026-05-17 dogfood pass
(A01-dogfood-audit) — all "server REST shape doesn't match
GitHub-compat" — into a single response-envelope refresh. Unblocks
six broken CLI flows in one PR.

  • A12author_id: 1 (flat FK) was the only author signal on
    issue/PR/comment responses; the CLI's user.{login,id} decoder
    rendered every author as "ghost". Each response now ships a
    user: {id, login, type, html_url} envelope alongside the legacy
    author_id. List endpoints batch-resolve the unique author set
    via ListUsersByIDs so we don't fan out one query per row.
  • A14labels: ["bug"] (string array) made the CLI's
    strongly-typed issues.Label{Name, Color, …} decoder panic on
    every labeled issue. issue view, issue close, and
    issue reopen were all unusable as a result. Now emits
    [{id, name, color, description}] via a shared
    presentLabelEnvelopes helper.
  • A16 — flat base_ref / head_ref / base_oid / head_oid
    on the PR response left shithub pr view rendering
    base: ← head: (empty). Added nested
    base: {ref, sha} / head: {ref, sha} envelopes; flat fields
    retained for one release cycle.
  • A5 — added GET /api/v1/users/{username} (the gh-compat
    public-profile lookup, distinct from /user which is the
    authenticated own-profile path). Returns a trimmed envelope
    (no email-verified flag, no plan, no admin markers). user:read
    scope. Capability list grew a users entry.

/api/v1/user itself now emits both username (legacy) and login
(gh-canonical) so transitional clients reading either field work.

The shared helpers live in a new
internal/web/handlers/api/envelopes.go. Single-issue / create
paths use resolveUserEnvelope (one extra GetUserByID); list
endpoints use resolveUserEnvelopesBatch (one ListUsersByIDs
with a dedup pass).

Test coverage:

  • TestIssues_UserEnvelope — create + get + comment exercise both
    resolveUserEnvelope paths.
  • TestPulls_CreateAndGet extended — asserts nested base/head
    • user envelope alongside the existing legacy assertions.
  • TestCrossCutting_UsersByName happy path + 404 case.
  • TestIssues_PatchAttachLabelAndMilestone updated to read
    Labels[0].Name (object shape) instead of the bare string.

Test plan

  • go build ./...
  • SHITHUB_TEST_DATABASE_URL=... go test ./... -count=1 (green across the repo)
  • scripts/lint-migration-versions.sh + scripts/lint-unused.sh (clean)
  • gofumpt -l clean on touched files

Follow-ups

Paired CLI sprint (C25b in the audit doc) picks up the remaining
ergonomics items (success-line messages, completion positional arg,
template newline, etc.). The mergeability worker is its own
sprint (A17/A20).

@mfwolffe mfwolffe merged commit 282e2a1 into trunk May 17, 2026
1 check passed
@mfwolffe mfwolffe deleted the s60/rest-github-compat-envelopes branch May 17, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants