You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Support a custom host for repositories (GitHub Enterprise, self-hosted GitLab) #143
DLoad always talks to api.github.com / gitlab.com: the API base is hardcoded in the repository API classes, and the GitHub factory keeps only the org/repo part of uri. So there is no way to point a <repository> at GitHub Enterprise Server, a self-hosted GitLab, or any other on-premise instance.
Proposal
A host attribute on <repository>: a host name with an optional port, no scheme and no path. Defaults to the public host of the repository type (github.com / gitlab.com).
With host, the repository API derives its base URL from it (e.g. for GitHub Enterprise Server https://<host>/api/v3, for GitLab https://<host>/api/v4) instead of the hardcoded constants.
Open questions
Tokens.GITHUB_TOKEN / GITLAB_TOKEN are currently sent only to the public hosts. A custom host needs a way to opt in, otherwise private enterprise repositories can't be reached, while blindly sending the token to any configured host is a leak risk.
Scheme. Real instances are HTTPS. A local test server (127.0.0.1:<port>) is usually plain HTTP — decide whether loopback hosts may use http://, or tests must serve TLS.
Side benefit
This also lets tests run DLoad against a local fake API server (e.g. host="127.0.0.1:8080"), which is what roadrunner-php/cli needs: its rr get acceptance tests (roadrunner-php/cli#66) run against such a server, and roadrunner-php/cli#49 (switching rr get to DLoad) can only pass them once DLoad supports host.
changed the title [-]Support custom hosts in repository uri (GitHub Enterprise, self-hosted GitLab)[/-][+]Support a custom host for repositories (GitHub Enterprise, self-hosted GitLab)[/+]on Oct 9, 2026
GITHUB_TOKEN / GITLAB_TOKEN are never sent to a custom server.
The config cannot choose which variable is read: only the user's environment opts a host in, so a foreign dload.xml can't exfiltrate a token or any other variable.
A custom server's token is attached only to requests to the same scheme, host and port (no subdomains). The default servers keep today's rule (api.github.com, github.com, *.githubusercontent.com).
No token over plain http, except loopback (localhost, 127.0.0.0/8, ::1), so a local fake server can still test authentication.
The GitLab client stops attaching the token to every request and gets the same host check.
Error messages (401 / 403 / rate limit) name the variable that was actually consulted.
Version registry
Repository::getId(): RepositoryId; the downloader takes the registry key from the repository instead of building it from the config.
RepositoryId gets an optional server (null for the public host). A custom server is stored under github@ghe.example.com/org/repo; default paths are unchanged, so existing registries stay valid.
RepositoryRecord gets an optional repository.server field; records without it read as the public host, so no format version bump.
Change of design: the server comes from uri, not a server attribute
The design above added a server attribute next to uri. Review of #148 showed that uri already accepted a full URL and silently dropped its host: uri="https://ghe.corp.com/infra/tool" downloaded infra/tool from github.com. Keeping both attributes would leave two places to name a server and a conflict between them to resolve, while the URL alone carries everything the attribute did (scheme, host, port). The attribute was never released, so it is dropped.
owner/repo and https://github.com/owner/repo (or gitlab.com) work as before, with the same registry keys and tokens.
A value without a scheme never names a server. github.com/owner/repo still reads as the public host; for GitHub a scheme-less foreign host (ghe.example.com/owner/repo) is an error instead of a silent download from github.com.
The rest of the design stands: {server}/api/v3 / {server}/api/v4, plain http only for loopback, per-server registry keys, and per-server tokens — with an injective variable name now (. → _, - → __, port after ___), so ghe-example.com cannot read the token of ghe.example.com. Tokens are also dropped on redirects that leave their server.
Activity
[-]Support custom hosts in repository uri (GitHub Enterprise, self-hosted GitLab)[/-][+]Support a custom host for repositories (GitHub Enterprise, self-hosted GitLab)[/+]feat: pass the RR_GITHUB_API_URL host to DLoad
roxblnfk commentedon Oct 10, 2026
Design
serverattributeThe attribute is named
serverrather thanhost: it carries the scheme too (same meaning asGITHUB_SERVER_URLin GitHub Actions).[scheme://]host[:port], no path, query or credentials. The scheme defaults tohttps; onlyhttpandhttpsare accepted.server→ behaviour stays exactly as today. An explicithttps://github.com/https://gitlab.comis the same as the default.API base URL
serverhttps://api.github.com{server}/api/v3https://gitlab.com/api/v4{server}/api/v4Tokens
A token is declared per server in the environment:
DLOAD_TOKEN_+ host and port, upper-cased, every non-alphanumeric character replaced with_:ghe.example.com→DLOAD_TOKEN_GHE_EXAMPLE_COMgitlab.example.com:8443→DLOAD_TOKEN_GITLAB_EXAMPLE_COM_8443DLOAD_TOKEN_GITHUB_COM, thenGITHUB_TOKENDLOAD_TOKEN_GITLAB_COM, thenGITLAB_TOKENDLOAD_TOKEN_<HOST>onlyGITHUB_TOKEN/GITLAB_TOKENare never sent to a custom server.dload.xmlcan't exfiltrate a token or any other variable.api.github.com,github.com,*.githubusercontent.com).http, except loopback (localhost,127.0.0.0/8,::1), so a local fake server can still test authentication.Version registry
Repository::getId(): RepositoryId; the downloader takes the registry key from the repository instead of building it from the config.RepositoryIdgets an optionalserver(nullfor the public host). A custom server is stored undergithub@ghe.example.com/org/repo; default paths are unchanged, so existing registries stay valid.RepositoryRecordgets an optionalrepository.serverfield; records without it read as the public host, so no format version bump.roxblnfk commentedon Oct 12, 2026
Change of design: the server comes from
uri, not aserverattributeThe design above added a
serverattribute next touri. Review of #148 showed thaturialready accepted a full URL and silently dropped its host:uri="https://ghe.corp.com/infra/tool"downloadedinfra/toolfrom github.com. Keeping both attributes would leave two places to name a server and a conflict between them to resolve, while the URL alone carries everything the attribute did (scheme, host, port). The attribute was never released, so it is dropped.Now:
owner/repoandhttps://github.com/owner/repo(orgitlab.com) work as before, with the same registry keys and tokens.github.com/owner/repostill reads as the public host; for GitHub a scheme-less foreign host (ghe.example.com/owner/repo) is an error instead of a silent download from github.com.{server}/api/v3/{server}/api/v4, plainhttponly for loopback, per-server registry keys, and per-server tokens — with an injective variable name now (.→_,-→__, port after___), soghe-example.comcannot read the token ofghe.example.com. Tokens are also dropped on redirects that leave their server.feat(repository): support self-hosted servers via repository URLs
feat(repository): support self-hosted servers via repository URLs