Skip to content

Enhance GitHub host detection for PAT creation and setup commands#46128

Merged
mnkiefer merged 5 commits into
mainfrom
support-other-hosts
Jul 17, 2026
Merged

Enhance GitHub host detection for PAT creation and setup commands#46128
mnkiefer merged 5 commits into
mainfrom
support-other-hosts

Conversation

@mnkiefer

@mnkiefer mnkiefer commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds implicit GitHub Enterprise Server (GHES) host detection to setup auth, setup repository check, tokens bootstrap, and PAT URL construction. When GH_HOST is unset, the implementation parses the origin remote URL at command entry to determine the target host, eliminating hardcoded github.com references that caused GHES users to receive incorrect PAT creation URLs and auth guidance.

Changes

Core implementation (pkg/cli/)

  • setup_repository.go: Added configureDefaultGHHostFromOriginRemoteIfUnset(). When GH_HOST is unset, calls getHostFromOriginRemote() and invokes workflow.SetDefaultGHHost(detectedHost) for non-github.com hosts. Called at the entry of runSetupAuthWithRuntime and runSetupRepositoryCheckWithRuntime.
  • tokens_bootstrap.go: Calls configureDefaultGHHostFromOriginRemoteIfUnset() at the start of runTokensBootstrap so secret discovery and upload target the correct host.
  • engine_secrets.go:
    • Refactored buildCopilotPATCreationURL to delegate to a new shared buildPATCreationURL(values url.Values) helper.
    • Added buildGenericPATCreationURL() for system token flows.
    • Added isAnyGitHubHostEnvVarSet() — checks GITHUB_SERVER_URL, GITHUB_ENTERPRISE_HOST, GITHUB_HOST, GH_HOST.
    • buildPATCreationURL uses the git remote host when no host env var is set and the detected host is not github.com.
    • promptForSystemTokenUnified: replaced hardcoded https://github.com/settings/personal-access-tokens/new with buildGenericPATCreationURL().
  • doctor_command.go: Extended Long description to document GHES auto-detection and manual fallback (gh auth login --hostname <host> + GH_HOST=<host>).

Tests (pkg/cli/)

  • engine_secrets_test.go: Expanded TestBuildCopilotPATCreationURL into 3 subtests: defaults to github.com outside a git repo with no env vars; uses GH_HOST when set; falls back to origin remote host when all host env vars are unset.
  • doctor_command_test.go: Added TestDoctorCommandLongMentionsEnterpriseHostFallback; added integration tests TestRunSetupAuthAutoDetectsDefaultGHHost and TestRunSetupRepositoryCheckAutoDetectsDefaultGHHost using real temporary git repos.
  • cli_consistency_help_test.go: Added assertion that doctor docs mention the enterprise host fallback.

Documentation

  • docs/adr/46128-auto-detect-ghes-host-from-git-remote.md (new): Draft ADR recording context, decision, alternatives considered, and consequences.
  • docs/src/content/docs/setup/cli.md: Added paragraph to doctor section documenting auto-detection behavior and fallback.

Behaviour

Condition Result
Any host env var set (GH_HOST, GITHUB_SERVER_URL, etc.) Env var takes precedence; git remote not consulted
No host env var; origin remote points to GHES Detected host used for PAT URLs and gh auth calls
No host env var; origin remote is github.com or absent Falls back to github.com

Limitations (documented in ADR)

  • Behavior is coupled to CWD git state; commands outside a git repo silently fall back to github.com.
  • Adds filesystem I/O at command startup.
  • Mirror/proxy remotes pointing to a non-canonical host will produce incorrect detection.

Generated by PR Description Updater for #46128 · 44 AIC · ⌖ 7.08 AIC · ⊞ 4.7K ·

@mnkiefer mnkiefer self-assigned this Jul 17, 2026
@mnkiefer
mnkiefer marked this pull request as ready for review July 17, 2026 04:57
Copilot AI review requested due to automatic review settings July 17, 2026 04:57
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enhances GHES host detection for diagnostics and PAT creation.

Changes:

  • Detects GHES hosts from Git remotes for setup checks.
  • Generates host-specific PAT creation URLs.
  • Adds tests and enterprise-host guidance.
Show a summary per file
File Description
pkg/cli/setup_repository.go Configures detected hosts for setup checks.
pkg/cli/engine_secrets.go Builds host-specific PAT URLs.
pkg/cli/engine_secrets_test.go Tests PAT URL host selection.
pkg/cli/doctor_command.go Adds enterprise-host help.
pkg/cli/doctor_command_test.go Tests detection and help text.
pkg/cli/cli_consistency_help_test.go Validates generated documentation.
docs/src/content/docs/setup/cli.md Documents doctor host detection.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 7/7 changed files
  • Comments generated: 7
  • Review effort level: Medium

