Skip to content

fix: name the host a GitHub account lives on - #109

Merged
omartelo merged 1 commit into
mainfrom
fix/gh-account-host
Jul 27, 2026
Merged

omartelo merged 1 commit into
mainfrom
fix/gh-account-host

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Why

#107 stored a GitHub account as its login alone. A login only identifies an account within one host, and gh auth token --user <login> looks it up on gh's default host only:

$ gh auth token --user naoexiste
no oauth token found for github.com account naoexiste

So an account authenticated on a GitHub Enterprise instance was listed in the picker, chosen by the user, not found by gh — and tokenFor fell back to the active account without a word. That silent fallback is the exact failure the account picker exists to prevent, and it hit precisely the people most likely to need the picker: anyone whose repositories live on an enterprise host.

The same login on two hosts was also a single ambiguous entry.

Worth saying plainly: nothing about the hostname can be inferred. git resolves a host through the ssh config — which is free to point github.com at an enterprise server — while gh reads the hostname from the remote and talks to that name's API. The two can reach different servers with no sign in the URL, so the host has to be carried, never guessed.

What changed

  • An account is "<host>/<login>". The parser keeps the host gh auth status already prints, and tokenArgs names it back with --hostname.
  • A value stored without a host still resolves on gh's default host, which is where it was found — no migration required to keep working.
  • It is rewritten to the full form the moment gh says which host it lives on (upgradeAccount), and only when exactly one host claims that login. Otherwise the picker would list one account twice, once in each form. A login gh no longer knows is left alone, so it stays visible and changeable.
  • The picker spells the host out only when there is more than one in play, or when it is not github.com — on a single-host machine it would be the same word on every row.
  • The label logic moved to src/lib/gh-account.ts: it is pure, and in a .tsx the node-only test gate could not reach it.

Test plan

  • Against the real gh: project.GitHubAccounts now answers ["github.com/omartelo", "github.com/marcelo-filho_snk"].
  • Against the real private repository, over the RPC: the legacy value (marcelo-filho_snk, the form already in my DB) resolves and lists the PRs; the host-qualified value (github.com/marcelo-filho_snk) resolves identically.
  • TestTokenArgs pins all three shapes — github.com, an enterprise host, and the host-less legacy form.
  • upgradeAccount covered for: one host claims the login, two hosts claim it (refuses to guess), gh no longer knows it, already upgraded, empty.
  • go test ./..., gofmt -l ., go vet ./... clean; vitest 480 passed, biome check 0 errors, tsc --noEmit clean, vite build ok.
  • Cross-compile loop for linux/darwin/windows (build + vet).
  • No enterprise instance to test against here — the enterprise path is covered by the arguments lich builds, not by a live GHE round-trip.

🤖 Generated with Claude Code

A login only identifies an account within one host. lich stored the login
alone, and `gh auth token --user <login>` looks a login up on gh's default
host only:

    $ gh auth token --user naoexiste
    no oauth token found for github.com account naoexiste

So an account authenticated on a GitHub Enterprise instance was offered in
the picker, chosen, not found, and every call fell back to gh's active
account — silently, which is the failure the account picker exists to
prevent. Two hosts holding the same login were the same entry twice.

An account is now "<host>/<login>": the parser keeps the host `gh auth
status` already prints, and the token lookup names it back. A value stored
without a host still resolves on the default host, which is where it was
found, and is rewritten the moment gh says which host that is — otherwise
the picker would list one account twice, once in each form. The host is
spelled out in the picker only when there is more than one in play.
@omartelo
omartelo merged commit aa79711 into main Jul 27, 2026
3 checks passed
@omartelo
omartelo deleted the fix/gh-account-host branch July 27, 2026 18:30
@omartelo omartelo mentioned this pull request Jul 27, 2026
6 tasks done
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