22
33import { createOctokit } from "../github/api/client" ;
44import * as fs from "fs/promises" ;
5- import {
6- updateCommentBody ,
7- type CommentUpdateInput ,
8- } from "../github/operations/comment-logic" ;
9- import {
10- parseGitHubContext ,
11- isPullRequestReviewCommentEvent ,
12- } from "../github/context" ;
5+ import { type ExecutionDetails } from "../github/operations/comment-logic" ;
6+ import { parseGitHubContext } from "../github/context" ;
137import { GITHUB_SERVER_URL } from "../github/api/config" ;
148import { checkAndDeleteEmptyBranch } from "../github/operations/branch-cleanup" ;
15- import { updateClaudeComment } from "../github/operations/comments/update-claude-comment" ;
9+ import { OutputManager , type OutputIdentifiers } from "../output-manager" ;
10+ import type { ReviewContent } from "../output-strategies/base" ;
1611
1712async function run ( ) {
1813 try {
19- const commentId = parseInt ( process . env . CLAUDE_COMMENT_ID ! ) ;
14+ // Legacy fallback for claude_comment_id
15+ const legacyCommentId = process . env . CLAUDE_COMMENT_ID ;
16+ const outputIdentifiersJson = process . env . OUTPUT_IDENTIFIERS ;
2017 const githubToken = process . env . GITHUB_TOKEN ! ;
2118 const claudeBranch = process . env . CLAUDE_BRANCH ;
2219 const baseBranch = process . env . BASE_BRANCH || "main" ;
2320 const triggerUsername = process . env . TRIGGER_USERNAME ;
21+ const outputModes = OutputManager . parseOutputModes (
22+ process . env . OUTPUT_MODE || "pr_comment" ,
23+ ) ;
24+ const commitSha = process . env . COMMIT_SHA ;
2425
2526 const context = parseGitHubContext ( ) ;
2627 const { owner, repo } = context . repository ;
2728 const octokit = createOctokit ( githubToken ) ;
2829
30+ // Parse output identifiers from prepare step or fall back to legacy
31+ let outputIdentifiers : OutputIdentifiers ;
32+ if ( outputIdentifiersJson ) {
33+ outputIdentifiers = OutputManager . deserializeIdentifiers (
34+ outputIdentifiersJson ,
35+ ) ;
36+ } else if ( legacyCommentId ) {
37+ // Legacy fallback - assume pr_comment mode
38+ outputIdentifiers = { pr_comment : legacyCommentId } ;
39+ } else {
40+ outputIdentifiers = { } ;
41+ }
42+
43+ // Create output manager for final update
44+ const outputManager = new OutputManager (
45+ outputModes ,
46+ octokit . rest ,
47+ context ,
48+ commitSha ,
49+ ) ;
50+
2951 const serverUrl = GITHUB_SERVER_URL ;
3052 const jobUrl = `${ serverUrl } /${ owner } /${ repo } /actions/runs/${ process . env . GITHUB_RUN_ID } ` ;
3153
32- let comment ;
33- let isPRReviewComment = false ;
34-
35- try {
36- // GitHub has separate ID namespaces for review comments and issue comments
37- // We need to use the correct API based on the event type
38- if ( isPullRequestReviewCommentEvent ( context ) ) {
39- // For PR review comments, use the pulls API
40- console . log ( `Fetching PR review comment ${ commentId } ` ) ;
41- const { data : prComment } = await octokit . rest . pulls . getReviewComment ( {
42- owner,
43- repo,
44- comment_id : commentId ,
45- } ) ;
46- comment = prComment ;
47- isPRReviewComment = true ;
48- console . log ( "Successfully fetched as PR review comment" ) ;
49- }
50-
51- // For all other event types, use the issues API
52- if ( ! comment ) {
53- console . log ( `Fetching issue comment ${ commentId } ` ) ;
54- const { data : issueComment } = await octokit . rest . issues . getComment ( {
55- owner,
56- repo,
57- comment_id : commentId ,
58- } ) ;
59- comment = issueComment ;
60- isPRReviewComment = false ;
61- console . log ( "Successfully fetched as issue comment" ) ;
62- }
63- } catch ( finalError ) {
64- // If all attempts fail, try to determine more information about the comment
65- console . error ( "Failed to fetch comment. Debug info:" ) ;
66- console . error ( `Comment ID: ${ commentId } ` ) ;
67- console . error ( `Event name: ${ context . eventName } ` ) ;
68- console . error ( `Entity number: ${ context . entityNumber } ` ) ;
69- console . error ( `Repository: ${ context . repository . full_name } ` ) ;
70-
71- // Try to get the PR info to understand the comment structure
54+ // For legacy support, we still need to fetch the current body if we have a pr_comment identifier
55+ let currentBody = "" ;
56+ if ( outputIdentifiers . pr_comment ) {
7257 try {
73- const { data : pr } = await octokit . rest . pulls . get ( {
74- owner,
75- repo,
76- pull_number : context . entityNumber ,
77- } ) ;
78- console . log ( `PR state: ${ pr . state } ` ) ;
79- console . log ( `PR comments count: ${ pr . comments } ` ) ;
80- console . log ( `PR review comments count: ${ pr . review_comments } ` ) ;
81- } catch {
82- console . error ( "Could not fetch PR info for debugging" ) ;
58+ const commentId = parseInt ( outputIdentifiers . pr_comment ) ;
59+ // Try to fetch the current comment body for the update
60+ try {
61+ const { data : issueComment } = await octokit . rest . issues . getComment ( {
62+ owner,
63+ repo,
64+ comment_id : commentId ,
65+ } ) ;
66+ currentBody = issueComment . body ?? "" ;
67+ } catch {
68+ // If issue comment fails, try PR review comment
69+ const { data : prComment } = await octokit . rest . pulls . getReviewComment (
70+ {
71+ owner,
72+ repo,
73+ comment_id : commentId ,
74+ } ,
75+ ) ;
76+ currentBody = prComment . body ?? "" ;
77+ }
78+ } catch ( error ) {
79+ console . warn (
80+ "Could not fetch current comment body, proceeding with empty body:" ,
81+ error ,
82+ ) ;
8383 }
84-
85- throw finalError ;
8684 }
8785
88- const currentBody = comment . body ?? "" ;
89-
9086 // Check if we need to add branch link for new branches
9187 const { shouldDeleteBranch, branchLink } = await checkAndDeleteEmptyBranch (
9288 octokit ,
@@ -140,11 +136,7 @@ async function run() {
140136 }
141137
142138 // Check if action failed and read output file for execution details
143- let executionDetails : {
144- cost_usd ?: number ;
145- duration_ms ?: number ;
146- duration_api_ms ?: number ;
147- } | null = null ;
139+ let executionDetails : ExecutionDetails | null = null ;
148140 let actionFailed = false ;
149141 let errorDetails : string | undefined ;
150142
@@ -190,9 +182,10 @@ async function run() {
190182 }
191183 }
192184
193- // Prepare input for updateCommentBody function
194- const commentInput : CommentUpdateInput = {
195- currentBody,
185+ // Prepare content for all output strategies
186+ const reviewContent : ReviewContent = {
187+ summary : actionFailed ? "Action failed" : "Action completed" ,
188+ body : currentBody ,
196189 actionFailed,
197190 executionDetails,
198191 jobUrl,
@@ -203,26 +196,9 @@ async function run() {
203196 errorDetails,
204197 } ;
205198
206- const updatedBody = updateCommentBody ( commentInput ) ;
207-
208- try {
209- await updateClaudeComment ( octokit . rest , {
210- owner,
211- repo,
212- commentId,
213- body : updatedBody ,
214- isPullRequestReviewComment : isPRReviewComment ,
215- } ) ;
216- console . log (
217- `✅ Updated ${ isPRReviewComment ? "PR review" : "issue" } comment ${ commentId } with job link` ,
218- ) ;
219- } catch ( updateError ) {
220- console . error (
221- `Failed to update ${ isPRReviewComment ? "PR review" : "issue" } comment:` ,
222- updateError ,
223- ) ;
224- throw updateError ;
225- }
199+ // Use OutputManager to update all configured output strategies
200+ await outputManager . updateFinal ( outputIdentifiers , context , reviewContent ) ;
201+ console . log ( "✅ Updated all configured output strategies" ) ;
226202
227203 process . exit ( 0 ) ;
228204 } catch ( error ) {
0 commit comments