@@ -12,6 +12,7 @@ import (
12
12
"github.com/sashabaranov/go-openai"
13
13
14
14
ghClient "github.com/ravilushqa/gpt-pullrequest-updater/github"
15
+ "github.com/ravilushqa/gpt-pullrequest-updater/jira"
15
16
oAIClient "github.com/ravilushqa/gpt-pullrequest-updater/openai"
16
17
)
17
18
@@ -22,6 +23,7 @@ var opts struct {
22
23
Repo string `long:"repo" env:"REPO" description:"GitHub repo" required:"true"`
23
24
PRNumber int `long:"pr-number" env:"PR_NUMBER" description:"Pull request number" required:"true"`
24
25
Test bool `long:"test" env:"TEST" description:"Test mode"`
26
+ JiraURL string `long:"jira-url" env:"JIRA_URL" description:"Jira URL"`
25
27
}
26
28
27
29
func main () {
@@ -35,6 +37,10 @@ func main() {
35
37
os .Exit (0 )
36
38
}
37
39
40
+ if opts .Test {
41
+ fmt .Println ("Test mode" )
42
+ }
43
+
38
44
if err := run (ctx ); err != nil {
39
45
panic (err )
40
46
}
@@ -54,55 +60,110 @@ func run(ctx context.Context) error {
54
60
return fmt .Errorf ("error getting commits: %w" , err )
55
61
}
56
62
57
- var OverallDescribeCompletion string
58
- OverallDescribeCompletion += fmt .Sprintf ("Pull request title: %s, body: %s\n \n " , pr .GetTitle (), pr .GetBody ())
63
+ var sumDiffs int
59
64
for _ , file := range diff .Files {
65
+ sumDiffs += len (* file .Patch )
66
+ }
60
67
68
+ var completion string
69
+ if sumDiffs < 4000 {
70
+ completion , err = genCompletionOnce (ctx , openAIClient , diff )
71
+ if err != nil {
72
+ return fmt .Errorf ("error generating completition once: %w" , err )
73
+ }
74
+ } else {
75
+ completion , err = genCompletionPerFile (ctx , openAIClient , diff , pr )
76
+ if err != nil {
77
+ return fmt .Errorf ("error generating completition twice: %w" , err )
78
+ }
79
+ }
80
+
81
+ if opts .JiraURL != "" {
82
+ fmt .Println ("Adding Jira ticket" )
83
+ id , err := jira .ExtractJiraTicketID (* pr .Title )
84
+ if err != nil {
85
+ fmt .Printf ("Error extracting Jira ticket ID: %v \n " , err )
86
+ } else {
87
+ completion = fmt .Sprintf ("### JIRA ticket: [%s](%s) \n \n %s" , id , jira .GenerateJiraTicketURL (opts .JiraURL , id ), completion )
88
+ }
89
+ }
90
+
91
+ if opts .Test {
92
+ fmt .Println (completion )
93
+ return nil
94
+ }
95
+
96
+ // Update the pull request description
97
+ fmt .Println ("Updating pull request" )
98
+ updatePr := & github.PullRequest {Body : github .String (completion )}
99
+ if _ , err = githubClient .UpdatePullRequest (ctx , opts .Owner , opts .Repo , opts .PRNumber , updatePr ); err != nil {
100
+ return fmt .Errorf ("error updating pull request: %w" , err )
101
+ }
102
+
103
+ return nil
104
+ }
105
+
106
+ func genCompletionOnce (ctx context.Context , client * oAIClient.Client , diff * github.CommitsComparison ) (string , error ) {
107
+ fmt .Println ("Generating completion once" )
108
+ messages := make ([]openai.ChatCompletionMessage , 0 , len (diff .Files ))
109
+ messages = append (messages , openai.ChatCompletionMessage {
110
+ Role : openai .ChatMessageRoleUser ,
111
+ Content : oAIClient .PromptDescribeChanges ,
112
+ })
113
+ for _ , file := range diff .Files {
61
114
if file .Patch == nil {
62
115
continue
63
116
}
64
117
118
+ messages = append (messages , openai.ChatCompletionMessage {
119
+ Role : openai .ChatMessageRoleUser ,
120
+ Content : * file .Patch ,
121
+ })
122
+ }
123
+
124
+ fmt .Println ("Sending prompt to OpenAI" )
125
+ completion , err := client .ChatCompletion (ctx , messages )
126
+ if err != nil {
127
+ return "" , fmt .Errorf ("error completing prompt: %w" , err )
128
+ }
129
+
130
+ return completion , nil
131
+ }
132
+
133
+ func genCompletionPerFile (ctx context.Context , client * oAIClient.Client , diff * github.CommitsComparison , pr * github.PullRequest ) (string , error ) {
134
+ fmt .Println ("Generating completion per file" )
135
+ OverallDescribeCompletion := fmt .Sprintf ("Pull request title: %s, body: %s\n \n " , pr .GetTitle (), pr .GetBody ())
136
+
137
+ for i , file := range diff .Files {
65
138
prompt := fmt .Sprintf (oAIClient .PromptDescribeChanges , * file .Patch )
66
139
67
140
if len (prompt ) > 4096 {
68
141
prompt = fmt .Sprintf ("%s..." , prompt [:4093 ])
69
142
}
70
143
71
- completion , err := openAIClient .ChatCompletion (ctx , []openai.ChatCompletionMessage {
144
+ fmt .Printf ("Sending prompt to OpenAI for file %d/%d\n " , i + 1 , len (diff .Files ))
145
+ completion , err := client .ChatCompletion (ctx , []openai.ChatCompletionMessage {
72
146
{
73
147
Role : openai .ChatMessageRoleUser ,
74
148
Content : prompt ,
75
149
},
76
150
})
77
151
if err != nil {
78
- return fmt .Errorf ("error getting review: %w" , err )
152
+ return "" , fmt .Errorf ("error getting review: %w" , err )
79
153
}
80
154
OverallDescribeCompletion += fmt .Sprintf ("File: %s \n Description: %s \n \n " , file .GetFilename (), completion )
81
155
}
82
156
83
- overallCompletion , err := openAIClient .ChatCompletion (ctx , []openai.ChatCompletionMessage {
157
+ fmt .Println ("Sending final prompt to OpenAI" )
158
+ overallCompletion , err := client .ChatCompletion (ctx , []openai.ChatCompletionMessage {
84
159
{
85
160
Role : openai .ChatMessageRoleUser ,
86
161
Content : fmt .Sprintf (oAIClient .PromptOverallDescribe , OverallDescribeCompletion ),
87
162
},
88
163
})
89
164
if err != nil {
90
- return fmt .Errorf ("error getting overall review: %w" , err )
91
- }
92
-
93
- if opts .Test {
94
- fmt .Println (OverallDescribeCompletion )
95
- fmt .Println ("=====================================" )
96
- fmt .Println (overallCompletion )
97
-
98
- return nil
165
+ return "" , fmt .Errorf ("error getting overall review: %w" , err )
99
166
}
100
167
101
- // Update the pull request description
102
- updatePr := & github.PullRequest {Body : github .String (overallCompletion )}
103
- if _ , err = githubClient .UpdatePullRequest (ctx , opts .Owner , opts .Repo , opts .PRNumber , updatePr ); err != nil {
104
- return fmt .Errorf ("error updating pull request: %w" , err )
105
- }
106
-
107
- return nil
168
+ return overallCompletion , nil
108
169
}
0 commit comments