coderev-cli 1.0.20 → 1.0.22

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/README.md CHANGED
@@ -736,6 +736,37 @@ coderev review --pr 42 --inline
736
736
  - 执行内容:对比 PR 的 diff → coderev 审查 → 结果回贴到 PR 评论
737
737
  - 效果:每个 PR 自动获得一份 AI 审查报告
738
738
 
739
+ 或使用 GitHub Actions Marketplace 中的 Action:
740
+
741
+ ```yaml
742
+ steps:
743
+ - uses: jishuanjimingtian/coderev@v1
744
+ with:
745
+ github-token: ${{ secrets.GITHUB_TOKEN }}
746
+ api-key: ${{ secrets.DEEPSEEK_API_KEY }}
747
+ ```
748
+
749
+ ### GitLab CI
750
+
751
+ 使用 `coderev init --gitlab-ci` 一键生成配置,或直接将 `templates/.gitlab-ci.yml` 复制到项目根目录。
752
+
753
+ **变量配置**(GitLab → Settings → CI/CD → Variables):
754
+
755
+ | 变量 | 必填 | 说明 |
756
+ |------|------|------|
757
+ | `DEEPSEEK_API_KEY` | ✅ | AI 提供商的 API Key |
758
+ | `GITLAB_TOKEN` | 可选 | GitLab PAT(api scope),用于自动发布 MR 评论 |
759
+ | `CODEREV_CONFIDENCE` | 可选 | 置信度阈值,默认 60 |
760
+ | `CODEREV_MODE` | 可选 | 审查模式:full / security / bugs / quality |
761
+ | `CODEREV_BLAME` | 可选 | 启用 git blame:true / false |
762
+ | `CODEREV_BLOCK` | 可选 | 发现问题时阻塞 MR:true / false |
763
+
764
+ **工作流过程**:
765
+ 1. MR 创建/更新时自动触发
766
+ 2. 生成 MR diff → coderev 3 Agent 并行审查
767
+ 3. 审查结果作为 MR 评论自动发布(需 GITLAB_TOKEN)
768
+ 4. 如开启 `CODEREV_BLOCK`,发现问题时 pipeline 失败
769
+
739
770
  ### 自定义 CI 集成
740
771
 
741
772
  在任意 CI 管道中:
@@ -805,6 +836,10 @@ A:可以,审查时加 `--no-cache` 参数即可跳过缓存。
805
836
  A:在 `.coderevrc.json` 的 `rules.custom` 数组中添加。详见上方「自定义规则」章节。
806
837
 
807
838
  ---
839
+ ## Contributing
840
+
841
+ 欢迎贡献!详见 [CONTRIBUTING.md](CONTRIBUTING.md)
842
+
808
843
  ## License
809
844
 
810
845
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coderev-cli",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "Multi-agent AI code review for git -- parallel agents with confidence scoring",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -35,6 +35,7 @@
35
35
  },
36
36
  "files": [
37
37
  "src/",
38
+ "templates/",
38
39
  "README.md",
39
40
  ".env.example"
40
41
  ],
package/src/cli.js CHANGED
@@ -639,7 +639,9 @@ fi
639
639
  program
640
640
  .command('init')
641
641
  .description('Create a default coderev config file')
