@@ -47,6 +47,14 @@ type Config struct {
4747 SlackUsername string
4848 SlackIconEmoji string
4949 SlackEnabled bool
50+
51+ // GitHub API retry configuration
52+ GitHubAPIMaxRetries int
53+ GitHubAPIInitialRetryDelay int // in milliseconds
54+
55+ // PR merge polling configuration
56+ PRMergePollMaxAttempts int
57+ PRMergePollInterval int // in milliseconds
5058}
5159
5260const (
@@ -78,11 +86,15 @@ const (
7886 AuditDatabase = "AUDIT_DATABASE"
7987 AuditCollection = "AUDIT_COLLECTION"
8088 MetricsEnabled = "METRICS_ENABLED"
81- SlackWebhookURL = "SLACK_WEBHOOK_URL"
82- SlackChannel = "SLACK_CHANNEL"
83- SlackUsername = "SLACK_USERNAME"
84- SlackIconEmoji = "SLACK_ICON_EMOJI"
85- SlackEnabled = "SLACK_ENABLED"
89+ SlackWebhookURL = "SLACK_WEBHOOK_URL"
90+ SlackChannel = "SLACK_CHANNEL"
91+ SlackUsername = "SLACK_USERNAME"
92+ SlackIconEmoji = "SLACK_ICON_EMOJI"
93+ SlackEnabled = "SLACK_ENABLED"
94+ GitHubAPIMaxRetries = "GITHUB_API_MAX_RETRIES"
95+ GitHubAPIInitialRetryDelay = "GITHUB_API_INITIAL_RETRY_DELAY"
96+ PRMergePollMaxAttempts = "PR_MERGE_POLL_MAX_ATTEMPTS"
97+ PRMergePollInterval = "PR_MERGE_POLL_INTERVAL"
8698)
8799
88100// NewConfig returns a new Config instance with default values
@@ -99,9 +111,13 @@ func NewConfig() *Config {
99111 WebhookSecretName : "projects/1054147886816/secrets/webhook-secret/versions/latest" , // default webhook secret name for GCP Secret Manager
100112 CopierLogName : "copy-copier-log" , // default log name for logging to GCP
101113 GoogleCloudProjectId : "github-copy-code-examples" , // default project ID for logging to GCP
102- DefaultRecursiveCopy : true , // system-wide default for recursive copying that individual config entries can override.
103- DefaultPRMerge : false , // system-wide default for PR merge without review that individual config entries can override.
104- DefaultCommitMessage : "Automated PR with updated examples" , // default commit message used when per-config commit_message is absent.
114+ DefaultRecursiveCopy : true , // system-wide default for recursive copying that individual config entries can override.
115+ DefaultPRMerge : false , // system-wide default for PR merge without review that individual config entries can override.
116+ DefaultCommitMessage : "Automated PR with updated examples" , // default commit message used when per-config commit_message is absent.
117+ GitHubAPIMaxRetries : 3 , // default number of retry attempts for GitHub API calls
118+ GitHubAPIInitialRetryDelay : 500 , // default initial retry delay in milliseconds (exponential backoff)
119+ PRMergePollMaxAttempts : 20 , // default max attempts to poll PR for mergeability (~10 seconds with 500ms interval)
120+ PRMergePollInterval : 500 , // default polling interval in milliseconds
105121 }
106122}
107123
@@ -173,6 +189,14 @@ func LoadEnvironment(envFile string) (*Config, error) {
173189 config .SlackIconEmoji = getEnvWithDefault (SlackIconEmoji , ":robot_face:" )
174190 config .SlackEnabled = getBoolEnvWithDefault (SlackEnabled , config .SlackWebhookURL != "" )
175191
192+ // GitHub API retry configuration
193+ config .GitHubAPIMaxRetries = getIntEnvWithDefault (GitHubAPIMaxRetries , config .GitHubAPIMaxRetries )
194+ config .GitHubAPIInitialRetryDelay = getIntEnvWithDefault (GitHubAPIInitialRetryDelay , config .GitHubAPIInitialRetryDelay )
195+
196+ // PR merge polling configuration
197+ config .PRMergePollMaxAttempts = getIntEnvWithDefault (PRMergePollMaxAttempts , config .PRMergePollMaxAttempts )
198+ config .PRMergePollInterval = getIntEnvWithDefault (PRMergePollInterval , config .PRMergePollInterval )
199+
176200 // Export resolved values back into environment so downstream os.Getenv sees defaults
177201 _ = os .Setenv (Port , config .Port )
178202 _ = os .Setenv (RepoName , config .RepoName )
@@ -218,6 +242,19 @@ func getBoolEnvWithDefault(key string, defaultValue bool) bool {
218242 return strings .ToLower (value ) == "true"
219243}
220244
245+ // getIntEnvWithDefault returns the integer environment variable value or default if not set
246+ func getIntEnvWithDefault (key string , defaultValue int ) int {
247+ value := os .Getenv (key )
248+ if value == "" {
249+ return defaultValue
250+ }
251+ var intValue int
252+ if _ , err := fmt .Sscanf (value , "%d" , & intValue ); err != nil {
253+ return defaultValue
254+ }
255+ return intValue
256+ }
257+
221258// validateConfig checks if all required configuration values are set
222259func validateConfig (config * Config ) error {
223260 var missingVars []string
0 commit comments