Skip to content

feat(gateway): forward /api/github to the github service - #179

Merged
Bakhomious merged 10 commits into
mainfrom
step/github-gateway
Oct 30, 2026
Merged

Bakhomious merged 10 commits into
mainfrom
step/github-gateway

Conversation

@Bakhomious

@Bakhomious Bakhomious commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Brief

Goal: the gateway forwards /api/github to the github service, behind both of its locks, so the app reaches my three lists at GET /api/github/mine, GET /api/github/reviews and GET /api/github/issues. The fifth of github-widgets' nine steps (decision 200).

Scope

  • github becomes one of the gateway's peers, each of which BAKHYARD_PEERS must name, and /api/github is forwarded behind the Tailscale lock and the session lock, with the session cookie hidden, as for every service.
  • mise run up names the peer and starts the gateway once github is healthy; the end-to-end gateway names it too.
  • docs/setup.md and docs/plan.md follow.

Out of scope

  • The lists in the app (github-page) and the Home's "Needs you" (github-attention), along with naming github among the local home's peers.
  • Running github on the laptop: codedogapp/homelab#43.

Acceptance criteria

  1. Without github in BAKHYARD_PEERS, the gateway doesn't start, and its error names the peer, a line for each missing one.
  2. With the Tailscale login and a live session, every method and path under /api/github reaches github as /github/…: GET /api/github/mine reaches GET /github/mine.
  3. Without a session, /api/github/… gets 401; without the Tailscale login, 403, session or not. github gets neither.
  4. github never sees the session cookie, while other cookies reach it, and the request renews the session.
  5. When github can't be reached, /api/github/… gets the gateway's 503 {"code":"unavailable","message":"github is unavailable"}.
  6. The end-to-end gateway forwards /api/github too, and Playwright's gateway names the peer.
  7. mise run up's gateway names github=tcp://127.0.0.1:8089 and depends_on github's health.
  8. The docs say all this.

Merge order: not before codedogapp/homelab#43 has merged and the laptop runs github. Flux deploys each new gateway image by itself, and the gateway won't start without the peer (decision 200), as codedogapp/homelab#42 went before #151. codedogapp/homelab#43 merged on 2026-10-30, and the laptop runs github (see QA).

What changed

  • services/gateway: github in upstreams and peers(), and proxy.Register(api, "github", …) in the API's group.
  • Tests: the forward table, the missing-peer table, the 401 table, the session-hiding table, the open gateway's table, and the two tables of the Tailscale lock (QA's rows); every test's BAKHYARD_PEERS names github.
  • process-compose.yaml: the gateway's peers and depends_on; apps/web/playwright.config.ts: the end-to-end gateway's peers.
  • docs/setup.md: the gateway waits for github, and forwards /api/github to it. docs/plan.md: §0's row, the §4 table's peers, §4.9's depends_on; after merging main, each of github-widgets' rows counts nine steps, as decisions 205 and 206 made it, where the older ones still said seven or eight; and, now that codedogapp/homelab#43 runs github on the laptop, homelab-github and github-widgets are done in §0 and §8.2.

QA

  • Every acceptance criterion has a test: 1 TestTheGatewayNeedsItsPeers; 2 TestTheGatewayForwardsEachAPIToItsService, TestTheGatewayLetsTheUserIn; 3 TestTheGatewayNeedsASessionForTheAPIOnly, TestTheGatewayRefusesEveryoneElse; 4 TestTheGatewayKeepsTheSessionFromTheServices; 6 TestTheOpenGatewayLetsEveryRequestThrough and the end-to-end run; 5 is the proxy's own, shown live below.
  • Mutants, each run against the gateway's tests: 9 of 9 killed. No github route; github outside both locks; behind the Tailscale lock only; behind the session lock alone; forwarded to home; under another name; a missing peer that's no error; github given home's URL; the upstream set to home's (killed by the compiler).
  • The session-lock-alone mutant survived the engineer's tests, since neither table of the Tailscale lock named /api/github; QA added a row to each (the second commit).
  • Playwright without 'github': the end-to-end gateway exits with BAKHYARD_PEERS has no peer "github", and the run fails.
  • process-compose.yaml, read with a YAML parser: the gateway's 10 peers, games' included, are exactly its depends_on, each process_healthy, and each peer's address is that process's BAKHYARD_LISTEN and probe port; process-compose up --dry-run validates 12 processes.
  • Live, with the binaries built from this branch, on ports 8284 to 8292:
    • The end-to-end gateway, with github in front of a stand-in GitHub, answered each of the three lists through /api/github/… with github's JSON, and passed on github's own 404 and 405.
    • With github stopped: 503 {"code":"unavailable","message":"github is unavailable"}, and the gateway logged upstream unavailable upstream=github.
    • The real gateway without the peer exited 1 with BAKHYARD_PEERS has no peer "github"; with it, it moved on to the next setting.
  • On the laptop, read-only, after codedogapp/homelab#43: github's pod Running with its Secret, and no failed search in its log; its three lists, 3, 0 and 1 items, match the gh CLI's searches item for item; Home's sources are all ok, github's included, with its 4 items.

Review

No blocking findings. Non-blocking:

  • The Tailscale lock's tables still don't name /api/time, /api/notify or /api/nudge; built from peerNames(), they'd stay complete as peers come. Older than this step.
  • TestOnlyTheEndToEndBuildIsOpen now takes its peers from withPeers(), the same full list, rather than a third copy of it.

Gates

mise run check green: fmt:check, lint (golangci-lint 0 issues, buf lint, config verify), lint:actions, lint:compose, gen:check, vuln, go test -race and cover (97.1% total; the gateway 92.2%), proto:breaking, and the web's lint, typecheck, test (1,341), unused, audit, build and end-to-end tests (438 passed, 8 skipped), with BAKHYARD_E2E_PORT=8280, on the head with main merged in (2ac639b; #188's games peer beside github, in alphabetical order).

The GitHub page and Home's "Needs you" need my lists through the
gateway. The gateway now requires a github peer and forwards
/api/github behind both locks, hiding the session cookie as for every
service. mise run up starts the gateway once github is healthy, and
the end-to-end gateway names the peer too.
A github route behind the session lock alone passed every test, since
the tables of the Tailscale lock didn't name /api/github.
# Conflicts:
#	docs/plan.md
#	docs/setup.md
The rows written before decisions 205 and 206 added two steps still said seven or eight.
# Conflicts:
#	apps/web/playwright.config.ts
#	docs/plan.md
#	docs/setup.md
#	process-compose.yaml
#	services/gateway/headers_test.go
#	services/gateway/lock_test.go
#	services/gateway/main.go
#	services/gateway/main_test.go
#	services/gateway/open_test.go
#	services/gateway/peers_test.go
#	services/gateway/router.go
codedogapp/homelab#43 runs github on the laptop with the user's token, so the gateway can require it now, and this step finishes the feature.
@Bakhomious
Bakhomious merged commit 0808234 into main Oct 30, 2026
2 checks passed
@Bakhomious
Bakhomious deleted the step/github-gateway branch October 30, 2026 12:09
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.

1 participant