mirror of
https://github.com/hustcer/deepseek-review.git
synced 2026-05-13 05:16:05 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29aec71797 | ||
|
|
957db0afb6 | ||
|
|
c53edfe925 | ||
|
|
0298773233 | ||
|
|
9d6bb02502 | ||
|
|
26e38f1543 | ||
|
|
8b7262a6b4 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.env
|
||||
.env.dev
|
||||
.env.local
|
||||
review.md
|
||||
config.yml
|
||||
prompts.yaml
|
||||
|
||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,6 +1,19 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.17.0] - 2025-04-11
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Read default `include` and `exclude` patterns from config for local code review (#170)
|
||||
|
||||
### Features
|
||||
|
||||
All the following changes are for local code review only:
|
||||
|
||||
- Add code review for `git show head:path/to/file` patch command support (#171)
|
||||
- Add write code review result to file by `--output` flag support (#172)
|
||||
|
||||
## [1.16.0] - 2025-04-05
|
||||
|
||||
### Documentation
|
||||
@@ -13,9 +26,9 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Add alias guide for `fish`
|
||||
- Add alias setup guide for `fish`
|
||||
- Add openrouter.ai config example
|
||||
- Set minimum required nushell version to v0.103
|
||||
- Set minimum required `nushell` version to v0.103
|
||||
|
||||
### Refactor
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
- Review Remote GitHub PRs Directly from Your Local CLI
|
||||
- Review Commit Changes with DeepSeek for Any Local Repository by CLI
|
||||
- Support On-demand Changes Generation via `git show`/`git diff` Command for Further Code Review
|
||||
- Output Code Review Result to Specified File in Markdown Format
|
||||
- Cross-platform Compatibility: Designed to function seamlessly across all platforms capable of running [Nushell](https://github.com/nushell/nushell)
|
||||
|
||||
### Both GH Action & Local
|
||||
@@ -191,6 +192,7 @@ Flags:
|
||||
-x, --exclude <string>: Comma separated file patterns to exclude in the code review
|
||||
-T, --temperature <float>: Temperature for the model, between `0` and `2`, default value `1.0`
|
||||
-C, --config <string>: Config file path, default to `config.yml`
|
||||
-o, --output <string>: Output file path
|
||||
-h, --help: Display the help message for this command
|
||||
|
||||
Parameters:
|
||||
@@ -242,6 +244,8 @@ To review a local repository:
|
||||
cr
|
||||
# Perform code review on the `git diff f536acc` changes in current directory
|
||||
cr --diff-from f536acc
|
||||
# Perform code review on the `git diff f536acc` changes and output result to review.md
|
||||
cr --diff-from f536acc --output review.md
|
||||
# Perform code review on the `git diff f536acc 0dd0eb5` changes in current directory
|
||||
cr --diff-from f536acc --diff-to 0dd0eb5
|
||||
# Review the changes in current directory using the `--patch-cmd` flag
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
- 通过本地 CLI 直接审查远程 GitHub PR
|
||||
- 通过本地 CLI 使用 DeepSeek 审查任何本地仓库的提交变更
|
||||
- 允许通过自定义 `git show`/`git diff` 命令生成变更记录并进行审查
|
||||
- 允许将代码审查结果以 Markdown 格式输出到指定文件
|
||||
- 跨平台:理论上只要能运行 [Nushell](https://github.com/nushell/nushell) 即可使用本工具
|
||||
|
||||
### 本地或 GH Action
|
||||
@@ -188,6 +189,7 @@ Flags:
|
||||
-x, --exclude <string>: Comma separated file patterns to exclude in the code review
|
||||
-T, --temperature <float>: Temperature for the model, between `0` and `2`, default value `1.0`
|
||||
-C, --config <string>: Config file path, default to `config.yml`
|
||||
-o, --output <string>: Output file path
|
||||
-h, --help: Display the help message for this command
|
||||
|
||||
Parameters:
|
||||
@@ -238,6 +240,8 @@ function cr {
|
||||
cr
|
||||
# 对本地当前目录所在仓库 `git diff f536acc` 修改内容进行代码审查
|
||||
cr --diff-from f536acc
|
||||
# 对本地当前目录所在仓库 `git diff f536acc` 修改内容进行代码审查并将审查结果输出到 review.md
|
||||
cr --diff-from f536acc --output review.md
|
||||
# 对本地当前目录所在仓库 `git diff f536acc 0dd0eb5` 修改内容进行代码审查
|
||||
cr --diff-from f536acc --diff-to 0dd0eb5
|
||||
# 通过 --patch-cmd 参数对本地当前目录所在仓库变更内容进行审查
|
||||
|
||||
8
cr
8
cr
@@ -4,8 +4,8 @@
|
||||
# Description: A wrapper for nu/review.nu as the main entry point of the project.
|
||||
|
||||
use nu/config.nu *
|
||||
use nu/common.nu [hr-line, check-nushell, ECODE]
|
||||
use nu/review.nu [deepseek-review]
|
||||
use nu/common.nu [hr-line, check-nushell, ECODE]
|
||||
|
||||
# Use DeepSeek AI to review code changes locally or in GitHub Actions
|
||||
def main [
|
||||
@@ -27,6 +27,7 @@ def main [
|
||||
--exclude(-x): string, # Comma separated file patterns to exclude in the code review
|
||||
--temperature(-T): float, # Temperature for the model, between `0` and `2`, default value `1.0`
|
||||
--config(-C): string # Config file path, default to `config.yml`
|
||||
--output(-o): string, # Output file path
|
||||
] {
|
||||
|
||||
check-nushell
|
||||
@@ -36,8 +37,7 @@ def main [
|
||||
deepseek-review $token
|
||||
--repo=$repo
|
||||
--debug=$debug
|
||||
--include=$include
|
||||
--exclude=$exclude
|
||||
--output=$output
|
||||
--model=$env.CHAT_MODEL
|
||||
--base-url=$base_url
|
||||
--chat-url=$chat_url
|
||||
@@ -50,5 +50,7 @@ def main [
|
||||
--sys-prompt=$sys_prompt
|
||||
--user-prompt=$user_prompt
|
||||
--temperature=$temperature
|
||||
--include=($include | default $env.INCLUDE_PATTERNS?)
|
||||
--exclude=($exclude | default $env.EXCLUDE_PATTERNS?)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deepseek-review",
|
||||
"version": "1.16.0",
|
||||
"actionVer": "v1.16",
|
||||
"version": "1.17.0",
|
||||
"actionVer": "v1.17",
|
||||
"author": "hustcer",
|
||||
"license": "MIT",
|
||||
"github": "https://github.com/hustcer/deepseek-review",
|
||||
|
||||
@@ -171,6 +171,6 @@ export def has-ref [
|
||||
|
||||
# Notify the user that the `CHAT_TOKEN` hasn't been configured
|
||||
export const NO_TOKEN_TIP = (
|
||||
"**Notice:** It looks like you're using [`hustcer/deepseek-review`](https://github.com/hustcer/deepseek-review), but the `CHAT_TOKEN` hasn't" +
|
||||
"been configured in your repo's Variables/Secrets. Please ensure this token is set for proper functionality. For step-by-step guidance, refer" +
|
||||
"**Notice:** It looks like you're using [`hustcer/deepseek-review`](https://github.com/hustcer/deepseek-review), but the `CHAT_TOKEN` hasn't " +
|
||||
"been configured in your repo's **Variables/Secrets**. Please ensure this token is set for proper functionality. For step-by-step guidance, refer " +
|
||||
"to the **CHAT_TOKEN Config** section of [README](https://github.com/hustcer/deepseek-review/blob/main/README.md#code-review-with-github-action).")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Description: Diff command for DeepSeek-Review
|
||||
|
||||
use common.nu [GITHUB_API_BASE, ECODE, git-check, has-ref]
|
||||
use util.nu [generate-include-regex, generate-exclude-regex, prepare-awk]
|
||||
use util.nu [generate-include-regex, generate-exclude-regex, prepare-awk, is-safe-git]
|
||||
|
||||
# If the PR title or body contains any of these keywords, skip the review
|
||||
const IGNORE_REVIEW_KEYWORDS = ['skip review' 'skip cr']
|
||||
|
||||
49
nu/review.nu
49
nu/review.nu
@@ -55,6 +55,7 @@ export def --env deepseek-review [
|
||||
token?: string, # Your DeepSeek API token, fallback to CHAT_TOKEN env var
|
||||
--debug(-d), # Debug mode
|
||||
--repo(-r): string, # GitHub repo name, e.g. hustcer/deepseek-review, or local repo path / alias
|
||||
--output(-o): string, # Output file path
|
||||
--pr-number(-n): string, # GitHub PR number
|
||||
--gh-token(-k): string, # Your GitHub token, fallback to GITHUB_TOKEN env var
|
||||
--diff-to(-t): string, # Diff to git REF
|
||||
@@ -73,16 +74,20 @@ export def --env deepseek-review [
|
||||
|
||||
$env.config.table.mode = 'psql'
|
||||
let local_repo = $env.PWD
|
||||
let write_file = ($output | is-not-empty)
|
||||
let is_action = ($env.GITHUB_ACTIONS? == 'true')
|
||||
let stream = if $is_action { false } else { true }
|
||||
let token = $token | default $env.CHAT_TOKEN?
|
||||
let repo = $repo | default $env.DEFAULT_GITHUB_REPO?
|
||||
let CHAT_HEADER = [Authorization $'Bearer ($token)']
|
||||
let stream = if $is_action or $write_file { false } else { true }
|
||||
let model = $model | default $env.CHAT_MODEL? | default $DEFAULT_OPTIONS.MODEL
|
||||
let base_url = $base_url | default $env.BASE_URL? | default $DEFAULT_OPTIONS.BASE_URL
|
||||
let url = $chat_url | default $env.CHAT_URL? | default $'($base_url)/chat/completions'
|
||||
let max_length = try { $max_length | default ($env.MAX_LENGTH? | default 0 | into int) } catch { 0 }
|
||||
let temperature = try { $temperature | default $env.TEMPERATURE? | default $DEFAULT_OPTIONS.TEMPERATURE | into float } catch { $DEFAULT_OPTIONS.TEMPERATURE }
|
||||
# Determine output mode
|
||||
let output_mode = if $is_action { 'action' } else if ($output | is-not-empty) { 'file' } else { 'console' }
|
||||
|
||||
validate-temperature $temperature
|
||||
let setting = {
|
||||
repo: $repo,
|
||||
@@ -155,18 +160,50 @@ export def --env deepseek-review [
|
||||
exit $ECODE.SERVER_ERROR
|
||||
}
|
||||
let result = if ($reason | is-empty) { $review } else { $result }
|
||||
if not $is_action {
|
||||
print $'Code Review Result:'; hr-line; print $result
|
||||
} else {
|
||||
post-comments-to-pr $repo $pr_number $result
|
||||
print $'✅ Code review finished!PR (ansi g)#($pr_number)(ansi reset) review result was posted as a comment.'
|
||||
|
||||
match $output_mode {
|
||||
'action' => {
|
||||
post-comments-to-pr $repo $pr_number $result
|
||||
print $'✅ Code review finished!PR (ansi g)#($pr_number)(ansi reset) review result was posted as a comment.'
|
||||
}
|
||||
'file' => { write-review-to-file $output $setting $result $response }
|
||||
_ => { print $'Code Review Result:'; hr-line; print $result }
|
||||
}
|
||||
|
||||
if ($response.usage? | is-not-empty) {
|
||||
print $'(char nl)Token Usage:'; hr-line
|
||||
$response.usage? | table -e | print
|
||||
}
|
||||
}
|
||||
|
||||
# Write the code review result to a file
|
||||
def write-review-to-file [
|
||||
file: string, # Output file path
|
||||
setting: record, # Review settings
|
||||
result: string, # Review result
|
||||
response: record, # DeepSeek API response
|
||||
] {
|
||||
let file = (if not ($file | str ends-with '.md') { $'($file).md' } else { $file })
|
||||
let token_usage = if ($response.usage? | is-empty) { [] } else {
|
||||
['## Token Usage', '', ($response.usage? | transpose key val | to md --pretty)]
|
||||
}
|
||||
# Generate content sections
|
||||
let content_sections = [
|
||||
'# DeepSeek Code Review Result', ''
|
||||
$"Generated at: (date now | format date '%Y/%m/%d %H:%M:%S')", ''
|
||||
'## Code Review Settings', ''
|
||||
($setting | compact-record | reject -i repo | transpose key val | to md --pretty)
|
||||
'', '## Review Detail', '', $result, '', ...$token_usage
|
||||
]
|
||||
try {
|
||||
$content_sections | str join (char nl) | save --force $file
|
||||
print $'Code Review Result saved to (ansi g)($file)(ansi reset)'
|
||||
} catch {|err|
|
||||
print $'(ansi r)Failed to save review result: (ansi reset)'
|
||||
$err | table -e | print
|
||||
}
|
||||
}
|
||||
|
||||
# Validate the DeepSeek API token
|
||||
def validate-token [token?: string, --pr-number: string, --repo: string] {
|
||||
if ($token | is-empty) {
|
||||
|
||||
@@ -114,7 +114,7 @@ export def is-safe-git [cmd: string] {
|
||||
let normalized_cmd = ($cmd | str trim | str downcase)
|
||||
|
||||
# Define allowed command patterns with named capture groups for better validation
|
||||
let git_cmd_pattern = '^git\s+(show|diff)(?:\s+(?:[a-zA-Z0-9_\-\.~/]+)){0,3}(?:\s+(?::[!]?)?[a-zA-Z0-9_\-\.\*\/]+){0,2}$'
|
||||
let git_cmd_pattern = '^git\s+(show|diff)(?:\s+(?:[a-zA-Z0-9_\-\.~/]+(?::[a-zA-Z0-9_\-\.\*\/]+)?)){0,3}(?:\s+(?::[!]?)?[a-zA-Z0-9_\-\.\*\/]+){0,2}$'
|
||||
|
||||
if ($normalized_cmd | find -r $git_cmd_pattern | is-empty) {
|
||||
print $'(ansi r)Invalid git command format. (ansi g)Only simple `git show` or `git diff` commands are allowed.(ansi reset)'
|
||||
|
||||
@@ -41,6 +41,8 @@ def 'is-safe-git:should work as expected' [] {
|
||||
assert equal (is-safe-git 'git diff f536acc 0dd0eb5 :!nu/* >> out.txt') false
|
||||
assert equal (is-safe-git 'git diff f536acc 0dd0eb5 :!nu/* < in.txt') false
|
||||
assert equal (is-safe-git 'git diff f536acc 0dd0eb5 :!nu/* << in.txt') false
|
||||
assert equal (is-safe-git 'git show head:nu/common.nu') true
|
||||
assert equal (is-safe-git 'git show HEAD:nu/common.nu') true
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user