-
Notifications
You must be signed in to change notification settings - Fork 593
docs(examples): add GitFlic CI auto-review example #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| # OpenCodeReview - GitFlic CI Demo | ||
|
|
||
| This demo shows how to integrate OpenCodeReview into a [GitFlic](https://gitflic.ru) CI/CD pipeline to automatically review Merge Requests and post the findings as MR discussions — inline on the changed lines where possible. | ||
|
|
||
| Like the GitHub Actions and GitLab CI examples, the posting glue lives in the CI layer rather than in the `ocr` binary. Here it is a small, dependency-free Python script — [`post_review.py`](post_review.py) — that reads `ocr review --format json` and posts to the GitFlic Discussions API. The only GitFlic-specific wrinkle it handles is the **old-side line**: GitFlic requires it even for a comment on the new side of the diff, and `ocr review` reports new-side positions only, so the script recomputes it from the same merge-base diff the review ran on. | ||
|
|
||
| ## How It Works | ||
|
|
||
| ``` | ||
| MR Created/Updated → Merge Request Pipeline → ocr review → post_review.py → Discussions on MR | ||
| ``` | ||
|
|
||
| 1. A Merge Request Pipeline triggers the `code-review` job | ||
| 2. It installs OCR via npm in a `node:20` image (which also ships `python3` and `git`) | ||
| 3. Runs `ocr review --from origin/<target> --to $CI_COMMIT_SHA --format json --audience agent` | ||
| 4. Runs `python3 post_review.py`, which reads the JSON and posts: | ||
| - **Inline discussions** on the changed lines (`POST .../discussions/create` with `newLine`/`oldLine`/`newPath`/`oldPath`) | ||
| - **A fallback note** collecting comments that could not be placed inline | ||
| - **A summary note** with the totals | ||
|
|
||
| The MR context (owner, project, MR id, branch refs) is picked up automatically from the predefined GitFlic CI variables (`CI_PROJECT_NAMESPACE`, `CI_PROJECT_NAME`, `CI_MERGE_REQUEST_LOCAL_ID`, `CI_MERGE_REQUEST_TARGET_BRANCH_NAME`, `CI_COMMIT_SHA`), so `post_review.py` needs no arguments in CI. Outside CI every value can be passed via flags — run `python3 post_review.py -h`. | ||
|
|
||
| ## Setup | ||
|
|
||
| ### 1. Enable Merge Request Pipelines | ||
|
|
||
| Go to **Project Settings → CI/CD Settings** and enable **Merge Request Pipeline**. New merge requests will then trigger the pipeline automatically. | ||
|
|
||
| ### 2. Copy the pipeline files | ||
|
|
||
| Copy **both** `gitflic-ci.yaml` (GitFlic expects this exact file name at the repository root) and `post_review.py` into your repository. If you keep `post_review.py` somewhere other than the repo root, adjust the `python3 post_review.py` path in `gitflic-ci.yaml` accordingly. | ||
|
|
||
| ### 3. Configure CI/CD Variables | ||
|
|
||
| Go to **Settings → CI/CD → Variables** and add: | ||
|
|
||
| | Variable | Required | Description | | ||
| |----------|----------|-------------| | ||
| | `OCR_LLM_URL` | Yes | LLM API endpoint URL | | ||
| | `OCR_LLM_AUTH_TOKEN` | Yes | LLM API authentication token | | ||
| | `GITFLIC_TOKEN` | Yes | GitFlic access token used to post discussions | | ||
| | `OCR_LLM_MODEL` | No | Model name (e.g., `gpt-4o`) | | ||
| | `GITFLIC_API_URL` | No | REST API base URL for self-hosted GitFlic (default: `https://api.gitflic.ru`) | | ||
|
|
||
| > **Note:** GitFlic CI/CD does not accept variables with values shorter than 8 characters, so `use_anthropic` cannot be set as a CI variable. The pipeline sets it to `false`; to use Anthropic Claude models, edit `gitflic-ci.yaml` directly. | ||
|
|
||
| ### 4. Create a GitFlic Access Token | ||
|
|
||
| Create a token in **User Settings → Access Tokens** (or a dedicated service account — its name becomes the bot name shown in discussions) and store it in the `GITFLIC_TOKEN` variable. The token owner must have access to the project sufficient for commenting on merge requests. | ||
|
|
||
| ## Notes & Limitations | ||
|
|
||
| - **Inline positioning** — GitFlic requires all four of `newLine`/`oldLine`/`newPath`/`oldPath` for a code comment; if any is missing it silently creates a general comment. `post_review.py` computes the old-side position from the same merge-base diff the review ran on (`git diff merge-base(from, to)..to`), and anchors added lines to the closest preceding old line. | ||
| - **Rate limit** — the GitFlic cloud API allows 500 requests/hour per token. One review posts `comments + 2` requests at most, which fits comfortably. | ||
| - **Self-hosted GitFlic** — set `GITFLIC_API_URL` to your instance's REST API base URL. | ||
| - **Re-reviews** — every push to the MR triggers a new pipeline and a new review. To skip already-reviewed MRs, check existing discussions for the `OpenCodeReview` marker before running the review step. | ||
|
|
||
| ## Tests | ||
|
|
||
| `post_review.py` ships with [`post_review_test.py`](post_review_test.py) — standard-library `unittest`, no network or git required: | ||
|
|
||
| ```bash | ||
| cd examples/gitflic_ci | ||
| python3 post_review_test.py | ||
| ``` | ||
|
|
||
| The line-mapping cases are ported from the upstream Go tests so the script keeps proven parity with the binary. | ||
|
|
||
| ## Debugging | ||
|
|
||
| Test the posting step locally without touching the MR: | ||
|
|
||
| ```bash | ||
| ocr review --from origin/main --to HEAD --format json > /tmp/r.json | ||
| python3 post_review.py /tmp/r.json \ | ||
| --owner <owner> --project <project> --mr <id> \ | ||
| --from origin/main --to HEAD --dry-run | ||
| ``` | ||
|
|
||
| `--dry-run` prints every discussion (with the computed positions) instead of posting, and does not require `GITFLIC_TOKEN`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # OpenCodeReview - GitFlic CI Merge Request Auto-Review Demo | ||
| # | ||
| # Reviews Merge Requests with OpenCodeReview and posts the findings onto the | ||
| # MR as discussions (inline where possible). The posting glue lives in the CI | ||
| # layer, in post_review.py next to this file -- consistent with the GitHub and | ||
| # GitLab examples, which keep platform-specific publishing out of the `ocr` | ||
| # binary. | ||
| # | ||
| # Setup: | ||
| # - Commit BOTH this file and post_review.py into your repository (adjust the | ||
| # `python3 post_review.py` path below if you place the script elsewhere). | ||
| # - Enable "Merge Request Pipeline" in Project Settings -> CI/CD Settings. | ||
| # - Use a runner able to run the node:20 image (it ships node, python3 and git), | ||
| # or any shell runner with node 20+, python3 and git available. | ||
| # | ||
| # Required CI/CD Variables (Settings -> CI/CD -> Variables): | ||
| # OCR_LLM_URL - LLM API endpoint (e.g., https://api.openai.com/v1/chat/completions) | ||
| # OCR_LLM_AUTH_TOKEN - Authentication token for the LLM API | ||
| # GITFLIC_TOKEN - GitFlic access token used to post MR discussions | ||
| # | ||
| # Optional CI/CD Variables: | ||
| # OCR_LLM_MODEL - Model name (e.g., gpt-4o) | ||
| # GITFLIC_API_URL - GitFlic REST API base URL; only needed for self-hosted | ||
| # instances (defaults to https://api.gitflic.ru) | ||
| # | ||
| # post_review.py picks up the MR context automatically from the predefined | ||
| # GitFlic CI variables: CI_PROJECT_NAMESPACE, CI_PROJECT_NAME, | ||
| # CI_MERGE_REQUEST_LOCAL_ID, CI_MERGE_REQUEST_TARGET_BRANCH_NAME, CI_COMMIT_SHA. | ||
|
|
||
| stages: | ||
| - review | ||
|
|
||
| code-review: | ||
| stage: review | ||
| image: node:20 | ||
| script: | ||
| # Run only in merge request pipelines | ||
| - | | ||
| if [ -z "$CI_MERGE_REQUEST_LOCAL_ID" ]; then | ||
| echo "Not a merge request pipeline, skipping review." | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Install OpenCodeReview | ||
| - npm install -g @alibaba-group/open-code-review | ||
|
|
||
| # Configure OCR | ||
| - | | ||
| ocr config set llm.url $OCR_LLM_URL | ||
| ocr config set llm.auth_token $OCR_LLM_AUTH_TOKEN | ||
| if [ -n "$OCR_LLM_MODEL" ]; then | ||
| ocr config set llm.model "$OCR_LLM_MODEL" | ||
| fi | ||
| ocr config set llm.use_anthropic false | ||
| ocr config set llm.extra_body '{"thinking": {"type": "disabled"}}' | ||
|
|
||
| # Make sure the target branch and full history are available for merge-base diff | ||
| - git fetch --unshallow 2>/dev/null || true | ||
| - git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" | ||
|
|
||
| # Run OCR review (CI_COMMIT_SHA as head supports forked MRs as well) | ||
| - | | ||
| ocr review \ | ||
| --from "origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}" \ | ||
| --to "${CI_COMMIT_SHA}" \ | ||
| --format json \ | ||
| --audience agent \ | ||
| > /tmp/ocr-result.json || true | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: 建议在之后加一个空文件检查: - |
if [ ! -s /tmp/ocr-result.json ]; then
echo "OCR review produced no output, skipping post."
exit 0
fi或者如果这是有意为之(让
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 1dc279b — added |
||
| echo "OCR review completed." | ||
|
|
||
| # Post review comments onto the MR (inline discussions + summary note). | ||
| # post_review.py recomputes the old-side line for each comment from the | ||
| # merge-base diff, which the GitFlic Discussions API requires for inline | ||
| # (code) comments. | ||
| # | ||
| # The review step above ends with `|| true`, so a failed `ocr review` (bad | ||
| # token, network error) leaves an empty or partial file. Skip posting in | ||
| # that case instead of feeding invalid JSON to post_review.py. | ||
| - | | ||
| if [ ! -s /tmp/ocr-result.json ]; then | ||
| echo "OCR review produced no output, skipping post." | ||
| exit 0 | ||
| fi | ||
| python3 post_review.py /tmp/ocr-result.json | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: 这个文件缺少末尾换行符(
No newline at end of file)。既然本次已修改了此文件,可以顺便修复。There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 1dc279b — added the trailing newline.