-
-
Notifications
You must be signed in to change notification settings - Fork 148
Duplicate issue and pr validator #244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| name: Duplicate Issue Detector | ||
|
|
||
| on: | ||
| issues: | ||
| types: [opened, edited] | ||
|
|
||
| permissions: | ||
| issues: write | ||
|
|
||
| jobs: | ||
| duplicate-check: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Analyze issue similarity | ||
| id: similarity | ||
| uses: actions-cool/issues-similarity-analysis@v1 | ||
| with: | ||
| # ---- Core accuracy ---- | ||
| filter-threshold: 0.88 # higher = fewer false positives | ||
|
|
||
| comment-title: 'Potential Duplicate Issue' | ||
| comment-body: | | ||
| Hi @${{ github.actor }}, | ||
|
|
||
| This issue appears **very similar** to one or more existing issues: | ||
|
|
||
| ${index}. **${title}** | ||
| ${url} | ||
| Similarity score: **${similarity}%** | ||
|
|
||
| If this is a duplicate, please: | ||
| - Close this issue | ||
| - Continue the discussion on the existing one | ||
|
|
||
| If not, feel free to clarify how this issue is different. | ||
|
|
||
| show-footer: true | ||
|
|
||
| # ---- Auto-label ONLY when confidence is very high ---- | ||
| - name: Label as duplicate (high confidence) | ||
| if: | | ||
| steps.similarity.outputs.similar-issues-found == 'true' && | ||
| steps.similarity.outputs.highest-similarity-score >= '80' | ||
| uses: actions/github-script@v6 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: The latest release of Update The current version 🧰 Tools🪛 actionlint (1.7.10)[error] 45-45: the runner of "actions/github-script@v6" action is too old to run on GitHub Actions. update the action's version to fix this issue (action) 🤖 Prompt for AI Agents |
||
| with: | ||
| script: | | ||
| await github.rest.issues.addLabels({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| labels: ['duplicate'] | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| name: PR Assignment Validation | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, reopened, edited] | ||
|
|
||
| permissions: | ||
| pull-requests: write | ||
| issues: read | ||
|
|
||
| jobs: | ||
| validate-assignment: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Validate PR issue assignment | ||
| uses: actions/github-script@v6 | ||
| with: | ||
| script: | | ||
| const pr = context.payload.pull_request; | ||
| const author = pr.user.login; | ||
| const body = pr.body || ""; | ||
|
|
||
| // Skip if already labeled | ||
| const existingLabels = pr.labels.map(l => l.name); | ||
| if (existingLabels.includes('not-assigned')) { | ||
| console.log('Already marked not-assigned. Skipping.'); | ||
| return; | ||
| } | ||
|
|
||
| // Match Fixes #123 / Closes #123 / Resolves #123 | ||
| const issueRegex = /(fixes|closes|resolves)\s+#(\d+)/gi; | ||
| const matches = [...body.matchAll(issueRegex)]; | ||
|
|
||
| if (matches.length === 0) { | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: pr.number, | ||
| body: `Hey @${author} 👋\n\nPlease link the issue you are working on (e.g. **Fixes #123**).` | ||
| }); | ||
|
|
||
| await github.rest.issues.addLabels({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: pr.number, | ||
| labels: ['not-assigned'] | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| for (const match of matches) { | ||
| const issueNumber = match[2]; | ||
|
|
||
| try { | ||
| const issue = await github.rest.issues.get({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: issueNumber | ||
| }); | ||
|
|
||
| const assignees = issue.data.assignees.map(a => a.login); | ||
|
|
||
| // Valid only if PR author is assigned | ||
| if (assignees.includes(author)) { | ||
| console.log('Author is assigned. PR is valid.'); | ||
| return; | ||
| } | ||
| } catch (e) { | ||
| console.log(`Failed to fetch issue #${issueNumber}`); | ||
| } | ||
| } | ||
|
Comment on lines
+52
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider edge case: all issue fetches fail. If every linked issue fails to fetch (e.g., all referenced issues were deleted or are in other repos), the workflow falls through and labels the PR as 🤖 Prompt for AI Agents |
||
|
|
||
| // Not assigned to linked issue | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: pr.number, | ||
| body: `🚫 **PR Validation Failed**\n\nHey @${author}, you are not assigned to the linked issue.\n\nPlease ask a maintainer to assign the issue to you before opening a PR.` | ||
| }); | ||
|
|
||
| await github.rest.issues.addLabels({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: pr.number, | ||
| labels: ['not-assigned'] | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.