Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 78 additions & 27 deletions .github/workflows/open_code_review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ on:
workflow_call:
secrets:
DEEPSEEK_API_KEY:
required: true
required: false
QWEN_API_KEY:
required: false

# A newer authorized /review command supersedes a review that is still running.
# Other comments get unique groups, so they cannot cancel a PR review.
Expand Down Expand Up @@ -35,46 +37,95 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Acknowledge review command
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'eyes',
});

- name: Resolve model and pull request refs
id: pr
uses: actions/github-script@v7
with:
script: |
const command = context.payload.comment.body.trim();
const match = /^\/review(?: +([A-Za-z0-9-]+))?$/.exec(command);
const providers = {
deepseek: {
url: 'https://api.deepseek.com/chat/completions',
secret: 'DEEPSEEK_API_KEY',
},
qwen: {
url: 'https://dashscope-us.aliyuncs.com/compatible-mode/v1/chat/completions',
secret: 'QWEN_API_KEY',
},
};

const models = {
pro: 'deepseek-v4-pro',
flash: 'deepseek-flash',
'deepseek-v4-pro': 'deepseek-v4-pro',
'deepseek-flash': 'deepseek-flash',
pro: { id: 'deepseek-v4-pro', provider: 'deepseek' },
flash: { id: 'deepseek-flash', provider: 'deepseek' },
max: { id: 'qwen3.8-max', provider: 'qwen' },

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no true

// DeepSeek
'deepseek-pro': { id: 'deepseek-v4-pro', provider: 'deepseek' },
'deepseek-flash': { id: 'deepseek-flash', provider: 'deepseek' },
// Qwen
'qwen-max': { id: 'qwen3.8-max', provider: 'qwen' },
'qwen-flash': { id: 'qwen3.8-flash', provider: 'qwen' },
'qwen-plus': { id: 'qwen3.7-plus', provider: 'qwen' },
};
const model = match && (match[1] ? models[match[1]] : models.pro);
if (!model) {
core.setFailed('Use /review [pro|flash|deepseek-v4-pro|deepseek-flash].');
return;
}
core.setOutput('model', model);

const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
core.setOutput('base_ref', pr.base.ref);
core.setOutput('head_sha', pr.head.sha);
try {
const command = context.payload.comment.body.trim();
const match = /^\/review(?: +([A-Za-z0-9._-]+))?$/i.exec(command);
const requestedModel = match && (match[1] || 'pro').toLowerCase();
const model = requestedModel && models[requestedModel];
if (!model) {
throw new Error(
`Unsupported model. Use /review MODEL. Supported models: ${Object.keys(models).join(', ')}.`
);
}

- name: Acknowledge review command
const provider = providers[model.provider];
if (!provider) {
throw new Error(`Provider configuration is missing for ${model.provider}.`);
}

const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});

core.setOutput('model', model.id);
core.setOutput('llm_url', provider.url);
core.setOutput('llm_auth_secret', provider.secret);
core.setOutput('base_ref', pr.base.ref);
core.setOutput('head_sha', pr.head.sha);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
core.setOutput('error', message);
core.setFailed(message);
}

- name: Report model resolution error
if: ${{ failure() && steps.pr.outcome == 'failure' }}
uses: actions/github-script@v7
continue-on-error: true
env:
ERROR_MESSAGE: ${{ steps.pr.outputs.error || 'Failed to resolve the review model or pull request.' }}
with:
script: |
await github.rest.reactions.createForIssueComment({
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'eyes',
issue_number: context.issue.number,
body: `OpenCodeReview could not start: ${process.env.ERROR_MESSAGE}`,
});


# The shared rules are checked out from this trusted repository, never
# from the pull request branch being reviewed.
- name: Check out shared Nim rules
Expand Down Expand Up @@ -111,8 +162,8 @@ jobs:
- name: Review with OpenCodeReview
uses: alibaba/open-code-review@main
with:
llm_url: https://api.deepseek.com/chat/completions
llm_auth_token: ${{ secrets.DEEPSEEK_API_KEY }}
llm_url: ${{ steps.pr.outputs.llm_url }}
llm_auth_token: ${{ secrets[steps.pr.outputs.llm_auth_secret] }}
llm_model: ${{ steps.pr.outputs.model }}
llm_use_anthropic: 'false'
base_ref: ${{ steps.pr.outputs.base_ref }}
Expand Down
Loading