GHES: Add auto-detection helper functions for wizard configuration#20971
GHES: Add auto-detection helper functions for wizard configuration#20971
Conversation
Add foundation for GHES auto-configuration in gh aw add-wizard: - isGHESInstance(): Detect GHES vs public GitHub from git remote - getGHESAPIURL(): Get GHES API URL for engine.api-target config - getGHESAllowedDomains(): Get GHES domains for network firewall These helpers parse the git origin remote URL and enable the wizard to: 1. Auto-populate engine.api-target for Copilot on GHES 2. Auto-add GHES domains to network.allowed 3. Support proper gh CLI host configuration Includes comprehensive test coverage for all GHES detection scenarios. Related: #20875 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
@claude[agent] fix the pr title and summary |
Updated the PR description with proper context about the GHES auto-detection helper functions. The PR now clearly explains:
The PR title should be: "GHES: Add auto-detection helper functions for wizard configuration" Unfortunately I don't have permission to update the PR title directly via the API, so you may need to update it manually through the GitHub UI. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
* Initial plan * Fix lint: replace fmt.Sprintf with string concatenation in git.go Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds initial GHES auto-detection helpers (based on the origin git remote) intended to support future gh aw add-wizard auto-configuration for enterprise environments.
Changes:
- Add GHES detection + derived values helpers in
pkg/cli/git.go - Add unit tests for GHES/public GitHub remote URL scenarios in
pkg/cli/git_ghes_test.go - Add a patch changeset describing the new helpers
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| pkg/cli/git.go | Introduces GHES detection + helper functions to compute API URL and firewall domains from origin remote host. |
| pkg/cli/git_ghes_test.go | Adds tests that create temp git repos and validate GHES/public GitHub detection behaviors. |
| .changeset/patch-ghes-auto-detect-helpers.md | Documents the new helper functions and intended follow-up wizard integration. |
Comments suppressed due to low confidence (5)
pkg/cli/git_ghes_test.go:156
- Same as the other test blocks:
require.NoErrorongit initwill fail in environments withoutgit. Consider usingt.Skip("Git not available")on init failure to align with existing test patterns in this repo.
// Initialize git repo
require.NoError(t, exec.Command("git", "init").Run(), "Failed to init git repo")
exec.Command("git", "config", "user.name", "Test User").Run()
exec.Command("git", "config", "user.email", "test@example.com").Run()
pkg/cli/git.go:166
getGHESAPIURL()returns a full URL with scheme and/api/v3path, butengine.api-targetelsewhere in the repo is defined/used as a hostname only (e.g. docs/enterprise-configuration.md:32; workflow.EngineConfig.APITarget comment in pkg/workflow/engine.go:29). If this is intended forengine.api-target, it should return just the hostname (or the correct Copilot endpoint for GHES, per docs). If it’s intended for the GHES GitHub REST API base URL, it should be renamed to avoid confusion withapi-target.
// getGHESAPIURL returns the API URL for a GHES instance (e.g., "https://ghes.example.com/api/v3")
// or an empty string if not a GHES instance. This is used to auto-populate engine.api-target.
func getGHESAPIURL() string {
host := getHostFromOriginRemote()
if host == "github.com" {
return ""
}
// GHES API URL format: https://<host>/api/v3
apiURL := fmt.Sprintf("https://%s/api/v3", host)
gitLog.Printf("GHES API URL: %s", apiURL)
return apiURL
}
pkg/cli/git_ghes_test.go:101
- This test uses
require.NoErrorforgit init, which will fail the suite on systems withoutgit. Elsewhere we usuallyt.Skip("Git not available")whengitis missing. Consider switching to that skip pattern here for consistency and portability.
// Initialize git repo
require.NoError(t, exec.Command("git", "init").Run(), "Failed to init git repo")
exec.Command("git", "config", "user.name", "Test User").Run()
exec.Command("git", "config", "user.email", "test@example.com").Run()
pkg/cli/git.go:180
getGHESAllowedDomains()currently returnshostandapi.+host. Two issues: (1) network allowlists already match all subdomains when you allow the base domain (see docs/src/content/docs/reference/network.md:58), so addingapi.<host>is redundant; and (2) if the remote host includes a port (e.g.ghes.example.com:8443), concatenatingapi.produces an invalid domain (api.ghes.example.com:8443) that will fail domain validation. Consider returning only the hostname (no port) and relying on automatic subdomain matching, or explicitly stripping the port before constructing any domain entries.
// getGHESAllowedDomains returns a list of domains that should be added to the firewall
// allowed list for GHES instances. This includes the GHES hostname and api.<ghes-host>.
func getGHESAllowedDomains() []string {
host := getHostFromOriginRemote()
if host == "github.com" {
return nil
}
// For GHES, allow both the main host and api subdomain
domains := []string{
host,
"api." + host,
}
pkg/cli/git_ghes_test.go:85
- The tests here encode behaviors that look inconsistent with existing
engine.api-targetsemantics:getGHESAPIURL()is expected to return a fullhttps://.../api/v3URL, but the rest of the codebase/docs treatapi-targetas hostname-only. Also, there’s no coverage for public GitHub remotes likessh://git@ssh.github.com:443/OWNER/REPO.git, which would currently be mis-detected as GHES. After adjusting the helpers, update these tests to coverssh.github.com:443and any host-with-port scenarios.
func TestGetGHESAPIURL(t *testing.T) {
tests := []struct {
name string
remoteURL string
wantAPIURL string
}{
{
name: "public GitHub returns empty",
remoteURL: "https://github.com/org/repo.git",
wantAPIURL: "",
},
{
name: "GHES instance returns API URL",
remoteURL: "https://ghes.example.com/org/repo.git",
wantAPIURL: "https://ghes.example.com/api/v3",
},
{
name: "GHES SSH format returns API URL",
remoteURL: "git@contoso.ghe.com:org/repo.git",
wantAPIURL: "https://contoso.ghe.com/api/v3",
},
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| // Initialize git repo | ||
| require.NoError(t, exec.Command("git", "init").Run(), "Failed to init git repo") | ||
| exec.Command("git", "config", "user.name", "Test User").Run() | ||
| exec.Command("git", "config", "user.email", "test@example.com").Run() |
| func isGHESInstance() bool { | ||
| host := getHostFromOriginRemote() | ||
| isGHES := host != "github.com" | ||
| gitLog.Printf("GHES instance check: host=%s, isGHES=%v", host, isGHES) | ||
| return isGHES |
| name: "GHES instance returns host and api subdomain", | ||
| remoteURL: "https://ghes.example.com/org/repo.git", | ||
| wantDomains: []string{ | ||
| "ghes.example.com", | ||
| "api.ghes.example.com", | ||
| }, | ||
| }, | ||
| { | ||
| name: "GHES SSH format returns domains", | ||
| remoteURL: "git@contoso-aw.ghe.com:org/repo.git", | ||
| wantDomains: []string{ | ||
| "contoso-aw.ghe.com", | ||
| "api.contoso-aw.ghe.com", | ||
| }, | ||
| }, |
| These functions detect GHES instances by parsing the git origin remote URL and can be used by the wizard to: | ||
| 1. Auto-populate `engine.api-target` for Copilot on GHES | ||
| 2. Auto-add GHES domains to `network.allowed` for firewall configuration | ||
| 3. Enable proper gh CLI host configuration via `GH_HOST` environment variable |
This PR adds foundational GHES auto-detection helper functions to enable automatic configuration of GHES-specific settings in
gh aw add-wizard.Changes
New Helper Functions in
pkg/cli/git.goisGHESInstance()- Detects if the git origin remote points to a GHES instance (vs. public GitHub)getGHESAPIURL()- Returns the GHES API URL (e.g.,https://ghes.example.com/api/v3) for auto-populatingengine.api-targetgetGHESAllowedDomains()- Returns GHES domains (ghes-host,api.ghes-host) for auto-adding tonetwork.allowedTest Coverage
Added comprehensive tests in
pkg/cli/git_ghes_test.gocovering:How It Works
These functions parse the git
originremote URL to detect GHES instances:https://github.com/org/repo.git→ Not GHEShttps://ghes.example.com/org/repo.git→ Detected as GHESgit@ghes.example.com:org/repo.git→ Detected as GHESFuture Integration
These helpers will be integrated in follow-up PRs to:
engine.api-targetfor Copilot engine on GHESnetwork.allowedfirewall configurationNote: The existing
actions/setup/sh/configure_gh_for_ghe.shscript already handlesGH_HOSTenvironment variable configuration, so that requirement is already met.Testing
All tests pass ✅