feat(coderd): refactors github pr sync functionality (#22715)

- Adds `_API_BASE_URL` to `CODER_EXTERNAL_AUTH_CONFIG_`
- Extracts and refactors existing GitHub PR sync logic to new packages
`coderd/gitsync` and `coderd/externalauth/gitprovider`
- Associated wiring and tests

Created using Opus 4.6
This commit is contained in:
Cian Johnston
2026-03-10 18:46:01 +00:00
committed by GitHub
parent cbe46c816e
commit bc27274aba
31 changed files with 4311 additions and 708 deletions
+33 -3
View File
@@ -23,6 +23,7 @@ import (
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/externalauth/gitprovider"
"github.com/coder/coder/v2/coderd/promoauth"
"github.com/coder/coder/v2/coderd/util/slice"
"github.com/coder/coder/v2/codersdk"
@@ -82,6 +83,10 @@ type Config struct {
// a Git clone. e.g. "Username for 'https://github.com':"
// The regex would be `github\.com`..
Regex *regexp.Regexp
// APIBaseURL is the base URL for provider REST API calls
// (e.g., "https://api.github.com" for GitHub). Derived from
// defaults when not explicitly configured.
APIBaseURL string
// AppInstallURL is for GitHub App's (and hopefully others eventually)
// to provide a link to install the app. There's installation
// of the application, and user authentication. It's possible
@@ -106,12 +111,23 @@ type Config struct {
CodeChallengeMethodsSupported []promoauth.Oauth2PKCEChallengeMethod
}
// Git returns a Provider for this config if the provider type
// is a supported git hosting provider. Returns nil for non-git
// providers (e.g. Slack, JFrog).
func (c *Config) Git(client *http.Client) gitprovider.Provider {
norm := strings.ToLower(c.Type)
if !codersdk.EnhancedExternalAuthProvider(norm).Git() {
return nil
}
return gitprovider.New(norm, c.APIBaseURL, client)
}
// GenerateTokenExtra generates the extra token data to store in the database.
func (c *Config) GenerateTokenExtra(token *oauth2.Token) (pqtype.NullRawMessage, error) {
if len(c.ExtraTokenKeys) == 0 {
return pqtype.NullRawMessage{}, nil
}
extraMap := map[string]interface{}{}
extraMap := map[string]any{}
for _, key := range c.ExtraTokenKeys {
extraMap[key] = token.Extra(key)
}
@@ -730,6 +746,7 @@ func ConvertConfig(instrument *promoauth.Factory, entries []codersdk.ExternalAut
ClientID: entry.ClientID,
ClientSecret: entry.ClientSecret,
Regex: regex,
APIBaseURL: entry.APIBaseURL,
Type: entry.Type,
NoRefresh: entry.NoRefresh,
ValidateURL: entry.ValidateURL,
@@ -766,7 +783,7 @@ func ConvertConfig(instrument *promoauth.Factory, entries []codersdk.ExternalAut
// applyDefaultsToConfig applies defaults to the config entry.
func applyDefaultsToConfig(config *codersdk.ExternalAuthConfig) {
configType := codersdk.EnhancedExternalAuthProvider(config.Type)
configType := codersdk.EnhancedExternalAuthProvider(strings.ToLower(config.Type))
if configType == "bitbucket" {
// For backwards compatibility, we need to support the "bitbucket" string.
configType = codersdk.EnhancedExternalAuthProviderBitBucketCloud
@@ -783,7 +800,7 @@ func applyDefaultsToConfig(config *codersdk.ExternalAuthConfig) {
}
// Dynamic defaults
switch codersdk.EnhancedExternalAuthProvider(config.Type) {
switch configType {
case codersdk.EnhancedExternalAuthProviderGitHub:
copyDefaultSettings(config, gitHubDefaults(config))
return
@@ -864,6 +881,19 @@ func copyDefaultSettings(config *codersdk.ExternalAuthConfig, defaults codersdk.
if config.CodeChallengeMethodsSupported == nil {
config.CodeChallengeMethodsSupported = []string{string(promoauth.PKCEChallengeMethodSha256)}
}
// Set default API base URL for providers that need one.
if config.APIBaseURL == "" {
normType := strings.ToLower(config.Type)
switch codersdk.EnhancedExternalAuthProvider(normType) {
case codersdk.EnhancedExternalAuthProviderGitHub:
config.APIBaseURL = "https://api.github.com"
case codersdk.EnhancedExternalAuthProviderGitLab:
config.APIBaseURL = "https://gitlab.com/api/v4"
case codersdk.EnhancedExternalAuthProviderGitea:
config.APIBaseURL = "https://gitea.com/api/v1"
}
}
}
// gitHubDefaults returns default config values for GitHub.