A production-ready custom GitHub Action that performs semantic search across open issues in your repository to detect and flag potential duplicates. Powered by the Google Gemini API gemini-embedding-001 model.
- 🔍 Semantic Search: Understands the meaning of titles and descriptions, finding matches that simple keyword searches would miss.
- ⏳ Rate-Limit Guard: Automatically enforces a strict 4.1-second delay between API requests to strictly respect the Gemini free tier limit (15 Requests Per Minute).
- 🛡️ Anti-Spam / Idempotency: Inspects previous bot comments to avoid duplicate warnings on the same issue.
- 🏷️ Auto-Labeling: Applies a
possible-duplicatelabel to flagged issues. - ⚡ Manual Trigger: Runs on-demand via the Actions tab using
workflow_dispatchto control when resources and API keys are consumed.
Follow these steps to integrate the duplicate detector into your repository.
To communicate with Google Gemini, you need a free Gemini API Key:
- Go to Google AI Studio and generate a free API Key.
- Navigate to your GitHub Repository: Settings → Secrets and variables → Actions → New repository secret.
- Create a secret named
GEMINI_API_KEYand paste your API key.
GitHub Actions need permission to write comments and add labels to issues:
- Navigate to: Settings → Actions → General.
- Scroll to Workflow permissions.
- Select Read and write permissions.
- Click Save.
- Navigate to the Actions tab of your repository.
- Select Find Semantic Duplicates from the left-hand sidebar.
- Click the Run workflow dropdown on the right and click the green button.
When a duplicate is successfully detected (similarity score
Hey @jhasourav07! 🤖
My semantic scan detected that this issue might be a duplicate of #42 (Similarity: 89.5%).
Please check between these issues and close this one if it is a duplicate.
The script includes several levels of robust, production-grade error handling:
- Missing Keys: Throws a explicit error if
GEMINI_API_KEYorGITHUB_TOKENis missing, immediately failing the step with clean diagnostic logs. - Failures in Embeddings API: Catch blocks log precise error diagnostics if a request to Gemini fails.
- Label Creation Safety: Gracefully catches errors if the
possible-duplicatelabel does not exist yet (or if the token lacks labeling permissions) to prevent the entire run from failing.
The cosine similarity calculation computes the dot product of normalized embedding vectors generated from your issue titles and descriptions:
This ensures mathematical precision across semantic features regardless of text length.
To conserve API tokens and prevent payload overflow, issue text is combined and truncated:
const textToEmbed = `Title: ${issue.title}\nBody: ${issue.body || ''}`.slice(0, 3000);