(rawBody, memoryID, options)
| 36 | } |
| 37 | |
| 38 | function buildManagedMemoryBody(rawBody, memoryID, options) { |
| 39 | const { includeFooter, runUrl, workflowName, workflowSource, workflowSourceURL, historyUrl, triggeringIssueNumber, triggeringPRNumber } = options; |
| 40 | if (!/^[a-zA-Z0-9_-]+$/.test(memoryID)) { |
| 41 | throw new Error(`${SAFE_OUTPUT_E001}: memory_id must contain only alphanumeric characters, hyphens, and underscores`); |
| 42 | } |
| 43 | core.info(`comment_memory: building managed body for memory_id='${memoryID}'`); |
| 44 | // Use code-fence-as-container so the memory content is visible in GitHub's rendered Markdown. |
| 45 | // The language specifier encodes the memory ID: ``````gh-aw-comment-memory:<id> |
| 46 | const codeFenceOpener = buildCodeFenceOpener(memoryID); |
| 47 | |
| 48 | const markdownParts = assembleMarkdownBodyParts({ |
| 49 | includeFooter, |
| 50 | workflowName, |
| 51 | runUrl, |
| 52 | workflowSource, |
| 53 | workflowSourceURL, |
| 54 | triggeringIssueNumber, |
| 55 | triggeringPRNumber, |
| 56 | historyUrl, |
| 57 | markerWhenFooterDisabled: "xml", |
| 58 | }); |
| 59 | |
| 60 | // Inject CAUTION at top of body if threat detection warning was raised |
| 61 | const detectionCaution = markdownParts.detectionCaution; |
| 62 | const cautionPrefix = detectionCaution ? detectionCaution + "\n\n" : ""; |
| 63 | |
| 64 | let body = `${cautionPrefix}${MANAGED_COMMENT_HEADER}\n\n${codeFenceOpener}\n${sanitizeContent(rawBody)}\n${COMMENT_MEMORY_CODE_FENCE}`; |
| 65 | |
| 66 | const tracker = getTrackerID("markdown"); |
| 67 | if (tracker) { |
| 68 | body += `\n\n${tracker}`; |
| 69 | } |
| 70 | |
| 71 | if (includeFooter) { |
| 72 | core.info(`comment_memory: footer enabled for memory_id='${memoryID}'`); |
| 73 | const resolvedDisclosureNote = renderManagedCommentDisclosureNote(); |
| 74 | body += "\n\n" + resolvedDisclosureNote; |
| 75 | body += "\n\n" + markdownParts.footer; |
| 76 | } else { |
| 77 | core.info(`comment_memory: footer disabled for memory_id='${memoryID}', adding provenance marker only`); |
| 78 | body += "\n\n" + markdownParts.noFooterMarker; |
| 79 | } |
| 80 | |
| 81 | core.info(`comment_memory: built body length=${body.length} for memory_id='${memoryID}'`); |
| 82 | return body; |
| 83 | } |
| 84 | |
| 85 | async function findManagedComment(github, owner, repo, itemNumber, memoryID) { |
| 86 | const newFormatMarker = buildCodeFenceOpener(memoryID); |
no test coverage detected