validateSafeOutputsMax validates that all max fields in safe-outputs configs hold valid values. Valid values are positive integers (n > 0) or -1 (unlimited per spec). 0 and other negative values are rejected. GitHub Actions expressions (e.g. "${{ inputs.max }}") are not evaluable at compile time and
(config *SafeOutputsConfig)
| 55 | // it is on the hot path and called on every compilation. The field ordering matches |
| 56 | // the sorted safeOutputFieldMapping keys for deterministic error reporting. |
| 57 | func validateSafeOutputsMax(config *SafeOutputsConfig) error { |
| 58 | if config == nil { |
| 59 | return nil |
| 60 | } |
| 61 | |
| 62 | safeOutputsMaxValidationLog.Print("Validating safe-outputs max fields") |
| 63 | |
| 64 | // Direct field access — no reflection, no heap allocation. |
| 65 | // Fields are checked in the alphabetical order of their struct field names, |
| 66 | // matching the sort order of safeOutputFieldMapping keys for deterministic |
| 67 | // error reporting. |
| 68 | if config.AddComments != nil { |
| 69 | if err := checkMaxField("add_comment", config.AddComments.Max); err != nil { |
| 70 | return err |
| 71 | } |
| 72 | } |
| 73 | if config.AddLabels != nil { |
| 74 | if err := checkMaxField("add_labels", config.AddLabels.Max); err != nil { |
| 75 | return err |
| 76 | } |
| 77 | } |
| 78 | if config.AddReviewer != nil { |
| 79 | if err := checkMaxField("add_reviewer", config.AddReviewer.Max); err != nil { |
| 80 | return err |
| 81 | } |
| 82 | } |
| 83 | if config.AssignMilestone != nil { |
| 84 | if err := checkMaxField("assign_milestone", config.AssignMilestone.Max); err != nil { |
| 85 | return err |
| 86 | } |
| 87 | } |
| 88 | if config.AssignToAgent != nil { |
| 89 | if err := checkMaxField("assign_to_agent", config.AssignToAgent.Max); err != nil { |
| 90 | return err |
| 91 | } |
| 92 | } |
| 93 | if config.AssignToUser != nil { |
| 94 | if err := checkMaxField("assign_to_user", config.AssignToUser.Max); err != nil { |
| 95 | return err |
| 96 | } |
| 97 | } |
| 98 | if config.AutofixCodeScanningAlert != nil { |
| 99 | if err := checkMaxField("autofix_code_scanning_alert", config.AutofixCodeScanningAlert.Max); err != nil { |
| 100 | return err |
| 101 | } |
| 102 | } |
| 103 | if config.CallWorkflow != nil { |
| 104 | if err := checkMaxField("call_workflow", config.CallWorkflow.Max); err != nil { |
| 105 | return err |
| 106 | } |
| 107 | } |
| 108 | if config.CloseDiscussions != nil { |
| 109 | if err := checkMaxField("close_discussion", config.CloseDiscussions.Max); err != nil { |
| 110 | return err |
| 111 | } |
| 112 | } |
| 113 | if config.CloseIssues != nil { |
| 114 | if err := checkMaxField("close_issue", config.CloseIssues.Max); err != nil { |