From 31c956e94e42a67c99b34614af73949da35f90fc Mon Sep 17 00:00:00 2001 From: Ahmad Shata Date: Thu, 19 Mar 2026 07:13:08 +0200 Subject: [PATCH] fix(config): route GitHub App token refresh to enterprise API_URL --- config/config.go | 12 ++++++++- config/config_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index b218910..242fee8 100644 --- a/config/config.go +++ b/config/config.go @@ -89,10 +89,20 @@ func (c *Config) GetClient() (*github.Client, error) { // Add custom transport for GitHub App authentication if enabled if c.GitHubApp { - itr, err := ghinstallation.NewKeyFromFile(transport, c.GitHubAppId, c.GitHubAppInstallationId, c.GitHubAppKeyPath) + itr, err := ghinstallation.NewKeyFromFile( + transport, + c.GitHubAppId, + c.GitHubAppInstallationId, + c.GitHubAppKeyPath, + ) if err != nil { return nil, fmt.Errorf("creating GitHub App installation transport: %v", err) } + + if c.ApiUrl != nil && c.ApiUrl.String() != "https://api.github.com" { + itr.BaseURL = c.ApiUrl.String() + } + transport = itr } diff --git a/config/config_test.go b/config/config_test.go index 20a2aae..0d48c69 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,10 +1,18 @@ package config import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" "errors" "net/url" + "os" + "path/filepath" "testing" + "github.com/bradleyfalzon/ghinstallation/v2" + "github.com/gofri/go-github-pagination/githubpagination" "github.com/stretchr/testify/assert" ) @@ -228,3 +236,52 @@ func TestGetClient(t *testing.T) { }) } } + +func TestGetClientGitHubAppEnterpriseTransportBaseURL(t *testing.T) { + privateKeyPath := writeTempPrivateKeyFile(t) + + t.Setenv("GITHUB_APP", "true") + t.Setenv("GITHUB_APP_KEY_PATH", privateKeyPath) + t.Setenv("GITHUB_APP_ID", "1") + t.Setenv("GITHUB_APP_INSTALLATION_ID", "999999") + t.Setenv("API_URL", "https://github.enterprise.test/api/v3") + + cfg, err := Init() + assert.NoError(t, err) + + client, err := cfg.GetClient() + assert.NoError(t, err) + + paginator, ok := client.Client().Transport.(*githubpagination.GitHubPagination) + if !assert.True(t, ok) { + return + } + + installationTransport, ok := paginator.Base.(*ghinstallation.Transport) + if !assert.True(t, ok) { + return + } + + assert.Equal(t, "https://github.enterprise.test/api/v3", installationTransport.BaseURL) +} + +func writeTempPrivateKeyFile(t *testing.T) string { + t.Helper() + + key, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("generating rsa key: %v", err) + } + + keyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(key), + }) + + path := filepath.Join(t.TempDir(), "github-app-private-key.pem") + if err := os.WriteFile(path, keyPEM, 0o600); err != nil { + t.Fatalf("writing private key file: %v", err) + } + + return path +}