diff --git a/github/actions/config.go b/github/actions/config.go index f19cb17f..50f23213 100644 --- a/github/actions/config.go +++ b/github/actions/config.go @@ -3,6 +3,7 @@ package actions import ( "fmt" "net/url" + "os" "strings" ) @@ -34,9 +35,7 @@ func ParseGitHubConfigFromURL(in string) (*GitHubConfig, error) { return nil, err } - isHosted := u.Host == "github.com" || - u.Host == "www.github.com" || - u.Host == "github.localhost" + isHosted := isHostedGitHubURL(u) configURL := &GitHubConfig{ ConfigURL: u, @@ -76,23 +75,35 @@ func ParseGitHubConfigFromURL(in string) (*GitHubConfig, error) { func (c *GitHubConfig) GitHubAPIURL(path string) *url.URL { result := &url.URL{ Scheme: c.ConfigURL.Scheme, + Host: c.ConfigURL.Host, // default for Enterprise mode + Path: "/api/v3", // default for Enterprise mode } - switch c.ConfigURL.Host { - // Hosted - case "github.com", "github.localhost": - result.Host = fmt.Sprintf("api.%s", c.ConfigURL.Host) - // re-routing www.github.com to api.github.com - case "www.github.com": - result.Host = "api.github.com" + isHosted := isHostedGitHubURL(c.ConfigURL) - // Enterprise - default: - result.Host = c.ConfigURL.Host - result.Path = "/api/v3" + if isHosted { + result.Host = fmt.Sprintf("api.%s", c.ConfigURL.Host) + result.Path = "" + + if strings.EqualFold("www.github.com", c.ConfigURL.Host) { + // re-routing www.github.com to api.github.com + result.Host = "api.github.com" + } } result.Path += path return result } + +func isHostedGitHubURL(u *url.URL) bool { + _, forceGhes := os.LookupEnv("GITHUB_ACTIONS_FORCE_GHES") + if forceGhes { + return false + } + + return strings.EqualFold(u.Host, "github.com") || + strings.EqualFold(u.Host, "www.github.com") || + strings.EqualFold(u.Host, "github.localhost") || + strings.HasSuffix(u.Host, ".ghe.com") +} diff --git a/github/actions/config_test.go b/github/actions/config_test.go index e21f7e9e..99b6459b 100644 --- a/github/actions/config_test.go +++ b/github/actions/config_test.go @@ -3,6 +3,7 @@ package actions_test import ( "errors" "net/url" + "os" "strings" "testing" @@ -117,6 +118,16 @@ func TestGitHubConfig(t *testing.T) { IsHosted: false, }, }, + { + configURL: "https://my-ghes.ghe.com/org/", + expected: &actions.GitHubConfig{ + Scope: actions.GitHubScopeOrganization, + Enterprise: "", + Organization: "org", + Repository: "", + IsHosted: true, + }, + }, } for _, test := range tests { @@ -151,9 +162,35 @@ func TestGitHubConfig_GitHubAPIURL(t *testing.T) { t.Run("when hosted", func(t *testing.T) { config, err := actions.ParseGitHubConfigFromURL("https://github.com/org/repo") require.NoError(t, err) + assert.True(t, config.IsHosted) result := config.GitHubAPIURL("/some/path") assert.Equal(t, "https://api.github.com/some/path", result.String()) }) - t.Run("when not hosted", func(t *testing.T) {}) + t.Run("when hosted with ghe.com", func(t *testing.T) { + config, err := actions.ParseGitHubConfigFromURL("https://github.ghe.com/org/repo") + require.NoError(t, err) + assert.True(t, config.IsHosted) + + result := config.GitHubAPIURL("/some/path") + assert.Equal(t, "https://api.github.ghe.com/some/path", result.String()) + }) + t.Run("when not hosted", func(t *testing.T) { + config, err := actions.ParseGitHubConfigFromURL("https://ghes.com/org/repo") + require.NoError(t, err) + assert.False(t, config.IsHosted) + + result := config.GitHubAPIURL("/some/path") + assert.Equal(t, "https://ghes.com/api/v3/some/path", result.String()) + }) + t.Run("when not hosted with ghe.com", func(t *testing.T) { + os.Setenv("GITHUB_ACTIONS_FORCE_GHES", "1") + defer os.Unsetenv("GITHUB_ACTIONS_FORCE_GHES") + config, err := actions.ParseGitHubConfigFromURL("https://test.ghe.com/org/repo") + require.NoError(t, err) + assert.False(t, config.IsHosted) + + result := config.GitHubAPIURL("/some/path") + assert.Equal(t, "https://test.ghe.com/api/v3/some/path", result.String()) + }) }