Skip to content

feat: add --account flag and GH_ACCOUNT env var for per-command account selection - #12853

Closed
tmehlinger wants to merge 10 commits into
cli:trunkfrom
tmehlinger:improve-auth
Closed

tmehlinger wants to merge 10 commits into
cli:trunkfrom
tmehlinger:improve-auth

Conversation

@tmehlinger

@tmehlinger tmehlinger commented Mar 6, 2026 •

Copy link
Copy Markdown

Note: I know the contribution guidelines say to open issues first and only push PRs for issues flagged help-wanted. However, there are only three such issues, and this is a real pain point using the CLI that's been around a long time. This fix would benefit everyone, including all the users who have commented on #326 with workarounds for the statefulness of the tool.

Summary

  • Adds a --account user@host persistent flag and GH_ACCOUNT environment variable that lets users specify which authenticated account to use per-command, eliminating the need to globally switch accounts with gh auth switch
  • Overrides token resolution, active user, and default host for the duration of the command without modifying any persisted configuration
  • Validates the account exists in config, fails loud on errors, and respects GH_TOKEN precedence with a warning

Closes #326

Test plan

  • Unit tests for ParseAccount parser (7 cases)
  • Unit tests for ActiveToken, ActiveUser, DefaultHost override behavior (4 cases)
  • Integration tests for applyAccountOverride (8 cases covering flag, env var, precedence, errors, GH_TOKEN, auth mutation guard, no-op)
  • Full go test ./... passes
  • Manual testing with --account user@host against real repos

🤖 Generated with Claude Code

tmehlinger and others added 10 commits March 5, 2026 22:01
When accountOverride is set, ActiveUser returns the overridden user for
the matching host, and ActiveToken bypasses the global oauth_token
lookup to fetch the per-user token directly via TokenForUser.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Authentication() was creating a new AuthConfig struct on every call,
so the account override set in PersistentPreRunE was lost when the
HTTP client resolved its token via a separate Authentication() call.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Store parsed user/host fields instead of raw string, eliminating
  redundant ParseAccount() calls in ActiveToken/ActiveUser/DefaultHost
- Fix critical bug: ActiveToken() no longer silently falls through to
  the wrong account when the override account's token lookup fails
- Use slices.Contains for account validation in applyAccountOverride
- Add end-to-end token assertions to integration tests

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Change SetAccountOverride(account string) to SetAccountOverride(user, host string)
  to eliminate redundant ParseAccount call and silent error swallowing
- Replace map allocation in isAuthMutationCommand with slices.Contains
- Use strings.Builder in accountNotFoundError instead of repeated concatenation

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@tmehlinger
tmehlinger requested a review from a team as a code owner March 6, 2026 17:39
@tmehlinger
tmehlinger requested a review from BagToad March 6, 2026 17:39
@github-actions github-actions Bot added external pull request originating outside of the CLI core team needs-triage needs to be reviewed unmet-requirements and removed needs-triage needs to be reviewed labels Mar 6, 2026
@github-actions

github-actions Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

Thanks for your pull request! Unfortunately, it doesn't meet the minimum requirements for review:

  • None of the referenced issues have the help wanted label

Please update your PR to address the above. Requirements:

  1. Include a detailed description of what this PR does
  2. Link to an issue with the help wanted label (use Fixes #123 or Closes #123 if it resolves the issue)

This PR will be automatically closed in 7 days if these requirements are not met.

@tmehlinger

Copy link
Copy Markdown
Author

None of the referenced issues have the help wanted label

Yep, I made a note about that.

Include a detailed description of what this PR does

I did.

Link to an issue with the help wanted label (use Fixes #123 or Closes #123 if it resolves the issue)

I did that too.

@williammartin

Copy link
Copy Markdown
Member

#12145 is probably the actual issue your solving here, rather than the #326 which probably needs closed in favour of many other individual issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external pull request originating outside of the CLI core team unmet-requirements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow multiple account credentials

2 participants