Repository navigation
shell-tool-mcp cannot be released until its publish job asks for permissions the caller grants #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Issue Deduplicator | |
| on: | |
| issues: | |
| types: | |
| - opened | |
| - labeled | |
| jobs: | |
| gather-duplicates: | |
| name: Identify potential duplicates | |
| # Prevent runs on forks (requires OpenAI API key, wastes Actions minutes) | |
| if: github.repository == 'openai/opencli' && (github.event.action == 'opened' || (github.event.action == 'labeled' && github.event.label.name == 'opencli-deduplicate')) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| opencli_output: ${{ steps.opencli.outputs.final-message }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Prepare OpenCLI inputs | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -eo pipefail | |
| CURRENT_ISSUE_FILE=opencli-current-issue.json | |
| EXISTING_ISSUES_FILE=opencli-existing-issues.json | |
| gh issue list --repo "${{ github.repository }}" \ | |
| --json number,title,body,createdAt \ | |
| --limit 1000 \ | |
| --state all \ | |
| --search "sort:created-desc" \ | |
| | jq '.' \ | |
| > "$EXISTING_ISSUES_FILE" | |
| gh issue view "${{ github.event.issue.number }}" \ | |
| --repo "${{ github.repository }}" \ | |
| --json number,title,body \ | |
| | jq '.' \ | |
| > "$CURRENT_ISSUE_FILE" | |
| - id: opencli | |
| uses: openai/opencli-action@main | |
| with: | |
| openai-api-key: ${{ secrets.OPENCLI_OPENAI_API_KEY }} | |
| allow-users: "*" | |
| prompt: | | |
| You are an assistant that triages new GitHub issues by identifying potential duplicates. | |
| You will receive the following JSON files located in the current working directory: | |
| - `opencli-current-issue.json`: JSON object describing the newly created issue (fields: number, title, body). | |
| - `opencli-existing-issues.json`: JSON array of recent issues (each element includes number, title, body, createdAt). | |
| Instructions: | |
| - Compare the current issue against the existing issues to find up to five that appear to describe the same underlying problem or request. | |
| - Focus on the underlying intent and context of each issue—such as reported symptoms, feature requests, reproduction steps, or error messages—rather than relying solely on string similarity or synthetic metrics. | |
| - After your analysis, validate your results in 1-2 lines explaining your decision to return the selected matches. | |
| - When unsure, prefer returning fewer matches. | |
| - Include at most five numbers. | |
| output-schema: | | |
| { | |
| "type": "object", | |
| "properties": { | |
| "issues": { | |
| "type": "array", | |
| "items": { | |
| "type": "string" | |
| } | |
| }, | |
| "reason": { "type": "string" } | |
| }, | |
| "required": ["issues", "reason"], | |
| "additionalProperties": false | |
| } | |
| comment-on-issue: | |
| name: Comment with potential duplicates | |
| needs: gather-duplicates | |
| if: ${{ needs.gather-duplicates.result != 'skipped' }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| issues: write | |
| steps: | |
| - name: Comment on issue | |
| uses: actions/github-script@v8 | |
| env: | |
| OPENCLI_OUTPUT: ${{ needs.gather-duplicates.outputs.opencli_output }} | |
| with: | |
| github-token: ${{ github.token }} | |
| script: | | |
| const raw = process.env.OPENCLI_OUTPUT ?? ''; | |
| let parsed; | |
| try { | |
| parsed = JSON.parse(raw); | |
| } catch (error) { | |
| core.info(`OpenCLI output was not valid JSON. Raw output: ${raw}`); | |
| core.info(`Parse error: ${error.message}`); | |
| return; | |
| } | |
| const issues = Array.isArray(parsed?.issues) ? parsed.issues : []; | |
| const currentIssueNumber = String(context.payload.issue.number); | |
| console.log(`Current issue number: ${currentIssueNumber}`); | |
| console.log(issues); | |
| const filteredIssues = issues.filter((value) => String(value) !== currentIssueNumber); | |
| if (filteredIssues.length === 0) { | |
| core.info('OpenCLI reported no potential duplicates.'); | |
| return; | |
| } | |
| const lines = [ | |
| 'Potential duplicates detected. Please review them and close your issue if it is a duplicate.', | |
| '', | |
| ...filteredIssues.map((value) => `- #${String(value)}`), | |
| '', | |
| '*Powered by [OpenCLI Action](https://github.com/ai-dashboad/opencli-action)*']; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.payload.issue.number, | |
| body: lines.join("\n"), | |
| }); | |
| - name: Remove opencli-deduplicate label | |
| if: ${{ always() && github.event.action == 'labeled' && github.event.label.name == 'opencli-deduplicate' }} | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| run: | | |
| gh issue edit "${{ github.event.issue.number }}" --remove-label opencli-deduplicate || true | |
| echo "Attempted to remove label: opencli-deduplicate" |