Skip to content

Commit 399a81f

Browse files
authored
Merge pull request #1 from ravilushqa/improvements
init
2 parents 2074e97 + 373d41a commit 399a81f

File tree

10 files changed

+510
-310
lines changed

10 files changed

+510
-310
lines changed

.github/workflows/cr.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Code Review
2+
3+
permissions:
4+
contents: read
5+
pull-requests: write
6+
7+
on:
8+
pull_request:
9+
types: [opened, reopened, synchronize]
10+
11+
jobs:
12+
test:
13+
# if: ${{ contains(github.event.*.labels.*.name, 'gpt review') }} # Optional; to run only when a label is attached
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: anc95/ChatGPT-CodeReview@main
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

README.md

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,69 @@
1-
# Pull Request Description Generator
1+
# GPT-PullRequest-Updater
22

3-
This Go program automates the process of generating GitHub pull request descriptions based on the changes made in each file. It uses OpenAI's GPT-3.5-turbo model to generate the descriptions and Jira issue links based on the PR title.
3+
This repository contains a tool for updating and reviewing GitHub pull requests using OpenAI's GPT language model. The project has two commands: `description` and `review`. The `description` command updates the pull request description with a high-level summary of the changes made. The `review` command creates individual comments for each file and an overall review summary comment.
4+
5+
## Requirements
6+
7+
- GitHub token with access to the desired repository
8+
- OpenAI API token
49

510
## Installation
611

7-
To install the program, clone the repository and build the binary:
12+
1. Clone the repository:
813

9-
```sh
10-
git clone https://github.com/your-repo/pull-request-description-generator.git
11-
cd pull-request-description-generator
12-
go build
13-
```
14+
```
15+
git clone https://github.com/ravilushqa/gpt-pullrequest-updater.git
16+
```
17+
18+
2. Navigate to the project root:
19+
20+
```
21+
cd gpt-pullrequest-updater
22+
```
23+
24+
3. Build the commands:
25+
26+
```
27+
go build -o description ./cmd/description
28+
go build -o review ./cmd/review
29+
```
1430

1531
## Usage
1632

17-
Before running the program, you'll need to set the following environment variables:
33+
Before running the commands, make sure you have set the following environment variables:
34+
35+
- `GITHUB_TOKEN`: Your GitHub token
36+
- `OPENAI_TOKEN`: Your OpenAI API token
37+
- `OWNER`: The owner of the GitHub repository
38+
- `REPO`: The name of the GitHub repository
39+
- `PR_NUMBER`: The pull request number you want to update or review
1840

19-
- `GITHUB_TOKEN`: Your GitHub access token.
20-
- `OPENAI_TOKEN`: Your OpenAI access token.
21-
- `OWNER`: The GitHub owner (username or organization) of the repository.
22-
- `REPO`: The GitHub repository name.
23-
- `PR_NUMBER`: The pull request number.
41+
### Description Command
2442

25-
You can also use flags to provide the required information:
43+
The `description` command updates the pull request description with a high-level summary of the changes made. To run the command, execute:
2644

2745
```
28-
./pull-request-description-generator --gh-token <GITHUB_TOKEN> --openai-token <OPENAI_TOKEN> --owner <OWNER> --repo <REPO> --pr-number <PR_NUMBER>
46+
./description
2947
```
3048

31-
Optional flags:
49+
### Review Command
3250

33-
- `--test`: Test mode. The generated description will be printed to the console without updating the pull request.
34-
- `--skip-files`: Comma-separated list of files to skip when generating the description (default: "go.mod,go.sum,.pb.go").
51+
The `review` command creates individual comments for each file and an overall review summary comment. To run the command, execute:
3552

36-
After running the program, the pull request description will be updated with the generated content.
53+
```
54+
./review
55+
```
3756

38-
## Dependencies
57+
### Test Mode
3958