642
- .action(() => {
642
+ .option('--gitlab-ci', 'Generate a .gitlab-ci.yml template for GitLab CI/CD review')
643
+ .option('--github-action', 'Generate a GitHub Actions workflow for PR review')
644
+ .action((options) => {
643
645
  const fs = require('fs');
644
646
  const path = require('path');
645
647
  const defaultConfig = {
@@ -708,6 +710,121 @@ build/
708
710
  fs.writeFileSync(hintPath, hintContent);
709
711
  console.log(chalk.green(`✔ Default .coderevhint created at ${hintPath}`));
710
712
  }
713
+
714
+ // --gitlab-ci: generate GitLab CI template
715
+ if (options.gitlabCi) {
716
+ const ciPath = path.join(process.cwd(), '.gitlab-ci.yml');
717
+ if (fs.existsSync(ciPath)) {
718
+ console.log(chalk.yellow(`⚠ .gitlab-ci.yml already exists. Skipping.`));
719
+ } else {
720
+ const templatePath = path.join(__dirname, '..', 'templates', '.gitlab-ci.yml');
721
+ if (fs.existsSync(templatePath)) {
722
+ fs.copyFileSync(templatePath, ciPath);
723
+ console.log(chalk.green(`✔ GitLab CI template created at ${ciPath}`));
724
+ } else {
725
+ // Fallback: inline the template content
726
+ const ciContent = `# coderev — Multi-Agent AI Code Review for GitLab CI
727
+ # Quick start:
728
+ # 1. Set CI variable DEEPSEEK_API_KEY in GitLab → Settings → CI/CD → Variables
729
+ # 2. (Optional) Set GITLAB_TOKEN for auto-posting MR comments
730
+
731
+ stages:
732
+ - review
733
+
734
+ coderev-review:
735
+ stage: review
736
+ image: node:20-alpine
737
+ needs: []
738
+ rules:
739
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
740
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
741
+ when: never
742
+ before_script:
743
+ - npm install -g coderev-cli
744
+ - command -v git >/dev/null 2>&1 || apk add --no-cache git
745
+ script:
746
+ - |
747
+ if [ -n "$CI_MERGE_REQUEST_DIFF_BASE_SHA" ]; then
748
+ git diff $CI_MERGE_REQUEST_DIFF_BASE_SHA...$CI_COMMIT_SHA > /tmp/coderev-mr.diff
749
+ else
750
+ git diff HEAD~1 > /tmp/coderev-mr.diff
751
+ fi
752
+ - cat /tmp/coderev-mr.diff | coderev review --output markdown --ci --min-confidence 60 > /tmp/coderev-output.md
753
+ - cat /tmp/coderev-output.md
754
+ artifacts:
755
+ when: always
756
+ paths:
757
+ - /tmp/coderev-output.md
758
+ expire_in: 7 days
759
+ `;
760
+ fs.writeFileSync(ciPath, ciContent);
761
+ console.log(chalk.green(`✔ GitLab CI template created at ${ciPath}`));
762
+ }
763
+ }
764
+ console.log(chalk.blue(' Next steps:'));
765
+ console.log(chalk.blue(' 1. Go to GitLab → Settings → CI/CD → Variables'));
766
+ console.log(chalk.blue(' 2. Add variable DEEPSEEK_API_KEY with your API key'));
767
+ console.log(chalk.blue(' 3. (Optional) Add GITLAB_TOKEN with api scope for MR comments'));
768
+ console.log(chalk.blue(' 4. Push to GitLab — coderev runs on every MR!'));
769
+ }
770
+
771
+ // --github-action: generate GitHub Actions workflow
772
+ if (options.githubAction) {
773
+ const gaDir = path.join(process.cwd(), '.github', 'workflows');
774
+ const gaPath = path.join(gaDir, 'coderev.yml');
775
+ if (fs.existsSync(gaPath)) {
776
+ console.log(chalk.yellow(`⚠ ${gaPath} already exists. Skipping.`));
777
+ } else {
778
+ const templatePath = path.join(__dirname, '..', 'templates', 'github-action.yml');
779
+ if (fs.existsSync(templatePath)) {
780
+ fs.mkdirSync(gaDir, { recursive: true });
781
+ fs.copyFileSync(templatePath, gaPath);
782
+ console.log(chalk.green(`✔ GitHub Actions workflow created at ${gaPath}`));
783
+ } else {
784
+ // Fallback: write minimal workflow
785
+ const gaContent = `name: coderev AI Code Review
786
+
787
+ on:
788
+ pull_request:
789
+ types: [opened, synchronize, reopened]
790
+
791
+ permissions:
792
+ contents: read
793
+ pull-requests: write
794
+
795
+ jobs:
796
+ coderev:
797
+ runs-on: ubuntu-latest
798
+ timeout-minutes: 10
799
+ steps:
800
+ - uses: actions/checkout@v4
801
+ with:
802
+ fetch-depth: 0
803
+ - uses: actions/setup-node@v4
804
+ with:
805
+ node-version: 20
806
+ - run: npm install -g coderev-cli
807
+ - run: |
808
+ git diff \${{ github.event.pull_request.base.sha }}...\${{ github.event.pull_request.head.sha }} > /tmp/coderev-pr.diff
809
+ - env:
810
+ DEEPSEEK_API_KEY: \${{ secrets.DEEPSEEK_API_KEY }}
811
+ run: |
812
+ cat /tmp/coderev-pr.diff | coderev review --output markdown --ci --min-confidence 60 > /tmp/coderev-report.md
813
+ - uses: marocchino/sticky-pull-request-comment@v2
814
+ with:
815
+ header: coderev-review
816
+ path: /tmp/coderev-report.md
817
+ `;
818
+ fs.mkdirSync(gaDir, { recursive: true });
819
+ fs.writeFileSync(gaPath, gaContent);
820
+ console.log(chalk.green(`✔ GitHub Actions workflow created at ${gaPath}`));
821
+ }
822
+ }
823
+ console.log(chalk.blue(' Next steps:'));
824
+ console.log(chalk.blue(' 1. Go to GitHub → Settings → Secrets and variables → Actions'));
825
+ console.log(chalk.blue(' 2. Add secret DEEPSEEK_API_KEY with your API key'));
826
+ console.log(chalk.blue(' 3. Push to GitHub — coderev reviews every PR!'));
827
+ }
711
828
  });
712
829
 
713
830
  // ── Serve (GitHub App) ────────────────────────────────────────────
@@ -0,0 +1,134 @@
1
+ # =============================================================================
2
+ # coderev — Multi-Agent AI Code Review for GitLab CI
3
+ # =============================================================================
4
+ #
5
+ # This template runs coderev on every merge request, using 3 parallel AI agents
6
+ # (Security / Bug / Quality) with confidence scoring.
7
+ #
8
+ # QUICK START:
9
+ # 1. Copy this file to your repo as .gitlab-ci.yml
10
+ # 2. Set CI variable DEEPSEEK_API_KEY in GitLab → Settings → CI/CD → Variables
11
+ # 3. (Optional) Set GITLAB_TOKEN for private repos or to post review comments
12
+ #
13
+ # VARIABLES (set in GitLab CI/CD Settings):
14
+ # DEEPSEEK_API_KEY (required) AI provider API key
15
+ # GITLAB_TOKEN (optional) GitLab PAT for posting MR comments (api scope)
16
+ # CODEREV_PROVIDER (optional) AI provider: deepseek | openai (default: deepseek)
17
+ # CODEREV_MODEL (optional) Model name (default: deepseek-chat)
18
+ # CODEREV_CONFIDENCE (optional) Min confidence 0-100 (default: 60)
19
+ # CODEREV_MODE (optional) Review mode: full | security | bugs | quality
20
+ # CODEREV_BLAME (optional) Enable git blame: "true" | "false" (default: false)
21
+ # CODEREV_BLOCK (optional) Block MR on issues: "true" | "false" (default: false)
22
+ # =============================================================================
23
+
24
+ stages:
25
+ - review
26
+
27
+ coderev-review:
28
+ stage: review
29
+ image: node:20-alpine
30
+ needs: []
31
+ rules:
32
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
33
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
34
+ when: never
35
+ before_script:
36
+ # Install coderev and dependencies
37
+ - npm install -g coderev-cli
38
+ # Ensure git is configured for diff generation
39
+ - command -v git >/dev/null 2>&1 || apk add --no-cache git
40
+ script:
41
+ # ── Generate MR diff ──
42
+ - |
43
+ echo "📋 Generating diff for merge request..."
44
+ if [ -n "$CI_MERGE_REQUEST_DIFF_BASE_SHA" ]; then
45
+ git diff $CI_MERGE_REQUEST_DIFF_BASE_SHA...$CI_COMMIT_SHA > /tmp/coderev-mr.diff
46
+ elif [ -n "$CI_MERGE_REQUEST_TARGET_BRANCH_SHA" ]; then
47
+ git diff $CI_MERGE_REQUEST_TARGET_BRANCH_SHA...$CI_COMMIT_SHA > /tmp/coderev-mr.diff
48
+ else
49
+ echo "⚠️ Could not determine MR base. Reviewing working tree..."
50
+ git diff HEAD~1 > /tmp/coderev-mr.diff
51
+ fi
52
+ echo "Debug: Diff saved ($(wc -c < /tmp/coderev-mr.diff) bytes)"
53
+
54
+ # ── Build CLI args ──
55
+ - |
56
+ CODEREV_ARGS=""
57
+
58
+ # Output format
59
+ CODEREV_ARGS="$CODEREV_ARGS --output markdown"
60
+
61
+ # Provider
62
+ PROVIDER="${CODEREV_PROVIDER:-deepseek}"
63
+
64
+ # Mode filter
65
+ case "${CODEREV_MODE:-full}" in
66
+ security) CODEREV_ARGS="$CODEREV_ARGS --audit" ;;
67
+ bugs) CODEREV_ARGS="$CODEREV_ARGS --agents bugs" ;;
68
+ quality) CODEREV_ARGS="$CODEREV_ARGS --agents quality" ;;
69
+ esac
70
+
71
+ # Confidence threshold
72
+ CONFIDENCE="${CODEREV_CONFIDENCE:-60}"
73
+ CODEREV_ARGS="$CODEREV_ARGS --min-confidence $CONFIDENCE"
74
+
75
+ # Git blame
76
+ if [ "${CODEREV_BLAME:-false}" = "true" ]; then
77
+ CODEREV_ARGS="$CODEREV_ARGS --blame"
78
+ fi
79
+
80
+ # CI mode (block MR on issues)
81
+ if [ "${CODEREV_BLOCK:-false}" = "true" ]; then
82
+ CODEREV_ARGS="$CODEREV_ARGS --ci"
83
+ fi
84
+
85
+ # ── Run coderev ──
86
+ - |
87
+ echo "🔍 Running coderev multi-agent review..."
88
+ export DEEPSEEK_API_KEY="${DEEPSEEK_API_KEY}"
89
+ export OPENAI_API_KEY="${OPENAI_API_KEY:-$DEEPSEEK_API_KEY}"
90
+ cat /tmp/coderev-mr.diff | coderev review $CODEREV_ARGS > /tmp/coderev-output.md 2>/tmp/coderev-stderr.txt
91
+ REVIEW_EXIT_CODE=$?
92
+ echo "Debug: review exit code = $REVIEW_EXIT_CODE"
93
+
94
+ # ── Post review as MR comment (if GITLAB_TOKEN is set) ──
95
+ - |
96
+ if [ -n "$GITLAB_TOKEN" ] && [ -n "$CI_MERGE_REQUEST_IID" ]; then
97
+ echo "💬 Posting review comment to MR !$CI_MERGE_REQUEST_IID ..."
98
+
99
+ # Read and escape the review output for JSON
100
+ REVIEW_BODY=$(cat /tmp/coderev-output.md | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))" 2>/dev/null || \
101
+ node -e "const fs=require('fs');console.log(JSON.stringify(fs.readFileSync('/tmp/coderev-output.md','utf8')))")
102
+
103
+ # Post via GitLab API
104
+ curl -s -X POST \
105
+ "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes" \
106
+ --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
107
+ --header "Content-Type: application/json" \
108
+ --data "{\"body\": $REVIEW_BODY}" \
109
+ > /tmp/coderev-post-response.json 2>/tmp/coderev-curl-stderr.txt
110
+
111
+ if [ $? -eq 0 ]; then
112
+ echo "✅ Review comment posted to MR !$CI_MERGE_REQUEST_IID"
113
+ else
114
+ echo "⚠️ Failed to post comment (check GITLAB_TOKEN scope: api)"
115
+ fi
116
+ else
117
+ echo "ℹ️ GITLAB_TOKEN not set — skipping MR comment. Review output:"
118
+ cat /tmp/coderev-output.md
119
+ fi
120
+
121
+ # ── Exit with review status (CI mode) ──
122
+ - |
123
+ if [ "${CODEREV_BLOCK:-false}" = "true" ] && [ $REVIEW_EXIT_CODE -ne 0 ]; then
124
+ echo "🚫 Issues found! Blocking MR. Fix issues or lower CODEREV_CONFIDENCE."
125
+ exit 1
126
+ fi
127
+ echo "✅ coderev review complete."
128
+
129
+ artifacts:
130
+ when: always
131
+ paths:
132
+ - /tmp/coderev-output.md
133
+ - /tmp/coderev-stderr.txt
134
+ expire_in: 7 days
@@ -0,0 +1,143 @@
1
+ # coderev — Multi-Agent AI Code Review for GitHub Actions
2
+ # Quick start:
3
+ # 1. Copy this file to .github/workflows/coderev.yml
4
+ # Or run: npx coderev-cli init --github-action
5
+ # 2. Set Secrets: DEEPSEEK_API_KEY in Settings → Secrets and variables → Actions
6
+ # 3. (Optional) Set GITHUB_TOKEN is auto-provided, no setup needed
7
+ #
8
+ # Usage:
9
+ # - Review on every PR: default trigger
10
+ # - Block merging on issues: enable CODEREV_BLOCK or comment with coderev status
11
+ #
12
+ # Variables (set in workflow or as env):
13
+ # CODEREV_PROVIDER AI provider (default: deepseek)
14
+ # CODEREV_MODEL Model name (default: deepseek-chat)
15
+ # CODEREV_CONFIDENCE Minimum confidence 0-100 (default: 60)
16
+ # CODEREV_BLOCK Block PR on issues (default: false)
17
+ # CODEREV_BLAME Enable git blame context (default: false)
18
+ # CODEREV_MODE Review mode: comment | check (default: comment)
19
+
20
+ name: coderev AI Code Review
21
+
22
+ on:
23
+ pull_request:
24
+ types: [opened, synchronize, reopened]
25
+ workflow_dispatch:
26
+ inputs:
27
+ ref:
28
+ description: 'Git ref to review (branch/commit)'
29
+ required: false
30
+
31
+ permissions:
32
+ contents: read
33
+ pull-requests: write
34
+ checks: write
35
+
36
+ jobs:
37
+ coderev:
38
+ name: AI Code Review
39
+ runs-on: ubuntu-latest
40
+ timeout-minutes: 10
41
+
42
+ steps:
43
+ - name: Checkout
44
+ uses: actions/checkout@v4
45
+ with:
46
+ fetch-depth: 0
47
+
48
+ - name: Setup Node.js
49
+ uses: actions/setup-node@v4
50
+ with:
51
+ node-version: 20
52
+
53
+ - name: Install coderev
54
+ run: npm install -g coderev-cli
55
+
56
+ - name: Generate diff
57
+ id: diff
58
+ run: |
59
+ if [ -n "${{ github.event.pull_request.base.sha }}" ]; then
60
+ git diff ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} > /tmp/coderev-pr.diff
61
+ else
62
+ git diff HEAD~1 > /tmp/coderev-pr.diff
63
+ fi
64
+ echo "Diff size: $(wc -c < /tmp/coderev-pr.diff) bytes"
65
+
66
+ - name: Run coderev review
67
+ id: review
68
+ env:
69
+ DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
70
+ CODEREV_PROVIDER: ${{ env.CODEREV_PROVIDER || 'deepseek' }}
71
+ CODEREV_MODEL: ${{ env.CODEREV_MODEL || 'deepseek-chat' }}
72
+ run: |
73
+ BLAME_FLAG=""
74
+ if [ "${{ env.CODEREV_BLAME || 'false' }}" = "true" ]; then
75
+ BLAME_FLAG="--blame"
76
+ fi
77
+
78
+ cat /tmp/coderev-pr.diff | coderev review \
79
+ --output markdown \
80
+ --ci $BLAME_FLAG \
81
+ --min-confidence ${{ env.CODEREV_CONFIDENCE || '60' }} \
82
+ > /tmp/coderev-report.md 2>/tmp/coderev-stderr.log
83
+
84
+ echo "Exit code: $?"
85
+
86
+ - name: Post review as PR comment
87
+ if: github.event_name == 'pull_request' && env.CODEREV_MODE != 'check'
88
+ uses: marocchino/sticky-pull-request-comment@v2
89
+ with:
90
+ header: coderev-review
91
+ path: /tmp/coderev-report.md
92
+
93
+ - name: Post review as GitHub Check
94
+ if: env.CODEREV_MODE == 'check'
95
+ uses: actions/github-script@v7
96
+ with:
97
+ script: |
98
+ const fs = require('fs');
99
+ const report = fs.readFileSync('/tmp/coderev-report.md', 'utf8');
100
+
101
+ // Parse score from report
102
+ const scoreMatch = report.match(/\*\*Score:\*\*\s*(\d+)\/100/);
103
+ const score = scoreMatch ? parseInt(scoreMatch[1]) : 0;
104
+ const conclusion = score >= 80 ? 'success' : score >= 50 ? 'neutral' : 'failure';
105
+
106
+ // Count issues
107
+ const issueMatches = report.match(/\*\*ERROR\*\*/g);
108
+ const warnMatches = report.match(/\*\*WARNING\*\*/g);
109
+
110
+ await github.rest.checks.create({
111
+ owner: context.repo.owner,
112
+ repo: context.repo.repo,
113
+ name: 'coderev AI Review',
114
+ head_sha: context.payload.pull_request?.head?.sha || context.sha,
115
+ status: 'completed',
116
+ conclusion: conclusion,
117
+ output: {
118
+ title: `Code Review: ${score}/100`,
119
+ summary: report.substring(0, 65535),
120
+ annotations: []
121
+ }
122
+ });
123
+
124
+ - name: Block on issues (optional)
125
+ if: env.CODEREV_BLOCK == 'true'
126
+ run: |
127
+ SCORE=$(grep -oP '\*\*Score:\*\*\s*\K\d+' /tmp/coderev-report.md || echo 0)
128
+ if [ "$SCORE" -lt 60 ]; then
129
+ echo "⛔ Score $SCORE/100 below threshold (60). Blocking PR."
130
+ cat /tmp/coderev-report.md
131
+ exit 1
132
+ fi
133
+ echo "✅ Score $SCORE/100 — passed."
134
+
135
+ - name: Upload review artifacts
136
+ if: always()
137
+ uses: actions/upload-artifact@v4
138
+ with:
139
+ name: coderev-report
140
+ path: |
141
+ /tmp/coderev-report.md
142
+ /tmp/coderev-stderr.log
143
+ retention-days: 7