( comments: Comment[], review?: string, minimumSeverity?: string, )
| 73 | * @returns Prepared comments and review body ready for GitHub posting |
| 74 | */ |
| 75 | export function prepareComments( |
| 76 | comments: Comment[], |
| 77 | review?: string, |
| 78 | minimumSeverity?: string, |
| 79 | ): { |
| 80 | lineComments: Comment[]; |
| 81 | generalComments: Comment[]; |
| 82 | reviewBody: string; |
| 83 | } { |
| 84 | // Sort comments by severity (descending: critical > high > medium > low) |
| 85 | const sortedComments = [...comments].sort((a, b) => { |
| 86 | const rankA = a.severity ? getSeverityRank(a.severity) : 0; |
| 87 | const rankB = b.severity ? getSeverityRank(b.severity) : 0; |
| 88 | return rankB - rankA; |
| 89 | }); |
| 90 | |
| 91 | // Only findings with a valid line can become inline review comments. File-only and |
| 92 | // fileless findings remain useful, but must go through the general-comment path. |
| 93 | const postableComments = sortedComments.filter(isPrPostableFinding); |
| 94 | const lineComments = postableComments.filter(hasInlineCommentLocation); |
| 95 | const generalComments = postableComments.filter((comment) => !hasInlineCommentLocation(comment)); |
| 96 | |
| 97 | // Check if we only have "none" severity comments (i.e., no real vulnerabilities) |
| 98 | const hasOnlyNoneSeverity = |
| 99 | comments.length > 0 && comments.every((c) => c.severity === CodeScanSeverity.NONE); |
| 100 | |
| 101 | // Construct review body |
| 102 | let reviewBody = review || ''; |
| 103 | |
| 104 | // If no real vulnerabilities, prepend "All Clear" to review |
| 105 | if (hasOnlyNoneSeverity && reviewBody) { |
| 106 | reviewBody = `${ALL_CLEAR_MESSAGE}\n\n${reviewBody}`; |
| 107 | } |
| 108 | |
| 109 | // Append minimum severity threshold if provided |
| 110 | if (minimumSeverity && reviewBody) { |
| 111 | const severityFormatted = formatSeverity(minimumSeverity as CodeScanSeverity, 'plain'); |
| 112 | reviewBody += `\n\n<sub>Minimum severity threshold: ${severityFormatted} | To re-scan after changes, comment \`@promptfoo-scanner\`</sub>`; |
| 113 | reviewBody += `\n<sub>[Learn more](https://www.promptfoo.dev/docs/code-scanning/)</sub>`; |
| 114 | } |
| 115 | |
| 116 | return { |
| 117 | lineComments, |
| 118 | generalComments, |
| 119 | reviewBody, |
| 120 | }; |
| 121 | } |
no test coverage detected
searching dependent graphs…