40-
- [go-flags](https://github.com/jessevdk/go-flags): A Go library for command line flag parsing.
41-
- [go-openai](https://github.com/sashabaranov/go-openai): A Go client for the OpenAI API.
59+
Both commands support a test mode that prints the generated content to the console instead of updating the pull request. To enable test mode, set the `TEST` environment variable to `true`:
4260

43-
## Functions
61+
```
62+
export TEST=true
63+
```
4464

45-
- `getDiffContent`: Fetches the diff content from the GitHub API.
46-
- `parseGitDiffAndSplitPerFile`: Parses the git diff and splits it into a slice of FileDiff.
47-
- `getFilenameFromDiffHeader`: Extracts the filename from a diff header.
48-
- `generatePRDescription`: Generates the pull request description using the OpenAI API.
49-
- `getPullRequestTitle`: Fetches the pull request title from the GitHub API.
50-
- `generateJiraLinkByTitle`: Generates a Jira issue link based on the PR title.
51-
- `updatePullRequestDescription`: Updates the pull request description on GitHub.
65+
Then, run the desired command as described above. The generated content will be printed to the console.
5266

5367
## License
5468

55-
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
69+
This project is licensed under the MIT License.

cmd/description/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# GPT Pull Request Updater
2+
3+
GPT Pull Request Updater is a command line tool that uses OpenAI's GPT-4 model to generate a comprehensive description of a GitHub pull request, including a summary of code changes. It then updates the pull request description with the generated summary.
4+
5+
## Prerequisites
6+
7+
To use the GPT Pull Request Updater, you need the following:
8+
- A GitHub token with repository access
9+
- An OpenAI API token
10+
11+
## Installation
12+
13+
1. Clone the repository:
14+
15+
```sh
16+
git clone https://github.com/ravilushqa/gpt-pullrequest-updater.git
17+
```
18+
19+
1. Change to the repository directory:
20+
21+
```sh
22+
cd gpt-pullrequest-updater
23+
```
24+
25+
1. Build the binary:
26+
27+
```sh
28+
go build -o gpt-pr-updater
29+
```
30+
31+
1. Add the binary to your PATH:
32+
33+
```sh
34+
export PATH=$PATH:$(pwd)
35+
```
36+
37+
## Usage
38+
39+
Run the GPT Pull Request Updater with the following command, providing the required flags:
40+
41+
```sh
42+
gpt-pr-updater --gh-token GITHUB_TOKEN --openai-token OPENAI_TOKEN --owner OWNER --repo REPO --pr-number PR_NUMBER
43+
```
44+
45+
### Flags
46+
47+
- `--gh-token` (required): Your GitHub token. Can also be set with the `GITHUB_TOKEN` environment variable.
48+
- `--openai-token` (required): Your OpenAI API token. Can also be set with the `OPENAI_TOKEN` environment variable.
49+
- `--owner` (required): GitHub repository owner. Can also be set with the `OWNER` environment variable.
50+
- `--repo` (required): GitHub repository name. Can also be set with the `REPO` environment variable.
51+
- `--pr-number` (required): The number of the pull request to update. Can also be set with the `PR_NUMBER` environment variable.
52+
- `--test` (optional): If set, the tool will print the generated description to the console without updating the pull request. Can also be set with the `TEST` environment variable.
53+
54+
## Example
55+
56+
```sh
57+
gpt-pr-updater --gh-token your_github_token --openai-token your_openai_token --owner ravilushqa --repo myrepo --pr-number 42
58+
```
59+
60+
This command will fetch the pull request #42 from the `myrepo` repository, generate a summary of code changes using GPT-4, and update the pull request description with the generated summary.
61+
62+
## License
63+
64+
This project is released under the [MIT License](LICENSE).

cmd/description/main.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
10+
"github.com/google/go-github/v51/github"
11+
"github.com/jessevdk/go-flags"
12+
"github.com/sashabaranov/go-openai"
13+
14+
ghClient "github.com/ravilushqa/gpt-pullrequest-updater/github"
15+
oAIClient "github.com/ravilushqa/gpt-pullrequest-updater/openai"
16+
)
17+
18+
var opts struct {
19+
GithubToken string `long:"gh-token" env:"GITHUB_TOKEN" description:"GitHub token" required:"true"`
20+
OpenAIToken string `long:"openai-token" env:"OPENAI_TOKEN" description:"OpenAI token" required:"true"`
21+
Owner string `long:"owner" env:"OWNER" description:"GitHub owner" required:"true"`
22+
Repo string `long:"repo" env:"REPO" description:"GitHub repo" required:"true"`
23+
PRNumber int `long:"pr-number" env:"PR_NUMBER" description:"Pull request number" required:"true"`
24+
Test bool `long:"test" env:"TEST" description:"Test mode"`
25+
}
26+
27+
func main() {
28+
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
29+
defer cancel()
30+
31+
if _, err := flags.Parse(&opts); err != nil {
32+
if err.(*flags.Error).Type != flags.ErrHelp {
33+
fmt.Printf("Error parsing flags: %v \n", err)
34+
}
35+
os.Exit(0)
36+
}
37+
38+
if err := run(ctx); err != nil {
39+
panic(err)
40+
}
41+
}
42+
43+
func run(ctx context.Context) error {
44+
openAIClient := oAIClient.NewClient(opts.OpenAIToken)
45+
githubClient := ghClient.NewClient(ctx, opts.GithubToken)
46+
47+
pr, err := githubClient.GetPullRequest(ctx, opts.Owner, opts.Repo, opts.PRNumber)
48+
if err != nil {
49+
return fmt.Errorf("error getting pull request: %w", err)
50+
}
51+
52+
diff, err := githubClient.CompareCommits(ctx, opts.Owner, opts.Repo, pr.GetBase().GetSHA(), pr.GetHead().GetSHA())
53+
if err != nil {
54+
return fmt.Errorf("error getting commits: %w", err)
55+
}
56+
57+
var OverallDescribeCompletion string
58+
OverallDescribeCompletion += fmt.Sprintf("Pull request title: %s, body: %s\n\n", pr.GetTitle(), pr.GetBody())
59+
for _, file := range diff.Files {
60+
prompt := fmt.Sprintf(oAIClient.PromptDescribeChanges, *file.Patch)
61+
62+
if len(prompt) > 4096 {
63+
prompt = fmt.Sprintf("%s...", prompt[:4093])
64+
}
65+
66+
completion, err := openAIClient.ChatCompletion(ctx, []openai.ChatCompletionMessage{
67+
{
68+
Role: openai.ChatMessageRoleUser,
69+
Content: prompt,
70+
},
71+
})
72+
if err != nil {
73+
return fmt.Errorf("error getting review: %w", err)
74+
}
75+
OverallDescribeCompletion += fmt.Sprintf("File: %s \nDescription: %s \n\n", file.GetFilename(), completion)
76+
}
77+
78+
overallCompletion, err := openAIClient.ChatCompletion(ctx, []openai.ChatCompletionMessage{
79+
{
80+
Role: openai.ChatMessageRoleUser,
81+
Content: fmt.Sprintf(oAIClient.PromptOverallDescribe, OverallDescribeCompletion),
82+
},
83+
})
84+
if err != nil {
85+
return fmt.Errorf("error getting overall review: %w", err)
86+
}
87+
88+
if opts.Test {
89+
fmt.Println(OverallDescribeCompletion)
90+
fmt.Println("=====================================")
91+
fmt.Println(overallCompletion)
92+
93+
return nil
94+
}
95+
96+
// Update the pull request description
97+
updatePr := &github.PullRequest{Body: github.String(overallCompletion)}
98+
if _, err = githubClient.UpdatePullRequest(ctx, opts.Owner, opts.Repo, opts.PRNumber, updatePr); err != nil {
99+
return fmt.Errorf("error updating pull request: %w", err)
100+
}
101+
102+
return nil
103+
}

0 commit comments

Comments
 (0)