ci: replace duplicate issue workflow (#21122)
- Replace AI MCP similar-issues flow with opencode duplicate check - Read OPENCODE_MODEL from repository variables - Support workflow_dispatch with issue_number input
This commit is contained in:
parent
fbe69a773a
commit
98e556cddd
|
|
@ -1,91 +1,73 @@
|
|||
name: Similar Issues via AI MCP
|
||||
name: duplicate-issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
issues:
|
||||
types: [opened]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: Issue number to check manually
|
||||
required: true
|
||||
type: number
|
||||
|
||||
jobs:
|
||||
find-similar:
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
models: read
|
||||
runs-on: ubuntu-slim
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
check-duplicates:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Prepare prompt variables
|
||||
id: prepare_input
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
with:
|
||||
script: |
|
||||
const issue = context.payload.issue || {};
|
||||
const title = issue.title || '';
|
||||
const body = issue.body || '';
|
||||
const indent = ' ';
|
||||
// Indent subsequent lines so YAML block scalar indentation remains valid
|
||||
const bodyIndented = body.replace(/\n/g, '\n' + indent);
|
||||
core.setOutput('issue_title_json', JSON.stringify(title));
|
||||
core.setOutput('issue_body_indented_json', JSON.stringify(bodyIndented));
|
||||
core.setOutput('issue_number', issue.number);
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Find similar issues with AI (MCP)
|
||||
id: inference
|
||||
uses: actions/ai-inference@a380166897b5408b8fb7dddd148142794cb5624a # v2.0.6
|
||||
with:
|
||||
prompt-file: ./.github/prompts/similar_issues.prompt.yml
|
||||
input: |
|
||||
issue_title: ${{ steps.prepare_input.outputs.issue_title_json }}
|
||||
issue_body: ${{ steps.prepare_input.outputs.issue_body_indented_json }}
|
||||
issue_number: ${{ steps.prepare_input.outputs.issue_number }}
|
||||
repository: ${{ github.repository }}
|
||||
enable-github-mcp: true
|
||||
# Inference token can use GITHUB_TOKEN. MCP specifically requires a PAT.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-mcp-token: ${{ secrets.USER_PAT }}
|
||||
max-tokens: 8000
|
||||
- name: Install opencode
|
||||
run: curl -fsSL https://opencode.ai/install | bash
|
||||
|
||||
- name: Prepare comment body
|
||||
id: prepare
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
env:
|
||||
AI_RESPONSE: ${{ steps.inference.outputs.response }}
|
||||
with:
|
||||
script: |
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(process.env.AI_RESPONSE || '{}');
|
||||
} catch (e) {
|
||||
core.setOutput('has_matches', 'false');
|
||||
return;
|
||||
}
|
||||
const matches = Array.isArray(data.matches) ? data.matches.filter(m => m.number !== context.payload.issue.number) : [];
|
||||
if (!matches.length) {
|
||||
core.setOutput('has_matches', 'false');
|
||||
return;
|
||||
}
|
||||
const lines = [];
|
||||
lines.push('I found similar issues that might help:');
|
||||
for (const m of matches.slice(0, 3)) {
|
||||
const num = m.number != null ? `#${m.number}` : '';
|
||||
const title = m.title || 'Untitled';
|
||||
const url = m.url || '';
|
||||
const score = typeof m.similarity_score === 'number' ? ` (similarity: ${m.similarity_score.toFixed(2)})` : '';
|
||||
lines.push(`- ${url}${score}`.trim());
|
||||
}
|
||||
core.setOutput('has_matches', 'true');
|
||||
core.setOutput('comment_body', lines.join('\n'));
|
||||
- name: Check for duplicate issues
|
||||
env:
|
||||
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ISSUE_NUMBER: ${{ github.event.issue.number || inputs.issue_number }}
|
||||
OPENCODE_PERMISSION: |
|
||||
{
|
||||
"bash": {
|
||||
"*": "deny",
|
||||
"gh issue*": "allow"
|
||||
},
|
||||
"webfetch": "deny"
|
||||
}
|
||||
run: |
|
||||
if [ -z "$ISSUE_NUMBER" ]; then
|
||||
echo "issue_number is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Comment similar issues
|
||||
if: steps.prepare.outputs.has_matches == 'true'
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
with:
|
||||
script: |
|
||||
const body = ${{ toJson(steps.prepare.outputs.comment_body) }};
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.issue.number,
|
||||
body
|
||||
});
|
||||
opencode run -m ${{ vars.OPENCODE_MODEL }} "A new issue has been created:'
|
||||
|
||||
Issue number:
|
||||
$ISSUE_NUMBER
|
||||
|
||||
Lookup this issue and search through existing issues (excluding #$ISSUE_NUMBER) in this repository to find any potential duplicates of this new issue.
|
||||
Consider:
|
||||
1. Similar titles or descriptions
|
||||
2. Same error messages or symptoms
|
||||
3. Related functionality or components
|
||||
4. Similar feature requests
|
||||
|
||||
If you find any potential duplicates, please comment on the new issue with:
|
||||
- A brief explanation of why it might be a duplicate
|
||||
- Links to the potentially duplicate issues
|
||||
- A suggestion to check those issues first
|
||||
|
||||
Use this format for the comment:
|
||||
'This issue might be a duplicate of existing issues. Please check:
|
||||
- #[issue_number]: [brief description of similarity]
|
||||
|
||||
Feel free to ignore if none of these address your specific case.'
|
||||
|
||||
If no clear duplicates are found, do not comment."
|
||||
|
|
|
|||
Loading…
Reference in New Issue