Skip to content
Closed
Show file tree
Hide file tree
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
53 changes: 53 additions & 0 deletions .github/workflows/duplicate_issue_detector.yaml
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
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

latest version actions/github-script GitHub Action

💡 Result:

The latest release of actions/github-script is v8.0.0, and the recommended major-version tag to use in workflows is actions/github-script@v8. [1][2]


Update actions/github-script to v8.

The current version actions/github-script@v6 is outdated. The latest stable version is v8, which includes compatibility and security improvements. Update to actions/github-script@v8.

🧰 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
In @.github/workflows/duplicate_issue_detector.yaml at line 45, Replace the
outdated action reference "actions/github-script@v6" with the current stable
version "actions/github-script@v8"; update the workflow step that uses
actions/github-script (the line containing uses: actions/github-script@v6) to
uses: actions/github-script@v8 so the workflow runs the newer, security- and
compatibility-improved release.

with:
script: |
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['duplicate']
});
87 changes: 87 additions & 0 deletions .github/workflows/pr_assignment_validation.yaml
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
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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 not-assigned. This may be unexpected behavior for the PR author. Consider adding explicit handling or a distinct message for this scenario.

🤖 Prompt for AI Agents
In @.github/workflows/pr_assignment_validation.yaml around lines 52 - 72, The
current loop over matches calling github.rest.issues.get (using issueNumber)
doesn't handle the case where all fetches fail; add a success flag or counter in
the scope outside the for (const match of matches) loop that is set when any
issue fetch succeeds and is processed (e.g., when you compute assignees from
issue.data.assignees and check assignees.includes(author)); after the loop,
check that flag and if no fetch succeeded, log a distinct message and
avoid/alter applying the `not-assigned` label (or add a separate
`issues-unreachable` label) so the workflow treats "all fetches failed"
differently from "author not assigned".


// 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']
});
Loading