Comment thread pkg/cli/engine_secrets.go Outdated
Comment thread pkg/cli/engine_secrets.go
Comment thread pkg/cli/engine_secrets_test.go
Comment thread pkg/cli/engine_secrets_test.go
Comment thread pkg/cli/doctor_command.go Outdated
Comment thread docs/src/content/docs/setup/cli.md Outdated
Comment thread pkg/cli/cli_consistency_help_test.go Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /codebase-design, /diagnosing-bugs, and /tdd — requesting changes on test reliability and a design duplication issue.

📋 Key Themes & Highlights

Key Themes

  • Duplicated host detectionbuildPATCreationURL re-implements the same origin-remote fallback that configureDefaultGHHostFromOriginRemoteIfUnset already provides, creating a divergence risk.
  • Fragile test assertions — The checkAuth stubs derive the host from a live gh subprocess rather than from the in-process state, making assertions environment-sensitive and potentially silently vacuous in CI.
  • Test-helper inconsistency — The new engine_secrets_test.go sub-test uses raw exec.Command + os.Chdir + defer while the new doctor_command_test.go tests correctly use testutil.TempDir + t.Chdir + initTestGitRepo.

Positive Highlights

  • ✅ Good layering: buildPATCreationURL is correctly extracted as a shared helper.
  • configureDefaultGHHostFromOriginRemoteIfUnset is well-named and fits the existing pattern.
  • ✅ Solid documentation update — the doc prose and help text are in sync.
  • ✅ The new sub-table test structure for TestBuildCopilotPATCreationURL is much more readable.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 36.2 AIC · ⌖ 7.27 AIC · ⊞ 6.7K
Comment /matt to run again

Comment thread pkg/cli/engine_secrets.go Outdated
Comment thread pkg/cli/setup_repository.go
Comment thread pkg/cli/engine_secrets_test.go Outdated
Comment thread pkg/cli/doctor_command_test.go
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 75/100 — Acceptable

Analyzed 7 test(s): 7 design, 0 implementation, 0 violation(s).

📊 Metrics (7 tests)
Metric Value
Analyzed 7 (Go: 7, JS: 0)
✅ Design 7 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 5 (71%)
Duplicate clusters 0
Inflation YES (2 files exceed 2:1)
🚨 Violations 0
📋 Test Classification Details

doctor_command_test.go (3 new tests):

  • TestDoctorCommandLongMentionsEnterpriseHostFallbackdesign_test, validates doc content consistency ✅
  • TestRunSetupAuthAutoDetectsDefaultGHHostdesign_test, integration-style test validates host detection from git remote ✅
  • TestRunSetupRepositoryCheckAutoDetectsDefaultGHHostdesign_test, integration-style test validates host fallback behavior ✅

engine_secrets_test.go (3 new table-driven subtests):

  • "defaults to public github" — design_test, ensures github.com fallback ✅
  • "uses GH_HOST when gh auth is configured for enterprise" — design_test, env override behavior ✅
  • "falls back to origin remote host when GH_HOST is unset" — design_test, git remote fallback with setup/cleanup ✅

cli_consistency_help_test.go (1 assertion addition):

  • Extended TestCLIDocsReflectStatusAuditAndExperimentsCommandsdesign_test, validates docs mention enterprise host guidance ✅
📈 Test Inflation Analysis
File Test Lines Prod Lines Ratio Assessment
doctor_command_test.go +77 +5 15.4:1 Exceeds threshold (justified: git setup, env cleanup, multi-function mocking)
engine_secrets_test.go +58 (net) +22 2.6:1 Exceeds threshold (justified: tempdir+git init, 3 environmental scenarios)
cli_consistency_help_test.go +1 +17 0.06:1 ✅ Acceptable

Justification: Integration-style tests with substantial infrastructure setup (git operations, filesystem manipulation, environment variables) naturally have higher line counts than production code changes.

Verdict

Passed. 0% implementation tests (threshold: 30%). No coding guideline violations. All tests verify behavioral contracts for GitHub host detection feature.

