@alibaba-group/open-code-review 1.1.8 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +0 -1
- package/CONTRIBUTING.zh-CN.md +0 -1
- package/README.md +301 -45
- package/README.zh-CN.md +21 -0
- package/examples/README.md +10 -0
- package/examples/github_actions/README.md +223 -0
- package/examples/github_actions/ocr-review.yml +321 -0
- package/examples/gitlab_ci/.gitlab-ci.yml +225 -0
- package/examples/gitlab_ci/README.md +268 -0
- package/package.json +2 -4
- package/NPM-README.md +0 -95
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# OpenCodeReview - GitLab CI Demo
|
|
2
|
+
|
|
3
|
+
This demo shows how to integrate OpenCodeReview into your GitLab CI/CD pipeline to automatically review Merge Requests and post review comments as inline discussions.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
MR Created/Updated → GitLab Pipeline Triggered → OCR Reviews Diff → Discussions Posted on MR
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
1. When a Merge Request is opened or updated, the pipeline triggers
|
|
12
|
+
2. It installs OCR via npm in a `node:20` Docker image
|
|
13
|
+
3. Runs `ocr review --from origin/<target> --to origin/<source> --format json` to analyze the diff
|
|
14
|
+
4. Parses the JSON output and posts inline discussions on the MR using GitLab's Discussions API
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
### 1. Copy the pipeline file
|
|
19
|
+
|
|
20
|
+
Copy `.gitlab-ci.yml` to your repository root (or include it via `include:`):
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cp .gitlab-ci.yml /path/to/your/repo/.gitlab-ci.yml
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or use GitLab's `include` feature in your existing `.gitlab-ci.yml`:
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
include:
|
|
30
|
+
- local: 'ci_demo/gitlab_ci/.gitlab-ci.yml'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Configure CI/CD Variables
|
|
34
|
+
|
|
35
|
+
Go to your project's **Settings → CI/CD → Variables** and add:
|
|
36
|
+
|
|
37
|
+
| Variable | Required | Masked | Description |
|
|
38
|
+
|----------|----------|--------|-------------|
|
|
39
|
+
| `OCR_LLM_URL` | Yes | No | LLM API endpoint URL (e.g., `https://api.openai.com/v1/chat/completions`) |
|
|
40
|
+
| `OCR_LLM_AUTH_TOKEN` | Yes | Yes | API authentication token |
|
|
41
|
+
| `OCR_LLM_MODEL` | No | No | Model name (defaults to `gpt-4o`) |
|
|
42
|
+
| `GITLAB_API_TOKEN` | Yes | Yes | GitLab access token with `api` scope |
|
|
43
|
+
|
|
44
|
+
> **Note:** GitLab CI/CD does not support variables with values shorter than 8 characters, so `use_anthropic` cannot be set as a CI variable. The pipeline sets it to `false` by default. If you need to use Anthropic Claude models, you'll need to modify the `.gitlab-ci.yml` script directly.
|
|
45
|
+
>
|
|
46
|
+
> The pipeline also configures `llm.extra_body` to disable thinking mode for compatibility with various LLM providers.
|
|
47
|
+
|
|
48
|
+
### 3. Create a GitLab Access Token
|
|
49
|
+
|
|
50
|
+
You need a token with `api` scope to post discussions on MRs. Options:
|
|
51
|
+
|
|
52
|
+
- **Project Access Token** (recommended): Settings → Access Tokens → Create with `api` scope
|
|
53
|
+
- **Personal Access Token**: User Settings → Access Tokens → Create with `api` scope
|
|
54
|
+
- **Group Access Token**: For organization-wide usage
|
|
55
|
+
|
|
56
|
+
> **Note:** The built-in `CI_JOB_TOKEN` does NOT have sufficient permissions to create MR discussions, which is why a separate token is needed.
|
|
57
|
+
>
|
|
58
|
+
> **Tip:** For Project Access Tokens and Group Access Tokens, the token name determines the bot name shown in MR discussions. For example, naming your token `OpenCodeReview Bot` will make review comments appear as posted by `OpenCodeReview Bot`.
|
|
59
|
+
|
|
60
|
+
## Example Output
|
|
61
|
+
|
|
62
|
+
When an MR is reviewed, comments appear as:
|
|
63
|
+
|
|
64
|
+
- **Inline discussions**: Directly on the changed lines in the MR diff view
|
|
65
|
+
- **Summary note**: A final note summarizing the total number of issues found
|
|
66
|
+
- **Fallback notes**: If inline posting fails for specific comments, they appear as regular MR notes with file/line references
|
|
67
|
+
|
|
68
|
+
### Inline Discussion Example
|
|
69
|
+
|
|
70
|
+
Comments are posted using GitLab's Discussion API with position data, so they appear directly next to the relevant code in the "Changes" tab.
|
|
71
|
+
|
|
72
|
+
## Supported LLM Providers
|
|
73
|
+
|
|
74
|
+
OCR supports both OpenAI and Anthropic API formats:
|
|
75
|
+
|
|
76
|
+
- **OpenAI-compatible APIs** (default):
|
|
77
|
+
- OpenAI (GPT-4o, GPT-4, etc.)
|
|
78
|
+
- Azure OpenAI
|
|
79
|
+
- Self-hosted models (vLLM, Ollama, etc.)
|
|
80
|
+
- **Anthropic APIs** (modify `.gitlab-ci.yml` to set `use_anthropic: true`):
|
|
81
|
+
- Anthropic Claude models
|
|
82
|
+
|
|
83
|
+
## Customization
|
|
84
|
+
|
|
85
|
+
### Use a specific OCR version
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
script:
|
|
89
|
+
- npm install -g @alibaba-group/open-code-review@1.0.0
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Add custom review rules
|
|
93
|
+
|
|
94
|
+
Use the `--rule` flag to pass a custom rules JSON file:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
script:
|
|
98
|
+
- ocr review --rule ./my-rules.json --from origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --to origin/$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Limit concurrency
|
|
102
|
+
|
|
103
|
+
Adjust the `--concurrency` flag for large MRs to control the number of concurrent LLM requests:
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
script:
|
|
107
|
+
- ocr review --concurrency 5 --from origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --to origin/$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Provide background context
|
|
111
|
+
|
|
112
|
+
Use the `--background` flag to pass additional context that helps OCR better understand the purpose of the changes:
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
script:
|
|
116
|
+
- ocr review --background "$CI_MERGE_REQUEST_TITLE" --from origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --to origin/$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This is particularly useful when your MR titles follow semantic conventions (e.g., `feat(auth): add OAuth2 support`) that clearly summarize what the MR implements. The background information helps OCR provide more relevant and context-aware review comments.
|
|
120
|
+
|
|
121
|
+
### Change the trigger events
|
|
122
|
+
|
|
123
|
+
By default, the pipeline uses `only: [merge_requests]`, which triggers on **all** MR events (creation, updates, reopen). GitLab CI does not natively support fine-grained control to trigger **only on MR creation**.
|
|
124
|
+
|
|
125
|
+
To avoid re-reviewing on every push to an existing MR (and wasting LLM API tokens), you can check for existing OCR reviews **before** running `ocr review`. Use a wrapper script that skips the review step if OCR comments already exist:
|
|
126
|
+
|
|
127
|
+
```yaml
|
|
128
|
+
script:
|
|
129
|
+
# Install OpenCodeReview
|
|
130
|
+
- npm install -g @alibaba-group/open-code-review
|
|
131
|
+
|
|
132
|
+
# Configure OCR
|
|
133
|
+
- mkdir -p ~/.open-code-review
|
|
134
|
+
- |
|
|
135
|
+
ocr config set llm.url $OCR_LLM_URL
|
|
136
|
+
ocr config set llm.auth_token $OCR_LLM_AUTH_TOKEN
|
|
137
|
+
ocr config set llm.model $OCR_LLM_MODEL
|
|
138
|
+
ocr config set llm.use_anthropic false
|
|
139
|
+
ocr config set llm.extra_body '{"thinking": {"type": "disabled"}}'
|
|
140
|
+
|
|
141
|
+
# Check for existing OCR reviews and run review only if not found
|
|
142
|
+
- |
|
|
143
|
+
python3 << 'WRAPPER_SCRIPT'
|
|
144
|
+
import json
|
|
145
|
+
import os
|
|
146
|
+
import subprocess
|
|
147
|
+
import sys
|
|
148
|
+
import urllib.request
|
|
149
|
+
|
|
150
|
+
GITLAB_URL = os.environ.get("CI_SERVER_URL", "https://gitlab.com")
|
|
151
|
+
PROJECT_ID = os.environ["CI_PROJECT_ID"]
|
|
152
|
+
MR_IID = os.environ["CI_MERGE_REQUEST_IID"]
|
|
153
|
+
API_TOKEN = os.environ["GITLAB_API_TOKEN"]
|
|
154
|
+
SOURCE_BRANCH = os.environ["CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"]
|
|
155
|
+
TARGET_BRANCH = os.environ["CI_MERGE_REQUEST_TARGET_BRANCH_NAME"]
|
|
156
|
+
|
|
157
|
+
# Check for existing OCR reviews
|
|
158
|
+
url = f"{GITLAB_URL}/api/v4/projects/{PROJECT_ID}/merge_requests/{MR_IID}/notes?per_page=100"
|
|
159
|
+
req = urllib.request.Request(url, headers={"PRIVATE-TOKEN": API_TOKEN})
|
|
160
|
+
with urllib.request.urlopen(req) as resp:
|
|
161
|
+
notes = json.loads(resp.read().decode("utf-8"))
|
|
162
|
+
|
|
163
|
+
for note in notes:
|
|
164
|
+
if "OpenCodeReview" in note.get("body", ""):
|
|
165
|
+
print("⏭️ OCR has already reviewed this MR. Skipping to save tokens.")
|
|
166
|
+
print("Delete previous OCR comments to re-trigger review.")
|
|
167
|
+
sys.exit(0)
|
|
168
|
+
|
|
169
|
+
# No existing review found - run OCR
|
|
170
|
+
print("🔍 No existing OCR review found. Running review...")
|
|
171
|
+
result = subprocess.run([
|
|
172
|
+
"ocr", "review",
|
|
173
|
+
"--from", f"origin/{TARGET_BRANCH}",
|
|
174
|
+
"--to", f"origin/{SOURCE_BRANCH}",
|
|
175
|
+
"--format", "json",
|
|
176
|
+
"--audience", "agent"
|
|
177
|
+
], capture_output=True, text=True)
|
|
178
|
+
|
|
179
|
+
# Save output for the posting script
|
|
180
|
+
with open("/tmp/ocr-result.json", "w") as f:
|
|
181
|
+
f.write(result.stdout)
|
|
182
|
+
with open("/tmp/ocr-stderr.log", "w") as f:
|
|
183
|
+
f.write(result.stderr)
|
|
184
|
+
|
|
185
|
+
print("OCR review completed.")
|
|
186
|
+
WRAPPER_SCRIPT
|
|
187
|
+
|
|
188
|
+
# Post review comments to MR
|
|
189
|
+
- |
|
|
190
|
+
python3 << 'PYTHON_SCRIPT'
|
|
191
|
+
...existing post script...
|
|
192
|
+
PYTHON_SCRIPT
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The key logic: the Python wrapper checks for existing OCR comments before running `ocr review`. If found, it exits early with `sys.exit(0)` before consuming any LLM tokens. To re-trigger a review, users can manually delete the previous OCR comments.
|
|
196
|
+
|
|
197
|
+
### Self-hosted GitLab
|
|
198
|
+
|
|
199
|
+
The script automatically uses `CI_SERVER_URL` to determine the GitLab API base URL, so it works with self-hosted GitLab instances out of the box.
|
|
200
|
+
|
|
201
|
+
### Use a Service Account as Review Bot
|
|
202
|
+
|
|
203
|
+
By default, review comments are posted using the user who owns the access token configured in `GITLAB_API_TOKEN`. You can create a dedicated service account bot to post reviews with a custom identity, making it easier to distinguish automated reviews from human comments.
|
|
204
|
+
|
|
205
|
+
For more details about GitLab service accounts, see the [GitLab Service Accounts documentation](https://docs.gitlab.com/ee/user/profile/service_accounts.html).
|
|
206
|
+
|
|
207
|
+
#### Step 1: Create a Service Account
|
|
208
|
+
|
|
209
|
+
Create a service account in your project:
|
|
210
|
+
|
|
211
|
+
1. Go to your **Project → Settings → Service Accounts**
|
|
212
|
+
2. Click **New service account**
|
|
213
|
+
3. Fill in the following:
|
|
214
|
+
- **Name**: e.g., `OpenCodeReview Bot` (this will be the bot name shown in MR discussions)
|
|
215
|
+
- **Username**: Will be auto-generated based on the name
|
|
216
|
+
4. Click **Create service account**
|
|
217
|
+
|
|
218
|
+
#### Step 2: Invite the Service Account to Your Project
|
|
219
|
+
|
|
220
|
+
After the service account is created, invite it to your project with appropriate permissions:
|
|
221
|
+
|
|
222
|
+
1. Go to your **Project → Settings → Members**
|
|
223
|
+
2. Click **Invite member**
|
|
224
|
+
3. Search for the service account by name (e.g., `OpenCodeReview Bot`)
|
|
225
|
+
4. Select the service account and assign a role (`Developer` or `Maintainer` required for posting discussions)
|
|
226
|
+
5. Click **Invite**
|
|
227
|
+
|
|
228
|
+
#### Step 3: Create an Access Token
|
|
229
|
+
|
|
230
|
+
Generate an access token for the service account:
|
|
231
|
+
|
|
232
|
+
1. Go to your **Project → Settings → Service Accounts**
|
|
233
|
+
2. Click on the service account to view its details
|
|
234
|
+
3. Click **Add new token**
|
|
235
|
+
4. Configure the token:
|
|
236
|
+
- **Name**: e.g., `ocr-review-token`
|
|
237
|
+
- **Expiration**: As needed
|
|
238
|
+
- **Scope**: Select `api` (required for Discussions API)
|
|
239
|
+
5. Click **Create token** and copy the token value
|
|
240
|
+
|
|
241
|
+
#### Step 4: Update CI/CD Variables
|
|
242
|
+
|
|
243
|
+
Update the `GITLAB_API_TOKEN` variable in your project's CI/CD settings:
|
|
244
|
+
|
|
245
|
+
Go to **Settings → CI/CD → Variables** and update `GITLAB_API_TOKEN` with the service account's token.
|
|
246
|
+
|
|
247
|
+
Now review comments will be posted with your service account identity (e.g., `OpenCodeReview Bot`), providing a clear and professional appearance for automated code reviews.
|
|
248
|
+
|
|
249
|
+
## Troubleshooting
|
|
250
|
+
|
|
251
|
+
### Common Issues
|
|
252
|
+
|
|
253
|
+
1. **"API error 403"**: The `GITLAB_API_TOKEN` lacks `api` scope or doesn't have access to the project
|
|
254
|
+
2. **"Failed to parse OCR output"**: Check that `OCR_LLM_URL` and `OCR_LLM_AUTH_TOKEN` variables are correctly set
|
|
255
|
+
3. **"Cannot find merge-base"**: Ensure `GIT_DEPTH: 0` is set (full clone)
|
|
256
|
+
4. **Inline comments on wrong lines**: GitLab requires exact SHA matching; the script fetches MR version metadata to get correct diff refs
|
|
257
|
+
|
|
258
|
+
### Debugging
|
|
259
|
+
|
|
260
|
+
Add verbose output to the review step:
|
|
261
|
+
|
|
262
|
+
```yaml
|
|
263
|
+
script:
|
|
264
|
+
- cat /tmp/ocr-result.json
|
|
265
|
+
- cat /tmp/ocr-stderr.log
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
|
package/package.json
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alibaba-group/open-code-review",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "OpenCodeReview CLI — AI-powered code review tool",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ocr": "bin/ocr.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"postinstall": "node scripts/install.js"
|
|
10
|
-
"prepublishOnly": "cp NPM-README.md README.md",
|
|
11
|
-
"postpublish": "git checkout README.md"
|
|
9
|
+
"postinstall": "node scripts/install.js"
|
|
12
10
|
},
|
|
13
11
|
"repository": {
|
|
14
12
|
"type": "git",
|
package/NPM-README.md
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# OpenCodeReview CLI
|
|
2
|
-
|
|
3
|
-
AI-powered code review tool that reads Git diffs, sends changed files to a configurable LLM via OpenAI-compatible API, and generates structured review comments. It goes beyond surface-level analysis — the Agent can read project context for deep reviews.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g @alibaba-group/open-code-review
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
After installation, the `ocr` command is available globally.
|
|
12
|
-
|
|
13
|
-
### Version Control
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
# Install specific version
|
|
17
|
-
OCR_VERSION=v1.0.0 npm install -g @alibaba-group/open-code-review
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Prerequisites
|
|
21
|
-
|
|
22
|
-
**You must configure an LLM provider before using `ocr`.** The tool requires access to an OpenAI-compatible API endpoint (OpenAI, Claude, local models, etc.).
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
ocr config set llm.url https://api.anthropic.com/v1/messages \
|
|
26
|
-
&& ocr config set llm.auth_token {{your-api-key}} \
|
|
27
|
-
&& ocr config set llm.model claude-opus-4-6 \
|
|
28
|
-
&& ocr config set llm.use_anthropic true \
|
|
29
|
-
&& ocr config set language Chinese
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Config is stored in `~/.opencodereview/config.json`.
|
|
33
|
-
|
|
34
|
-
Or via environment variables:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
export OCR_LLM_URL=https://api.anthropic.com/v1/messages
|
|
38
|
-
export OCR_LLM_TOKEN=your-api-key
|
|
39
|
-
export OCR_LLM_MODEL=claude-opus-4-6
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Test Connectivity
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
ocr llm test
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Quick Start
|
|
49
|
-
|
|
50
|
-
Navigate to any Git repository and run:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# Review all workspace changes
|
|
54
|
-
ocr review
|
|
55
|
-
|
|
56
|
-
# Review diff between two branches
|
|
57
|
-
ocr review --from main --to feature-branch
|
|
58
|
-
|
|
59
|
-
# Review a single commit
|
|
60
|
-
ocr review --commit abc123
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Commands
|
|
64
|
-
|
|
65
|
-
| Command | Description |
|
|
66
|
-
|---------|-------------|
|
|
67
|
-
| `ocr review` / `ocr r` | Start code review |
|
|
68
|
-
| `ocr config set <key> <value>` | Manage configuration |
|
|
69
|
-
| `ocr llm test` | Test LLM connectivity |
|
|
70
|
-
| `ocr viewer` | Start WebUI session viewer |
|
|
71
|
-
| `ocr version` | Show version info |
|
|
72
|
-
|
|
73
|
-
## Common Options
|
|
74
|
-
|
|
75
|
-
| Flag | Shorthand | Default | Description |
|
|
76
|
-
|------|-----------|---------|-------------|
|
|
77
|
-
| `--repo` | | current dir | Git repository root |
|
|
78
|
-
| `--from` | | | Source ref (e.g., `main`) |
|
|
79
|
-
| `--to` | | | Target ref (e.g., `feature-branch`) |
|
|
80
|
-
| `--commit` | `-c` | | Review a single commit |
|
|
81
|
-
| `--format` | `-f` | `text` | Output format: `text` or `json` |
|
|
82
|
-
| `--concurrency` | | `4` | Max concurrent file reviews |
|
|
83
|
-
| `--timeout` | | `10` | Per-file timeout (minutes) |
|
|
84
|
-
|
|
85
|
-
## Features
|
|
86
|
-
|
|
87
|
-
- **Three review modes**: workspace changes, branch range, single commit
|
|
88
|
-
- **Context-aware**: Agent reads arbitrary files, searches code via `git grep`, inspects diffs
|
|
89
|
-
- **Plan phase**: Large changes (>50 lines) get risk analysis first
|
|
90
|
-
- **Any LLM**: Works with OpenAI, Claude-compatible endpoints, local models
|
|
91
|
-
- **Concurrent**: Files reviewed in parallel (configurable workers)
|
|
92
|
-
|
|
93
|
-
## License
|
|
94
|
-
|
|
95
|
-
Apache-2.0
|