@@ -30,6 +30,13 @@ import (
30
30
31
31
const githubCommentMaxSize = 65536
32
32
33
+ type DiffCommentData struct {
34
+ DiffOfChangedComponents []argocd.DiffResult
35
+ HasSyncableComponents bool
36
+ BranchName string
37
+ Header string
38
+ }
39
+
33
40
type promotionInstanceMetaData struct {
34
41
SourcePath string `json:"sourcePath"`
35
42
TargetPaths []string `json:"targetPaths"`
@@ -169,40 +176,29 @@ func HandlePREvent(eventPayload *github.PullRequestEvent, ghPrClientDetails GhPr
169
176
}
170
177
171
178
if len (diffOfChangedComponents ) > 0 {
172
- diffCommentData := struct {
173
- DiffOfChangedComponents []argocd.DiffResult
174
- HasSyncableComponens bool
175
- BranchName string
176
- }{
179
+ diffCommentData := DiffCommentData {
177
180
DiffOfChangedComponents : diffOfChangedComponents ,
178
181
BranchName : ghPrClientDetails .Ref ,
179
182
}
180
183
181
184
for _ , componentPath := range componentPathList {
182
185
if isSyncFromBranchAllowedForThisPath (config .Argocd .AllowSyncfromBranchPathRegex , componentPath ) {
183
- diffCommentData .HasSyncableComponens = true
186
+ diffCommentData .HasSyncableComponents = true
184
187
break
185
188
}
186
189
}
187
-
188
- err , templateOutput := executeTemplate (ghPrClientDetails .PrLogger , "argoCdDiff" , "argoCD-diff-pr-comment.gotmpl" , diffCommentData )
190
+ comments , err := generateArgoCdDiffComments (diffCommentData , githubCommentMaxSize )
189
191
if err != nil {
190
192
prHandleError = err
191
- ghPrClientDetails .PrLogger .Errorf ("Failed to generate ArgoCD diff comment template : err=%s\n " , err )
192
- } else if len ( templateOutput ) > githubCommentMaxSize {
193
- ghPrClientDetails . PrLogger . Warnf ( "Diff comment is too large (%d bytes), using concise template" , len ( templateOutput ))
194
- err , templateOutput = executeTemplate (ghPrClientDetails . PrLogger , "argoCdDiffConcise" , "argoCD-diff-pr- comment-concise.gotmpl" , diffCommentData )
193
+ ghPrClientDetails .PrLogger .Errorf ("Failed to comment ArgoCD diff: err=%s\n " , err )
194
+ }
195
+ for _ , comment := range comments {
196
+ err = commentPR (ghPrClientDetails , comment )
195
197
if err != nil {
196
198
prHandleError = err
197
- ghPrClientDetails .PrLogger .Errorf ("Failed to generate ArgoCD diff comment template : err=%s\n " , err )
199
+ ghPrClientDetails .PrLogger .Errorf ("Failed to comment on PR : err=%s\n " , err )
198
200
}
199
201
}
200
-
201
- err = commentPR (ghPrClientDetails , templateOutput )
202
- if err != nil {
203
- prHandleError = err
204
- ghPrClientDetails .PrLogger .Errorf ("Failed to comment ArgoCD diff: err=%s\n " , err )
205
- }
206
202
} else {
207
203
ghPrClientDetails .PrLogger .Debugf ("Diff not find affected ArogCD apps" )
208
204
}
@@ -230,6 +226,47 @@ func HandlePREvent(eventPayload *github.PullRequestEvent, ghPrClientDetails GhPr
230
226
}
231
227
}
232
228
229
+ func generateArgoCdDiffComments (diffCommentData DiffCommentData , githubCommentMaxSize int ) (comments []string , err error ) {
230
+ err , templateOutput := executeTemplate ("argoCdDiff" , "argoCD-diff-pr-comment.gotmpl" , diffCommentData )
231
+ if err != nil {
232
+ return nil , fmt .Errorf ("failed to generate ArgoCD diff comment template: %w" , err )
233
+ }
234
+
235
+ // Happy path, the diff comment is small enough to be posted in one comment
236
+ if len (templateOutput ) < githubCommentMaxSize {
237
+ comments = append (comments , templateOutput )
238
+ return comments , nil
239
+ }
240
+
241
+ // If the diff comment is too large, we'll split it into multiple comments, one per component
242
+ totalComponents := len (diffCommentData .DiffOfChangedComponents )
243
+ for i , singleComponentDiff := range diffCommentData .DiffOfChangedComponents {
244
+ componentTemplateData := diffCommentData
245
+ componentTemplateData .DiffOfChangedComponents = []argocd.DiffResult {singleComponentDiff }
246
+ componentTemplateData .Header = fmt .Sprintf ("Component %d/%d: %s (Split for comment size)" , i + 1 , totalComponents , singleComponentDiff .ComponentPath )
247
+ err , templateOutput := executeTemplate ("argoCdDiff" , "argoCD-diff-pr-comment.gotmpl" , componentTemplateData )
248
+ if err != nil {
249
+ return nil , fmt .Errorf ("failed to generate ArgoCD diff comment template: %w" , err )
250
+ }
251
+
252
+ // Even per component comments can be too large, in that case we'll just use the concise template
253
+ // Somewhat Happy path, the per-component diff comment is small enough to be posted in one comment
254
+ if len (templateOutput ) < githubCommentMaxSize {
255
+ comments = append (comments , templateOutput )
256
+ continue
257
+ }
258
+
259
+ // now we don't have much choice, this is the saddest path, we'll use the concise template
260
+ err , templateOutput = executeTemplate ("argoCdDiffConcise" , "argoCD-diff-pr-comment-concise.gotmpl" , componentTemplateData )
261
+ if err != nil {
262
+ return comments , fmt .Errorf ("failed to generate ArgoCD diff comment template: %w" , err )
263
+ }
264
+ comments = append (comments , templateOutput )
265
+ }
266
+
267
+ return comments , nil
268
+ }
269
+
233
270
// ReciveEventFile this one is similar to ReciveWebhook but it's used for CLI triggering, i simulates a webhook event to use the same code path as the webhook handler.
234
271
func ReciveEventFile (eventType string , eventFilePath string , mainGhClientCache * lru.Cache [string , GhClientPair ], prApproverGhClientCache * lru.Cache [string , GhClientPair ]) {
235
272
log .Infof ("Event type: %s" , eventType )
@@ -449,21 +486,23 @@ func handleCommentPrEvent(ghPrClientDetails GhPrClientDetails, ce *github.IssueC
449
486
}
450
487
451
488
func commentPlanInPR (ghPrClientDetails GhPrClientDetails , promotions map [string ]PromotionInstance ) {
452
- _ , templateOutput := executeTemplate (ghPrClientDetails .PrLogger , "dryRunMsg" , "dry-run-pr-comment.gotmpl" , promotions )
489
+ err , templateOutput := executeTemplate ("dryRunMsg" , "dry-run-pr-comment.gotmpl" , promotions )
490
+ if err != nil {
491
+ ghPrClientDetails .PrLogger .Errorf ("Failed to generate dry-run comment template: err=%s\n " , err )
492
+ return
493
+ }
453
494
_ = commentPR (ghPrClientDetails , templateOutput )
454
495
}
455
496
456
- func executeTemplate (logger * log. Entry , templateName string , templateFile string , data interface {}) (error , string ) {
497
+ func executeTemplate (templateName string , templateFile string , data interface {}) (error , string ) {
457
498
var templateOutput bytes.Buffer
458
499
messageTemplate , err := template .New (templateName ).ParseFiles (getEnv ("TEMPLATES_PATH" , "templates/" ) + templateFile )
459
500
if err != nil {
460
- logger .Errorf ("Failed to parse template: err=%v" , err )
461
- return err , ""
501
+ return fmt .Errorf ("failed to parse template: %w" , err ), ""
462
502
}
463
503
err = messageTemplate .ExecuteTemplate (& templateOutput , templateName , data )
464
504
if err != nil {
465
- logger .Errorf ("Failed to execute template: err=%v" , err )
466
- return err , ""
505
+ return fmt .Errorf ("failed to execute template: %w" , err ), ""
467
506
}
468
507
return nil , templateOutput .String ()
469
508
}
@@ -594,7 +633,7 @@ func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubCl
594
633
templateData := map [string ]interface {}{
595
634
"prNumber" : * pull .Number ,
596
635
}
597
- err , templateOutput := executeTemplate (ghPrClientDetails . PrLogger , "autoMerge" , "auto-merge-comment.gotmpl" , templateData )
636
+ err , templateOutput := executeTemplate ("autoMerge" , "auto-merge-comment.gotmpl" , templateData )
598
637
if err != nil {
599
638
return err
600
639
}
0 commit comments