mirror of
https://github.com/hustcer/deepseek-review.git
synced 2026-05-13 05:16:05 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
000000086e | ||
|
|
5225cc66ea | ||
|
|
e94ff03208 | ||
|
|
a7fd374fc1 | ||
|
|
a7699eee9c |
@@ -2,11 +2,13 @@
|
||||
# Usage: Copy this file to .env and replace the values with your own
|
||||
# WARNING: Do not commit the actual .env file to version control as it may contain sensitive information.
|
||||
|
||||
# DEEPSEEK_TOKEN: Obtain this token from your Deepseek account settings
|
||||
DEEPSEEK_TOKEN='Your Deepseek API token'
|
||||
# CHAT_TOKEN: Obtain this token from your Deepseek account settings
|
||||
CHAT_TOKEN='Your Deepseek API token'
|
||||
# GITHUB_TOKEN: Your GitHub API token to query GitHub PR changes
|
||||
# Generate this token from your GitHub account with the necessary permissions
|
||||
GITHUB_TOKEN='Your GitHub API token'
|
||||
# MAX_LENGTH: The maximum length of the content for review, 0 means no limit.
|
||||
MAX_LENGTH='0'
|
||||
# Default GitHub repository name to fetch PR changes
|
||||
DEFAULT_GITHUB_REPO='hustcer/deepseek-review'
|
||||
# Default local repository absolute path to query commit changes
|
||||
|
||||
2
.github/workflows/basic.yml
vendored
2
.github/workflows/basic.yml
vendored
@@ -20,4 +20,4 @@ jobs:
|
||||
- name: Deepseek Code Review
|
||||
uses: hustcer/deepseek-review@develop
|
||||
with:
|
||||
deepseek-token: ${{ secrets.DEEPSEEK_TOKEN }}
|
||||
chat-token: ${{ secrets.CHAT_TOKEN }}
|
||||
|
||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,6 +1,20 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.2.0] - 2025-01-31
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- Change `DEEPSEEK_TOKEN` to `CHAT_TOKEN` (#50)
|
||||
|
||||
### Features
|
||||
|
||||
- Add `max-length` input (#52)
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update action name, description and icon (#49)
|
||||
|
||||
## [1.1.0] - 2025-01-30
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -36,16 +36,17 @@ jobs:
|
||||
- name: Deepseek Code Review
|
||||
uses: hustcer/deepseek-review@v1
|
||||
with:
|
||||
deepseek-token: ${{ secrets.DEEPSEEK_TOKEN }}
|
||||
chat-token: ${{ secrets.CHAT_TOKEN }}
|
||||
```
|
||||
|
||||
## Input Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------------- | ------ | ----------------------------------------------------------------------- |
|
||||
| deepseek-token | String | Required, Deepseek API Token |
|
||||
| chat-token | String | Required, Deepseek API Token |
|
||||
| model | String | Optional, the model used for code review, defaults to `deepseek-chat` |
|
||||
| base-url | String | Optional, Deepseek API Base URL, defaults to `https://api.deepseek.com` |
|
||||
| max-length | Int | Optional, Maximum length of the content for review, if the content length exceeds this value, the review will be skipped. Default `0` means no limit. |
|
||||
| sys-prompt | String | Optional, system prompt corresponding to `$sys_prompt` in the payload, default value see note below |
|
||||
| user-prompt | String | Optional, user prompt corresponding to `$user_prompt` in the payload, default value see note below |
|
||||
|
||||
@@ -99,7 +100,7 @@ Flags:
|
||||
-h, --help: Display the help message for this command
|
||||
|
||||
Parameters:
|
||||
token <string>: Your Deepseek API token, fallback to DEEPSEEK_TOKEN (optional)
|
||||
token <string>: Your Deepseek API token, fallback to CHAT_TOKEN (optional)
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -34,16 +34,17 @@ jobs:
|
||||
- name: Deepseek Code Review
|
||||
uses: hustcer/deepseek-review@v1
|
||||
with:
|
||||
deepseek-token: ${{ secrets.DEEPSEEK_TOKEN }}
|
||||
chat-token: ${{ secrets.CHAT_TOKEN }}
|
||||
```
|
||||
|
||||
## 输入参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------------- | ------ | -------------------------------------------------------------- |
|
||||
| deepseek-token | String | 必填,Deepseek API Token |
|
||||
| chat-token | String | 必填,Deepseek API Token |
|
||||
| model | String | 可选,配置代码审核选用的模型,默认为 `deepseek-chat` |
|
||||
| base-url | String | 可选,Deepseek API Base URL, 默认为 `https://api.deepseek.com` |
|
||||
| max-length | Int | 可选,待审核内容的最大长度, 默认 `0` 表示没有限制,超过非零值则跳过审核 |
|
||||
| sys-prompt | String | 可选,系统 Prompt 对应入参中的 `$sys_prompt`, 默认值见后文注释 |
|
||||
| user-prompt | String | 可选,用户 Prompt 对应入参中的 `$user_prompt`, 默认值见后文注释 |
|
||||
|
||||
@@ -97,7 +98,7 @@ Flags:
|
||||
-h, --help: Display the help message for this command
|
||||
|
||||
Parameters:
|
||||
token <string>: Your Deepseek API token, fallback to DEEPSEEK_TOKEN (optional)
|
||||
token <string>: Your Deepseek API token, fallback to CHAT_TOKEN (optional)
|
||||
|
||||
```
|
||||
|
||||
|
||||
16
action.yaml
16
action.yaml
@@ -6,18 +6,22 @@
|
||||
# - https://docs.github.com/cn/actions/creating-actions/metadata-syntax-for-github-actions
|
||||
# - https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||
|
||||
name: 'Deepseek Code Review'
|
||||
name: 'Deepseek CR'
|
||||
author: 'hustcer'
|
||||
description: 'A github action to do code review by Deepseek for PRs.'
|
||||
description: '🚀 Sharpen Your Code, Ship with Confidence – Elevate Your Workflow with Deepseek Code Review 🚀'
|
||||
|
||||
branding:
|
||||
icon: 'code'
|
||||
icon: 'eye'
|
||||
color: 'purple'
|
||||
|
||||
inputs:
|
||||
deepseek-token:
|
||||
chat-token:
|
||||
required: true
|
||||
description: 'Your deepseek API token.'
|
||||
max-length:
|
||||
required: false
|
||||
default: 0
|
||||
description: 'The maximum length of the content for review, 0 means no limit.'
|
||||
model:
|
||||
required: false
|
||||
default: 'deepseek-chat'
|
||||
@@ -52,9 +56,10 @@ runs:
|
||||
let ghToken = '${{ github.token }}'
|
||||
let baseUrl = '${{inputs.base-url}}'
|
||||
let repo = '${{ github.repository }}'
|
||||
let token = '${{inputs.deepseek-token}}'
|
||||
let token = '${{inputs.chat-token}}'
|
||||
let sysPrompt = '${{inputs.sys-prompt}}'
|
||||
let userPrompt = '${{inputs.user-prompt}}'
|
||||
let maxLength = ${{inputs.max-length}} | into int
|
||||
let pr = '${{ github.event.pull_request.number }}'
|
||||
(deepseek-review $token
|
||||
--model $model
|
||||
@@ -62,6 +67,7 @@ runs:
|
||||
--pr-number $pr
|
||||
--gh-token $ghToken
|
||||
--base-url $baseUrl
|
||||
--max-length $maxLength
|
||||
--sys-prompt $sysPrompt
|
||||
--user-prompt $userPrompt
|
||||
)
|
||||
|
||||
@@ -39,6 +39,7 @@ commit_parsers = [
|
||||
{ message = "^doc", group = "Documentation"},
|
||||
{ message = "^perf", group = "Performance"},
|
||||
{ message = "^refactor", group = "Refactor"},
|
||||
{ message = "^breaking", group = "Breaking Changes"},
|
||||
{ message = "^style", group = "Styling"},
|
||||
{ message = "^test", group = "Testing"},
|
||||
{ message = "^chore\\(release\\): prepare for", skip = true},
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "deepseek-review",
|
||||
"version": "1.1.0",
|
||||
"actionVer": "v1.1",
|
||||
"version": "1.2.0",
|
||||
"actionVer": "v1.2",
|
||||
"author": "hustcer",
|
||||
"license": "MIT",
|
||||
"github": "https://github.com/hustcer/deepseek-review",
|
||||
"home": "https://github.com/marketplace/actions/deepseek-review",
|
||||
"description": "A github action to do code review for pull requests."
|
||||
"description": "🚀 Sharpen Your Code, Ship with Confidence – Elevate Your Workflow with Deepseek Code Review 🚀"
|
||||
}
|
||||
|
||||
42
nu/review.nu
42
nu/review.nu
@@ -10,7 +10,7 @@
|
||||
# Description: A script to do code review by deepseek
|
||||
# Env vars:
|
||||
# GITHUB_TOKEN: Your GitHub API token
|
||||
# DEEPSEEK_TOKEN: Your Deepseek API token
|
||||
# CHAT_TOKEN: Your Deepseek API token
|
||||
# BASE_URL: Deepseek API base URL
|
||||
# SYSTEM_PROMPT: System prompt message
|
||||
# USER_PROMPT: User prompt message
|
||||
@@ -38,42 +38,45 @@ const DEFAULT_OPTIONS = {
|
||||
SYS_PROMPT: 'You are a professional code review assistant responsible for analyzing code changes in GitHub Pull Requests. Identify potential issues such as code style violations, logical errors, security vulnerabilities, and provide improvement suggestions. Clearly list the problems and recommendations in a concise manner.',
|
||||
}
|
||||
|
||||
# Use Deepseek AI to review code changes
|
||||
# Use Deepseek AI to review code changes locally or in GitHub Actions
|
||||
export def --env deepseek-review [
|
||||
token?: string, # Your Deepseek API token, fallback to DEEPSEEK_TOKEN
|
||||
token?: string, # Your Deepseek API token, fallback to CHAT_TOKEN env var
|
||||
--debug(-d), # Debug mode
|
||||
--repo(-r): string, # GitHub repository name, e.g. hustcer/deepseek-review
|
||||
--pr-number(-n): string, # GitHub PR number
|
||||
--gh-token: string, # Your GitHub token, GITHUB_TOKEN by default
|
||||
--gh-token: string, # Your GitHub token, fallback to GITHUB_TOKEN env var
|
||||
--diff-to(-t): string, # Diff to git REF
|
||||
--diff-from(-f): string, # Diff from git REF
|
||||
--max-length(-l): int, # Maximum length of the content for review, 0 means no limit.
|
||||
--model(-m): string = $DEFAULT_OPTIONS.MODEL, # Model name, deepseek-chat by default
|
||||
--base-url: string = $DEFAULT_OPTIONS.BASE_URL,
|
||||
--sys-prompt(-s): string = $DEFAULT_OPTIONS.SYS_PROMPT,
|
||||
--user-prompt(-u): string = $DEFAULT_OPTIONS.USER_PROMPT,
|
||||
] {
|
||||
]: nothing -> nothing {
|
||||
$env.config.table.mode = 'psql'
|
||||
let is_action = ($env.GITHUB_ACTIONS? == 'true')
|
||||
let token = $token | default $env.DEEPSEEK_TOKEN?
|
||||
let token = $token | default $env.CHAT_TOKEN?
|
||||
let repo = $repo | default $env.DEFAULT_GITHUB_REPO?
|
||||
let header = [Authorization $'Bearer ($token)']
|
||||
let url = $'($base_url)/chat/completions'
|
||||
let local_repo = $env.DEFAULT_LOCAL_REPO? | default (pwd)
|
||||
let max_length = $max_length | default ($env.MAX_LENGTH? | default 0 | into int)
|
||||
let setting = {
|
||||
repo: $repo,
|
||||
diff_to: $diff_to,
|
||||
diff_from: $diff_from,
|
||||
pr_number: $pr_number,
|
||||
max_length: $max_length,
|
||||
local_repo: $local_repo,
|
||||
}
|
||||
$env.GH_TOKEN = $gh_token | default $env.GITHUB_TOKEN?
|
||||
if ($token | is-empty) {
|
||||
print $'(ansi r)Please provide your Deepseek API token by setting `DEEPSEEK_TOKEN` or passing it as an argument.(ansi reset)'
|
||||
return
|
||||
print $'(ansi r)Please provide your Deepseek API token by setting `CHAT_TOKEN` or passing it as an argument.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
if $is_action and not (is-installed gh) {
|
||||
print $'(ansi r)Please install GitHub CLI from https://cli.github.com (ansi reset)'
|
||||
return
|
||||
exit $ECODE.MISSING_BINARY
|
||||
}
|
||||
let hint = if not $is_action and ($pr_number | is-empty) {
|
||||
$'🚀 Initiate the code review by Deepseek AI for local changes ...'
|
||||
@@ -84,6 +87,12 @@ export def --env deepseek-review [
|
||||
if ($pr_number | is-empty) { $setting | compact-record | reject repo | print }
|
||||
|
||||
let diff_content = get-diff --pr-number $pr_number --repo $repo --diff-to $diff_to --diff-from $diff_from
|
||||
let length = $diff_content | str stats | get unicode-width
|
||||
if ($max_length != 0) and ($length > $max_length) {
|
||||
print $'(char nl)(ansi r)The content length ($length) exceeds the maximum limit ($max_length), review skipped.(ansi reset)'
|
||||
exit $ECODE.SUCCESS
|
||||
}
|
||||
print $'Review content length: (ansi g)($length)(ansi reset)'
|
||||
let payload = {
|
||||
model: $model,
|
||||
stream: false,
|
||||
@@ -98,13 +107,11 @@ export def --env deepseek-review [
|
||||
if ($response | is-empty) {
|
||||
print $'(ansi r)Oops, No response returned from Deepseek API.(ansi reset)'
|
||||
exit $ECODE.SERVER_ERROR
|
||||
return
|
||||
}
|
||||
if $debug { print $'Deepseek Response:'; hr-line; $response | table -e | print }
|
||||
if ($response | describe) == 'string' {
|
||||
print $'❌ Code review failed!Error: '; hr-line; print $response
|
||||
exit $ECODE.SERVER_ERROR
|
||||
return
|
||||
}
|
||||
let review = $response | get -i choices.0.message.content
|
||||
if not $is_action {
|
||||
@@ -119,10 +126,10 @@ export def --env deepseek-review [
|
||||
|
||||
# Get the diff content from GitHub PR or local git changes
|
||||
export def get-diff [
|
||||
--pr-number: string, # GitHub PR number
|
||||
--repo: string, # GitHub repository name
|
||||
--diff-to: string, # Diff to git ref
|
||||
--diff-from: string, # Diff from git ref
|
||||
--pr-number: string, # GitHub PR number
|
||||
--diff-to: string, # Diff to git ref
|
||||
--diff-from: string, # Diff from git ref
|
||||
] {
|
||||
let local_repo = $env.DEFAULT_LOCAL_REPO? | default (pwd)
|
||||
if not ($local_repo | path exists) {
|
||||
@@ -152,14 +159,13 @@ export def get-diff [
|
||||
} else { git diff }
|
||||
|
||||
if ($diff_content | is-empty) {
|
||||
print $'(ansi g)Nothing to review.(ansi reset)'
|
||||
exit $ECODE.SUCCESS
|
||||
print $'(ansi g)Nothing to review.(ansi reset)'; exit $ECODE.SUCCESS
|
||||
}
|
||||
$diff_content
|
||||
}
|
||||
|
||||
# Compact the record by removing empty columns
|
||||
export def compact-record [] {
|
||||
export def compact-record []: record -> record {
|
||||
let record = $in
|
||||
let empties = $record | columns | filter {|it| $record | get $it | is-empty }
|
||||
$record | reject ...$empties
|
||||
@@ -204,9 +210,9 @@ export def has-ref [
|
||||
|
||||
export def hr-line [
|
||||
width?: int = 90,
|
||||
--color(-c): string = 'g',
|
||||
--blank-line(-b),
|
||||
--with-arrow(-a),
|
||||
--color(-c): string = 'g',
|
||||
] {
|
||||
# Create a line by repeating the unit with specified times
|
||||
def build-line [
|
||||
|
||||
Reference in New Issue
Block a user