Skip to content

Add GitHub Enterprise Cloud host support - #605

Open
mightyguava wants to merge 1 commit into
cashapp:masterfrom
mightyguava:yunchi/ghe
Open

Add GitHub Enterprise Cloud host support#605
mightyguava wants to merge 1 commit into
cashapp:masterfrom
mightyguava:yunchi/ghe

Conversation

@mightyguava

@mightyguava mightyguava commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Add host-aware GitHub Enterprise support for private release downloads and git source rewrites.

This specifically adds support for GitHub Enterprise Cloud with data residency, where the web host is a subdomain.ghe.com host and the API host is api.subdomain.ghe.com. The implementation should also work for GitHub Enterprise more generally by allowing additional enterprise hosts to be configured in github-token-auth.

Changes

1. Config now supports multiple GitHub auth blocks

github-token-auth is now repeatable and host-aware. For GitHub Enterprise Cloud with data residency (*.ghe.com), this block is optional for release downloads because Hermit recognizes those hosts by default and will try to fetch credentials from the GitHub CLI with gh auth token -h <host>.

The block is still available when you want to override the token environment variable, or when using a self-hosted GitHub Enterprise domain that is not github.com or *.ghe.com:

github-token-auth {
  host = "mycompany.ghe.com"
  token-env = "HERMIT_GITHUB_TOKEN_MYCOMPANY_GHE_COM"
  match = ["mycompany/*"]
}

The default host remains github.com, preserving existing behavior for current configs.

2. Added host-aware GitHub client configuration

Added github.HostConfig and github.NewWithHosts() so a single client can know about multiple GitHub-compatible hosts and their tokens.

The REST API base URL is always derived as:

https://api.<github-host>

Only the existing REST v3 endpoint paths are supported. The previous configurable API URL field has been removed.

3. Added host-specific GitHub API methods

Added host-aware variants for repo and release lookups:

  • RepoForHost()
  • ReleaseForHost()
  • LatestReleaseForHost()
  • ReleasesForHost()

The legacy methods still exist and route through the client default host for backwards compatibility. These could probably be removed if there are no external usages of these methods; there are very few call sites inside the Hermit repo.

4. Token injection is now scoped by host

Authentication transport now maps tokens to each configured web host and API host. A GHE token for mycompany.ghe.com is only sent to mycompany.ghe.com and api.mycompany.ghe.com, not to github.com or api.github.com.

For non-github.com hosts, if a token is not configured through token-env, Hermit uses:

gh auth token -h <host>

If the gh CLI is unavailable or token lookup fails, Hermit returns an explicit error asking the user to authenticate that host with gh.

5. Private release source selection is now host-aware and non-recursive

Private release source selection now uses a single aggregate selector rather than wrapping one selector per host. It recognizes GitHub-style release URLs on:

  • github.com
  • *.ghe.com hosts by default
  • additional enterprise hosts configured in github-token-auth
https://<host>/<owner>/<repo>/releases/download/<tag>/<asset>

When a URL matches, Hermit uses the host-specific GitHub releases API to find and download the asset instead of following browser login/SSO redirects.

6. Added defensive checks for release asset URLs

Release asset downloads and ETag checks now validate the returned asset URL against the configured host/API host. For a non-github.com host, Hermit also refuses redirects to github.com or api.github.com.

This might be unnecessary in normal GitHub Enterprise behavior, but seemed harmless and prevents a GHE source from accidentally using GitHub.com URLs if an unexpected asset URL or redirect is returned. Presigned release asset redirects to object storage hosts like objects-origin.<host> are allowed and are not treated as GitHub hosts for auth.

7. Git source URL rewriting supports GHE HTTPS URLs

Added AuthenticatedURLRewriterForHost() so HTTPS git sources on configured enterprise hosts can be rewritten with the correct token while preserving the original host:

https://mycompany.ghe.com/owner/repo.git

becomes:

https://x-access-token:<token>@mycompany.ghe.com/owner/repo.git

SSH URLs are still passed through unchanged.

8. App wiring builds one GitHub client from all configured hosts

Hermit now reads all configured github-token-auth blocks, resolves each configured env token, and installs one aggregate source selector plus host-specific source rewriters.

9. Manifest inference carries the GitHub host through repo lookup

Manifest inference now uses ProjectForURLWithHost() and RepoForHost() so GHE artifact URLs do not accidentally call api.github.com for repo metadata.

For non-github.com hosts, inference does not emit github-release = "owner/repo" because autoversion has not been updated to support GitHub Enterprise yet.

Notes

  • Autoversion has not been updated to support GitHub Enterprise release APIs. Existing github-release autoversion still uses the legacy GitHub.com-oriented interface.
  • The legacy GitHub API methods remain for compatibility but may be removable if there are no external users.
  • This primarily targets GitHub Enterprise Cloud with data residency (subdomain.ghe.com) but should work for GitHub Enterprise in general.
  • For GHEC data residency (*.ghe.com), github-token-auth is optional for release downloads unless you want to override token-env; self-hosted GitHub Enterprise domains still need a configured block.
  • gh auth status --json hosts is not used for host discovery; Hermit recognizes github.com/*.ghe.com by default and uses configured hosts for other enterprise domains.

Test Plan

  • GOROOT= GOCACHE=$PWD/.tmp9/gocache GOMODCACHE=$PWD/.tmp9/gomodcache go test ./...
  • git diff --check

Co-authored-by: Codex <codex-noreply@coinbase.com>
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