Skip to content

Commit

Permalink
Add support for GitHub Enterprise Cloud Data residency (#2547)
Browse files Browse the repository at this point in the history
* Add support for GitHub Enterprise Cloud with Data residency

* Fix broken build

* Add test for GHECDataResidencyMatch

---------

Co-authored-by: Keegan Campbell <[email protected]>
  • Loading branch information
EricDales and kfcampbell authored Feb 27, 2025
1 parent e5f0c4c commit c99f24e
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
2 changes: 1 addition & 1 deletion github/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func GenerateOAuthTokenFromApp(baseURL, appID, appInstallationID, pemData string
}

func getInstallationAccessToken(baseURL string, jwt string, installationID string) (string, error) {
if baseURL != "https://api.github.com/" {
if baseURL != "https://api.github.com/" && !GHECDataResidencyMatch.MatchString(baseURL) {
baseURL += "api/v3/"
}

Expand Down
9 changes: 7 additions & 2 deletions github/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"net/url"
"path"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -36,6 +37,10 @@ type Owner struct {
IsOrganization bool
}

// GHECDataResidencyMatch is a regex to match a GitHub Enterprise Cloud data residency URL:
// https://[hostname].ghe.com instances expect paths that behave similar to github.com, not GitHub Enterprise Server.
var GHECDataResidencyMatch = regexp.MustCompile(`^https:\/\/[a-zA-Z0-9.\-]*\.ghe\.com$`)

func RateLimitedHTTPClient(client *http.Client, writeDelay time.Duration, readDelay time.Duration, retryDelay time.Duration, parallelRequests bool, retryableErrors map[int]bool, maxRetries int) *http.Client {

client.Transport = NewEtagTransport(client.Transport)
Expand Down Expand Up @@ -80,7 +85,7 @@ func (c *Config) NewGraphQLClient(client *http.Client) (*githubv4.Client, error)
return nil, err
}

if uv4.String() != "https://api.github.com/" {
if uv4.String() != "https://api.github.com/" && !GHECDataResidencyMatch.MatchString(uv4.String()) {
uv4.Path = path.Join(uv4.Path, "api/graphql/")
} else {
uv4.Path = path.Join(uv4.Path, "graphql")
Expand All @@ -96,7 +101,7 @@ func (c *Config) NewRESTClient(client *http.Client) (*github.Client, error) {
return nil, err
}

if uv3.String() != "https://api.github.com/" {
if uv3.String() != "https://api.github.com/" && !GHECDataResidencyMatch.MatchString(uv3.String()) {
uv3.Path = uv3.Path + "api/v3/"
}

Expand Down
58 changes: 58 additions & 0 deletions github/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,64 @@ import (
"github.com/shurcooL/githubv4"
)

func TestGHECDataResidencyMatch(t *testing.T) {
testCases := []struct {
url string
matches bool
description string
}{
{
url: "https://customer.ghe.com",
matches: true,
description: "GHEC data residency URL with customer name",
},
{
url: "https://customer-name.ghe.com",
matches: true,
description: "GHEC data residency URL with hyphenated name",
},
{
url: "https://api.github.com",
matches: false,
description: "github.com API URL",
},
{
url: "https://github.com",
matches: false,
description: "github.com URL",
},
{
url: "https://example.com",
matches: false,
description: "Generic URL",
},
{
url: "http://customer.ghe.com",
matches: false,
description: "Non-HTTPS GHEC URL",
},
{
url: "https://customer.ghe.com/api/v3",
matches: false,
description: "GHEC URL with path",
},
{
url: "https://ghe.com",
matches: false,
description: "GHEC domain without subdomain",
},
}

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
matches := GHECDataResidencyMatch.MatchString(tc.url)
if matches != tc.matches {
t.Errorf("URL %q: expected match=%v, got %v", tc.url, tc.matches, matches)
}
})
}
}

func TestAccConfigMeta(t *testing.T) {

// FIXME: Skip test runs during travis lint checking
Expand Down

0 comments on commit c99f24e

Please sign in to comment.