Key strengths:

  • 100% of new tests verify design contracts, not implementation details
  • 71% cover error/edge cases (git remote fallback, env var handling)
  • No mock libraries or forbidden patterns
  • All Go tests have required build tags
  • Integration tests properly set up and clean up state

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 16.5 AIC · ⌖ 13.3 AIC · ⊞ 6.8K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 75/100. All 7 new/modified tests verify behavioral contracts for GitHub host detection. 0% implementation tests (threshold: 30%). No coding guideline violations. Well-designed integration tests with proper infrastructure setup and cleanup.

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (180 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/46128-auto-detect-ghes-host-from-git-remote.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI could not infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-46128: Auto-Detect GitHub Enterprise Host from Git Remote When GH_HOST Is Unset

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 46128-auto-detect-ghes-host-from-git-remote.md for PR #46128).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · 54.6 AIC · ⌖ 13.8 AIC · ⊞ 8.5K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Enhance GitHub host detection for PAT creation and setup commands

Good direction — auto-detecting the GHES host from the git remote and plumbing it through to PAT URLs is the right behaviour. Two blocking correctness issues found.

Blocking issues

  1. Incomplete guard in configureDefaultGHHostFromOriginRemoteIfUnset (inline comment on setup_repository.go:21): the early-return only checks GH_HOST, but parser.GetGitHubHost() honours four env vars (GITHUB_SERVER_URL, GITHUB_ENTERPRISE_HOST, GITHUB_HOST, GH_HOST). In a standard GitHub Actions run against GHES, GITHUB_SERVER_URL is set but GH_HOST is empty, so the guard does not fire — origin-detection runs and SetDefaultGHHost potentially overwrites an already-correct host.

  2. Duplicate host-detection in buildPATCreationURL (inline comment on engine_secrets.go:413): this function independently re-implements the same guard and fallback logic with the same GH_HOST-only blind spot. The two paths will drift; fixing #1 will not automatically fix this one.

Non-blocking

  • buildGenericPATCreationURL is a one-liner wrapper with no dedicated tests; consider inlining it to reduce indirection.
  • Tests in engine_secrets_test.go manually call exec.Command("git", ...) instead of using the initTestGitRepo/addOriginRemoteToTestRepo helpers already used elsewhere in the package — worth consolidating for consistency.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 48.4 AIC · ⌖ 4.72 AIC · ⊞ 5K

Comment thread pkg/cli/setup_repository.go
Comment thread pkg/cli/engine_secrets.go Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GHES host-detection feature is a useful improvement, but has several blocking issues around test correctness and global state management that need to be addressed before merging.

Blocking themes

1. os.Chdir in test — process-wide race

The new TestBuildCopilotPATCreationURL subtest uses os.Chdir/defer os.Chdir instead of t.Chdir(). os.Chdir affects the entire process, not just the current goroutine. Other tests in the same binary that call getHostFromOriginRemote() (which shells out to git in the cwd) will silently pick up the wrong directory. The other two new tests correctly use t.Chdir — fix the subtest to match.

2. exec.Command without context — unbounded hang risk

The git init and git remote add calls in the same subtest have no timeout. Any CI environment with credential helpers or hooks will hang indefinitely.

3. configureDefaultGHHostFromOriginRemoteIfUnset mutates global state as a side effect

workflow.SetDefaultGHHost is a process-wide global. Both runSetupAuthWithRuntime and runSetupRepositoryCheckWithRuntime now unconditionally mutate it as a side effect. The explicit else if detectedHost == "github.com" { SetDefaultGHHost("") } branch also silently resets the global, which can clobber a previously-set value with no explanation. These concerns are detailed in inline comments.

4. Duplicate git subprocess in buildPATCreationURL

buildPATCreationURL independently calls getHostFromOriginRemote() instead of reading the global that configureDefaultGHHostFromOriginRemoteIfUnset already set. This doubles the subprocess cost and introduces a potential TOCTOU inconsistency if the cwd changes between calls.

🔎 Code quality review by PR Code Quality Reviewer · 81.1 AIC · ⌖ 5.12 AIC · ⊞ 5.6K
Comment /review to run again

Comment thread pkg/cli/engine_secrets_test.go Outdated
}
}()

require.NoError(t, os.Chdir(tmpDir))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.Chdir in a subtest mutates the entire process working directory and will race with other test goroutines.

💡 Details and suggested fix

os.Chdir changes the working directory for the whole process, not just the current goroutine. Go runs subtests in the same binary and can schedule goroutines concurrently; any code that implicitly uses the cwd (e.g. getHostFromOriginRemote() which shells out to git remote) will see the wrong directory while this subtest is running.

The defer os.Chdir(originalDir) is also silently logged rather than t.Fatal-ed on failure.

t.Chdir() (Go 1.24+) handles this correctly and is already used in TestRunSetupAuthAutoDetectsDefaultGHHost in the same file:

// Replace this block:
originalDir, err := os.Getwd()
require.NoError(t, err)
defer func() {
    if err := os.Chdir(originalDir); err != nil {
        t.Logf("Warning: failed to restore directory: %v", err)
    }
}()
require.NoError(t, os.Chdir(tmpDir))

// With:
t.Chdir(tmpDir)

Comment thread pkg/cli/engine_secrets_test.go Outdated
Comment thread pkg/cli/setup_repository.go
Comment thread pkg/cli/setup_repository.go
Comment thread pkg/cli/engine_secrets.go
@mnkiefer

Copy link
Copy Markdown
Collaborator Author

@copilot Address all open review comments.

