* Add a comment with a workflow run link to the triggering item. * This script ONLY creates comments - it does NOT add reactions. * Use add_reaction.cjs in the pre-activation job to add reactions first for immediate feedback.
(rawContext = context)
| 233 | * Use add_reaction.cjs in the pre-activation job to add reactions first for immediate feedback. |
| 234 | */ |
| 235 | async function createOrReuseStatusComment(rawContext = context) { |
| 236 | const messagesConfig = getMessages(); |
| 237 | if (!parseBoolTemplatable(messagesConfig?.activationComments, true)) { |
| 238 | core.info("activation-comments is disabled: skipping activation comment creation"); |
| 239 | return null; |
| 240 | } |
| 241 | |
| 242 | const invocationContext = resolveInvocationContext(rawContext); |
| 243 | const reusableComment = readReusableStatusComment(rawContext); |
| 244 | if (reusableComment) { |
| 245 | core.info(`Reusing existing status comment ID: ${reusableComment.id}`); |
| 246 | if (!reusableComment.repo) { |
| 247 | core.warning("Reusable status comment repo missing; falling back to the invocation event repo."); |
| 248 | } |
| 249 | let reusableCommentUrl = reusableComment.url; |
| 250 | try { |
| 251 | reusableCommentUrl = await updateReusableStatusComment(reusableComment, invocationContext, rawContext); |
| 252 | core.info("Updated reusable status comment with current workflow run metadata"); |
| 253 | } catch (error) { |
| 254 | core.warning(`Failed to update reusable status comment body: ${getErrorMessage(error)}`); |
| 255 | if (!reusableCommentUrl) { |
| 256 | core.warning("No fallback reusable status comment URL available; comment-url output will be empty."); |
| 257 | } |
| 258 | } |
| 259 | const outputs = setCommentOutputs(reusableComment.id, reusableCommentUrl, reusableComment.repo || invocationContext.eventRepo, { logReuse: true }); |
| 260 | return { |
| 261 | ...outputs, |
| 262 | reused: true, |
| 263 | }; |
| 264 | } |
| 265 | |
| 266 | const runUrl = buildWorkflowRunUrl(rawContext, invocationContext.workflowRepo); |
| 267 | |
| 268 | core.info(`Run ID: ${rawContext.runId}`); |
| 269 | core.info(`Run URL: ${runUrl}`); |
| 270 | core.info(`Event source: ${invocationContext.source}`); |
| 271 | |
| 272 | // Determine the API endpoint based on the event type |
| 273 | let commentEndpoint; |
| 274 | const eventName = invocationContext.eventName; |
| 275 | const owner = invocationContext.eventRepo.owner; |
| 276 | const repo = invocationContext.eventRepo.repo; |
| 277 | const payload = invocationContext.eventPayload; |
| 278 | |
| 279 | switch (eventName) { |
| 280 | case "issues": |
| 281 | case "issue_comment": { |
| 282 | const number = payload?.issue?.number; |
| 283 | if (!number) { |
| 284 | reportCommentError(rawContext, `${ERR_NOT_FOUND}: Issue number not found in event payload`); |
| 285 | return null; |
| 286 | } |
| 287 | commentEndpoint = `/repos/${owner}/${repo}/issues/${number}/comments`; |
| 288 | break; |
| 289 | } |
| 290 | |
| 291 | case "pull_request": |
| 292 | case "pull_request_comment": |