Describe the enhancement
isGhes() in @actions/artifact (packages/artifact/src/internal/shared/config.ts) returns true for any GITHUB_SERVER_URL whose hostname is not github.com, *.ghe.com, or *.localhost. When isGhes() returns true, client.ts throws GHESNotSupportedError on every upload, download, and list call, blocking the v4+ artifact family on every self-hosted GHES instance regardless of release.
GHES 3.13 added the artifact-storage-v2 backend that v4+ clients require. 3.16+ has full production support. Despite that, the hostname-only gate continues to throw on these releases, so v4+ users on supported GHES see:
@actions/artifact v2.0.0+, upload-artifact@v4+ and download-artifact@v4+
are not currently supported on GHES.
The runtime already exposes a clean signal for whether v2 is reachable: the runner sets ACTIONS_RESULTS_URL exactly when the storage backend is available. The artifact client's own getResultsServiceUrl() (in the same file) already throws if ACTIONS_RESULTS_URL is unset, so it's already a precondition for v4+ paths to function.
Treating its presence as the authority on "is the v2 backend reachable" would unblock GHES 3.13+ without any new env-var contract or operator opt-in.
Code Snippet
Proposed change to packages/artifact/src/internal/shared/config.ts:
const hostnameLooksLikeGhes =
!isGitHubHost && !isGheHost && !isLocalHost
if (hostnameLooksLikeGhes && process.env['ACTIONS_RESULTS_URL']) {
return false
}
return hostnameLooksLikeGhes
Additional information
This is narrower in scope than #2123, which takes a more general vendor-aware approach (an explicit ACTIONS_VENDOR env var that operators set to identify their environment, supporting third-party servers like Gitea and Forgejo as well as GHES). That PR addresses the broader compatibility need; this issue covers the specific case of GHES instances on releases that already ship the v2 backend, where the runtime's existing ACTIONS_RESULTS_URL signal lets the action detect v2 availability automatically without operator action.
The two approaches are complementary and could both land. If they do, the check proposed here would short-circuit before vendor detection on v2-supporting GHES.
Describe the enhancement
isGhes()in@actions/artifact(packages/artifact/src/internal/shared/config.ts) returns true for anyGITHUB_SERVER_URLwhose hostname is notgithub.com,*.ghe.com, or*.localhost. WhenisGhes()returns true,client.tsthrowsGHESNotSupportedErroron every upload, download, and list call, blocking the v4+ artifact family on every self-hosted GHES instance regardless of release.GHES 3.13 added the artifact-storage-v2 backend that v4+ clients require. 3.16+ has full production support. Despite that, the hostname-only gate continues to throw on these releases, so v4+ users on supported GHES see:
The runtime already exposes a clean signal for whether v2 is reachable: the runner sets
ACTIONS_RESULTS_URLexactly when the storage backend is available. The artifact client's owngetResultsServiceUrl()(in the same file) already throws ifACTIONS_RESULTS_URLis unset, so it's already a precondition for v4+ paths to function.Treating its presence as the authority on "is the v2 backend reachable" would unblock GHES 3.13+ without any new env-var contract or operator opt-in.
Code Snippet
Proposed change to
packages/artifact/src/internal/shared/config.ts:Additional information
This is narrower in scope than #2123, which takes a more general vendor-aware approach (an explicit
ACTIONS_VENDORenv var that operators set to identify their environment, supporting third-party servers like Gitea and Forgejo as well as GHES). That PR addresses the broader compatibility need; this issue covers the specific case of GHES instances on releases that already ship the v2 backend, where the runtime's existingACTIONS_RESULTS_URLsignal lets the action detect v2 availability automatically without operator action.The two approaches are complementary and could both land. If they do, the check proposed here would short-circuit before vendor detection on v2-supporting GHES.