Copilot AI and others added 2 commits July 17, 2026 05:21
Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com>
- Only use git remote fallback in buildPATCreationURL when no host
  env vars (GITHUB_SERVER_URL, GITHUB_ENTERPRISE_HOST, GITHUB_HOST,
  GH_HOST) are explicitly set, preventing a silent override of an
  explicit GH_HOST=github.com selection

- Call configureDefaultGHHostFromOriginRemoteIfUnset() at the start
  of runTokensBootstrap so that secret discovery and upload both
  target the correct GHES host when running in a GHES checkout

- Fix 'defaults to public github' test to clear all host env vars and
  run outside a git checkout to isolate from process environment

- Fix 'uses GH_HOST for enterprise' test to clear higher-priority
  env vars (GITHUB_SERVER_URL etc.) so GH_HOST is actually honoured

- Update doctor command guidance and docs to require both
  authentication (gh auth login --hostname) and GH_HOST for
  repository diagnostics outside a checkout

- Update cli_consistency_help_test.go assertion to match corrected
  guidance text

Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com>

Copilot AI commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@copilot Address all open review comments.

All review comments have been addressed in commit fix: address review feedback on GHES host detection:

  1. buildPATCreationURL remote fallback – Added isAnyGitHubHostEnvVarSet() helper that checks all four env vars consumed by getGitHubHost() (GITHUB_SERVER_URL, GITHUB_ENTERPRISE_HOST, GITHUB_HOST, GH_HOST). The remote fallback is now skipped whenever any of these is set, preventing a silent override of an explicit GH_HOST=github.com choice.

  2. GHES host for secrets bootstrap gh callsrunTokensBootstrap now calls configureDefaultGHHostFromOriginRemoteIfUnset() at its entry point (before secret discovery and upload), so gh secret list/set uses the correct GHES host.

  3. Test "defaults to public github" – Now clears all host env vars and changes to a temp directory (no git remotes) to fully isolate from the process environment and current checkout.

  4. Test "uses GH_HOST for enterprise" – Now clears the higher-priority variables (GITHUB_SERVER_URL, GITHUB_ENTERPRISE_HOST, GITHUB_HOST) before setting GH_HOST, so the lowest-priority variable is actually honoured.

  5. Doctor command guidance and docs – Updated both doctor_command.go and docs/src/content/docs/setup/cli.md to clarify that outside a checkout users need both gh auth login --hostname <host> and GH_HOST=<host> for repository diagnostics. The cli_consistency_help_test.go assertion was updated to match.

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Hey @mnkiefer 👋 — thanks for this improvement to GHES host detection and PAT creation guidance! The change is well-scoped, includes an ADR, tests across doctor_command, engine_secrets, and setup_repository, and the description clearly summarises the intent. This looks ready for review. 🎉

Generated by ✅ Contribution Check · 87.5 AIC · ⌖ 15.7 AIC · ⊞ 6.2K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, review the latest maintainer feedback, address any unresolved review comments, and rerun checks once updated.

Generated by 👨‍🍳 PR Sous Chef · 7.43 AIC · ⌖ 7.38 AIC · ⊞ 7.5K ·
Comment /souschef to run again

- Replace manual os.Getwd + defer os.Chdir + os.Chdir(tmpDir) pattern
  with t.Chdir(tmpDir) in both subtests to avoid mutating the process
  working directory for the duration of the whole process and racing
  with other test goroutines
- Replace exec.Command("git", "init") + exec.Command("git", "remote",
  "add", ...) with initTestGitRepo + addOriginRemoteToTestRepo helpers
  which create the .git structure directly without spawning git
  subprocesses (no timeout risk, no git hook interference)
- Remove os/exec import that is no longer needed

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@copilot please run the pr-finisher skill, review the latest maintainer feedback, address any unresolved review comments, and rerun checks once updated.

...

Addressed the remaining open review thread in commit fix: replace os.Chdir with t.Chdir and exec git calls with test helpers:

  • Replaced os.Getwd() + defer os.Chdir(originalDir) + os.Chdir(tmpDir) with t.Chdir(tmpDir) in both subtests — this avoids mutating the process-wide working directory and racing with other test goroutines
  • Replaced bare exec.Command("git", "init") and exec.Command("git", "remote", "add", ...) with the existing initTestGitRepo / addOriginRemoteToTestRepo helpers that create the .git structure directly (no subprocess, no timeout risk, no git hook interference)
  • Removed the now-unused os/exec import

CI is stale after the agent push and will need to be re-triggered by a maintainer.

Copilot AI requested a review from gh-aw-bot July 17, 2026 06:10
@mnkiefer
mnkiefer merged commit 5780279 into main Jul 17, 2026
29 checks passed
@mnkiefer
mnkiefer deleted the support-other-hosts branch July 17, 2026 06:18
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.82.12

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.

4 participants