33import { createOctokit } from "../github/api/client" ;
44import * as fs from "fs/promises" ;
55import {
6- updateCommentBody ,
7- type CommentUpdateInput ,
6+ type ExecutionDetails ,
87} from "../github/operations/comment-logic" ;
98import {
109 parseGitHubContext ,
11- isPullRequestReviewCommentEvent ,
1210} from "../github/context" ;
1311import { GITHUB_SERVER_URL } from "../github/api/config" ;
1412import { checkAndDeleteEmptyBranch } from "../github/operations/branch-cleanup" ;
15- import { updateClaudeComment } from "../github/operations/comments/update-claude-comment" ;
13+ import { OutputManager , type OutputIdentifiers } from "../output-manager" ;
14+ import type { ReviewContent } from "../output-strategies/base" ;
1615
1716async function run ( ) {
1817 try {
19- const commentId = parseInt ( process . env . CLAUDE_COMMENT_ID ! ) ;
18+ // Legacy fallback for claude_comment_id
19+ const legacyCommentId = process . env . CLAUDE_COMMENT_ID ;
20+ const outputIdentifiersJson = process . env . OUTPUT_IDENTIFIERS ;
2021 const githubToken = process . env . GITHUB_TOKEN ! ;
2122 const claudeBranch = process . env . CLAUDE_BRANCH ;
2223 const baseBranch = process . env . BASE_BRANCH || "main" ;
2324 const triggerUsername = process . env . TRIGGER_USERNAME ;
25+ const outputModes = OutputManager . parseOutputModes ( process . env . OUTPUT_MODE || "pr_comment" ) ;
26+ const commitSha = process . env . COMMIT_SHA ;
2427
2528 const context = parseGitHubContext ( ) ;
2629 const { owner, repo } = context . repository ;
2730 const octokit = createOctokit ( githubToken ) ;
2831
32+ // Parse output identifiers from prepare step or fall back to legacy
33+ let outputIdentifiers : OutputIdentifiers ;
34+ if ( outputIdentifiersJson ) {
35+ outputIdentifiers = OutputManager . deserializeIdentifiers ( outputIdentifiersJson ) ;
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 ( outputModes , octokit . rest , context , commitSha ) ;
45+
2946 const serverUrl = GITHUB_SERVER_URL ;
3047 const jobUrl = `${ serverUrl } /${ owner } /${ repo } /actions/runs/${ process . env . GITHUB_RUN_ID } ` ;
3148
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
49+ // For legacy support, we still need to fetch the current body if we have a pr_comment identifier
50+ let currentBody = "" ;
51+ if ( outputIdentifiers . pr_comment ) {
7252 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" ) ;
53+ const commentId = parseInt ( outputIdentifiers . pr_comment ) ;
54+ // Try to fetch the current comment body for the update
55+ try {
56+ const { data : issueComment } = await octokit . rest . issues . getComment ( {
57+ owner,
58+ repo,
59+ comment_id : commentId ,
60+ } ) ;
61+ currentBody = issueComment . body ?? "" ;
62+ } catch {
63+ // If issue comment fails, try PR review comment
64+ const { data : prComment } = await octokit . rest . pulls . getReviewComment ( {
65+ owner,
66+ repo,
67+ comment_id : commentId ,
68+ } ) ;
69+ currentBody = prComment . body ?? "" ;
70+ }
71+ } catch ( error ) {
72+ console . warn ( "Could not fetch current comment body, proceeding with empty body:" , error ) ;
8373 }
84-
85- throw finalError ;
8674 }
8775
88- const currentBody = comment . body ?? "" ;
89-
9076 // Check if we need to add branch link for new branches
9177 const { shouldDeleteBranch, branchLink } = await checkAndDeleteEmptyBranch (
9278 octokit ,
@@ -140,11 +126,7 @@ async function run() {
140126 }
141127
142128 // 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 ;
129+ let executionDetails : ExecutionDetails | null = null ;
148130 let actionFailed = false ;
149131 let errorDetails : string | undefined ;
150132
@@ -190,9 +172,10 @@ async function run() {
190172 }
191173 }
192174
193- // Prepare input for updateCommentBody function
194- const commentInput : CommentUpdateInput = {
195- currentBody,
175+ // Prepare content for all output strategies
176+ const reviewContent : ReviewContent = {
177+ summary : actionFailed ? "Action failed" : "Action completed" ,
178+ body : currentBody ,
196179 actionFailed,
197180 executionDetails,
198181 jobUrl,
@@ -203,26 +186,9 @@ async function run() {
203186 errorDetails,
204187 } ;
205188
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- }
189+ // Use OutputManager to update all configured output strategies
190+ await outputManager . updateFinal ( outputIdentifiers , context , reviewContent ) ;
191+ console . log ( "✅ Updated all configured output strategies" ) ;
226192
227193 process . exit ( 0 ) ;
228194 } catch ( error ) {
0 commit comments