mirror of
https://github.com/iv-org/close-potential-duplicates.git
synced 2024-11-26 15:40:34 +00:00
refactor: ♻️ update deps
This commit is contained in:
parent
e36d3331b9
commit
0fb7fc67dd
49
README.md
49
README.md
@ -1,6 +1,9 @@
|
||||
# Potential Duplicates
|
||||
|
||||
> A Github Action to search for potential issue duplicates using [Damerau–Levenshtein](https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance) algorithm.
|
||||
<h1 align="center">Potential Duplicates</h1>
|
||||
<p align="center">
|
||||
<strong>
|
||||
Search for potential issue duplicates using <a href="https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance">Damerau–Levenshtein</a> algorithm
|
||||
</strong>
|
||||
</p>
|
||||
|
||||
## Usage
|
||||
|
||||
@ -15,7 +18,7 @@ jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: bubkoo/potential-duplicates@v1
|
||||
- uses: wow-actions/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Issue title filter work with anymatch https://www.npmjs.com/package/anymatch.
|
||||
@ -40,6 +43,44 @@ jobs:
|
||||
{{/issues}}
|
||||
```
|
||||
|
||||
### Inputs
|
||||
|
||||
Various inputs are defined to let you configure the action:
|
||||
|
||||
> Note: [Workflow command and parameter names are not case-sensitive](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#about-workflow-commands).
|
||||
|
||||
| Name | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| `GITHUB_TOKEN` | The GitHub token for authentication | N/A |
|
||||
| `filter` | Issue title filter work with [anymatch](https://www.npmjs.com/package/anymatch) <br> Any matched issue will stop detection immediately <br> You can specify multi filters in each line | `''` |
|
||||
| `exclude` | Exclude keywords in title before detecting | `''` |
|
||||
| `label` | Label to set, when potential duplicates are detected | `'potential-duplicate'` |
|
||||
| `state` | Get issues with state to compare. Supported state: `'all'` `'closed'` `'open'` | `'all'` |
|
||||
| `threshold` | If similarity is higher than this threshold(`[0,1]`), issue will be marked as duplicate | `0.6` |
|
||||
| `reactions` | Reactions to be add to comment when potential duplicates are detected <br> Available reactions: "-1", "+1", "confused", "laugh", "heart", "hooray", "rocket", "eyes" | |
|
||||
| `comment` | Comment to post when potential duplicates are detected | 👇 |
|
||||
|
||||
Available reactions:
|
||||
|
||||
| content | emoji |
|
||||
| ---------- | ----- |
|
||||
| `+1` | 👍 |
|
||||
| `-1` | 👎 |
|
||||
| `laugh` | 😄 |
|
||||
| `confused` | 😕 |
|
||||
| `heart` | ❤️ |
|
||||
| `hooray` | 🎉 |
|
||||
| `rocket` | 🚀 |
|
||||
| `eyes` | 👀 |
|
||||
|
||||
Default comment:
|
||||
|
||||
```
|
||||
Potential duplicates: {{#issues}}
|
||||
- [#{{ number }}] {{ title }} ({{ accuracy }}%)
|
||||
{{/issues}}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||
|
66
package.json
66
package.json
@ -1,34 +1,25 @@
|
||||
{
|
||||
"name": "potential-duplicates",
|
||||
"description": "A Github Action to search for potential issue duplicates using Damerau–Levenshtein algorithm.",
|
||||
"description": "Search for potential issue duplicates using Damerau–Levenshtein algorithm.",
|
||||
"version": "1.0.8",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/bubkoo/potential-duplicates",
|
||||
"author": "bubkoo <bubkoo.wy@gmail.com>",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
"action.yml"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"lint": "tslint -c tslint.json -p tsconfig.json --fix",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build": "ncc build src/index.ts --minify --v8-cache",
|
||||
"prebuild": "run-s lint clean",
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
|
||||
"pre-commit": "lint-staged && yarn precommit"
|
||||
}
|
||||
"prepare": "is-ci || husky install .husky"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.{js,jsx,tsx,ts,less,md,json}": [
|
||||
"pretty-quick — staged"
|
||||
],
|
||||
"src/**/*.ts": [
|
||||
"tslint -c tslint.json -p ./tsconfig.json --fix"
|
||||
"*.ts": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"commitlint": {
|
||||
@ -36,33 +27,42 @@
|
||||
"@commitlint/config-conventional"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "bubkoo",
|
||||
"email": "bubkoo.wy@gmail.com"
|
||||
},
|
||||
"contributors": [],
|
||||
"repository": "https://github.com/wow-actions/potential-duplicates",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/github": "^4.0.0",
|
||||
"@actions/github": "^5.0.0",
|
||||
"anymatch": "^3.1.1",
|
||||
"js-yaml": "^3.14.0",
|
||||
"mustache": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^11.0.0",
|
||||
"@commitlint/config-conventional": "^11.0.0",
|
||||
"@types/js-yaml": "^3.12.5",
|
||||
"@commitlint/cli": "^13.1.0",
|
||||
"@commitlint/config-conventional": "^13.1.0",
|
||||
"@types/mustache": "^4.0.1",
|
||||
"@types/node": "^14.0.27",
|
||||
"@typescript-eslint/eslint-plugin": "^4.1.1",
|
||||
"@typescript-eslint/parser": "^4.1.1",
|
||||
"@vercel/ncc": "^0.24.1",
|
||||
"eslint": "^7.9.0",
|
||||
"husky": "^4.3.0",
|
||||
"lint-staged": "^10.3.0",
|
||||
"@types/node": "^16.9.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.18.0",
|
||||
"@typescript-eslint/parser": "^4.18.0",
|
||||
"@vercel/ncc": "^0.31.1",
|
||||
"devmoji": "^2.3.0",
|
||||
"eslint": "^7.22.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"husky": "^7.0.2",
|
||||
"is-ci": "^3.0.0",
|
||||
"lint-staged": "^11.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.1.2",
|
||||
"pretty-quick": "^3.0.2",
|
||||
"prettier": "^2.4.1",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-airbnb": "^5.11.2",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"tslint-eslint-rules": "^5.4.0",
|
||||
"typescript": "^4.0.3"
|
||||
"typescript": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import { Reaction } from './reaction'
|
||||
|
||||
export namespace Action {
|
||||
export async function run() {
|
||||
const context = github.context
|
||||
const { context } = github
|
||||
const payload = context.payload.issue
|
||||
if (
|
||||
payload &&
|
||||
@ -16,15 +16,16 @@ export namespace Action {
|
||||
) {
|
||||
const octokit = Util.getOctokit()
|
||||
const duplicates = []
|
||||
const response = await octokit.issues.listForRepo({
|
||||
const response = await octokit.rest.issues.listForRepo({
|
||||
...context.repo,
|
||||
state: core.getInput('state') as 'all' | 'open' | 'closed',
|
||||
})
|
||||
|
||||
const title = payload.title
|
||||
const { title } = payload
|
||||
const issues = response.data.filter((i) => i.number !== payload.number)
|
||||
const threshold = parseFloat(core.getInput('threshold'))
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const issue of issues) {
|
||||
const accuracy = Algo.compare(
|
||||
Util.formatTitle(issue.title),
|
||||
@ -49,7 +50,7 @@ export namespace Action {
|
||||
if (duplicates.length) {
|
||||
const label = core.getInput('label')
|
||||
if (label) {
|
||||
await octokit.issues.addLabels({
|
||||
await octokit.rest.issues.addLabels({
|
||||
...context.repo,
|
||||
issue_number: payload.number,
|
||||
labels: [label],
|
||||
@ -63,7 +64,7 @@ export namespace Action {
|
||||
issues: duplicates,
|
||||
})
|
||||
|
||||
const { data } = await octokit.issues.createComment({
|
||||
const { data } = await octokit.rest.issues.createComment({
|
||||
...context.repo,
|
||||
body,
|
||||
issue_number: payload.number,
|
||||
|
@ -9,10 +9,12 @@ export namespace Algo {
|
||||
function prepare(phrase: string) {
|
||||
let ret = phrase.toLowerCase()
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const punct of Dic.punctuation) {
|
||||
ret = ret.replace(new RegExp(`\\${punct}`, 'g'), ' ')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
for (const word in Dic.synonyms) {
|
||||
ret = ret.replace(
|
||||
new RegExp((Dic.synonyms as any)[word].join('|'), 'gi'),
|
||||
@ -20,6 +22,7 @@ export namespace Algo {
|
||||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const exclude of Dic.excludes) {
|
||||
ret = ret.replace(new RegExp(`\\b${exclude}\\s\\b`, 'g'), '')
|
||||
}
|
||||
@ -118,11 +121,13 @@ export namespace Algo {
|
||||
let total = 0
|
||||
|
||||
if (wordsA.length > wordsB.length) {
|
||||
[wordsA, wordsB] = [wordsB, wordsA]
|
||||
;[wordsA, wordsB] = [wordsB, wordsA]
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
for (const wordA of wordsA) {
|
||||
const temp = []
|
||||
// eslint-disable-next-line
|
||||
for (const wordB of wordsB) {
|
||||
temp.push(similarity(wordA, wordB))
|
||||
}
|
||||
|
11
src/dic.ts
11
src/dic.ts
@ -28,7 +28,16 @@ export namespace Dic {
|
||||
'outo',
|
||||
]
|
||||
|
||||
export const punctuation = ['! ', ', ', ' - ', ' – ', '... ', '.. ', '. ', ': ']
|
||||
export const punctuation = [
|
||||
'! ',
|
||||
', ',
|
||||
' - ',
|
||||
' – ',
|
||||
'... ',
|
||||
'.. ',
|
||||
'. ',
|
||||
': ',
|
||||
]
|
||||
|
||||
export const synonyms = {
|
||||
app: ['aplication', 'application', 'client'],
|
||||
|
@ -28,14 +28,14 @@ export namespace Reaction {
|
||||
return true
|
||||
}
|
||||
core.debug(`Skipping invalid reaction '${item}'.`)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}) as ReactionType[]
|
||||
}
|
||||
|
||||
export async function add(
|
||||
octokit: ReturnType<typeof github.getOctokit>,
|
||||
comment_id: number, // tslint:disable-line
|
||||
comment_id: number, // eslint-disable-line
|
||||
reactions: string | string[],
|
||||
owner: string = github.context.repo.owner,
|
||||
repo: string = github.context.repo.repo,
|
||||
@ -51,7 +51,7 @@ export namespace Reaction {
|
||||
|
||||
const deferreds = candidates.map((content) => {
|
||||
try {
|
||||
return octokit.reactions.createForIssueComment({
|
||||
return octokit.rest.reactions.createForIssueComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id,
|
||||
@ -61,10 +61,12 @@ export namespace Reaction {
|
||||
core.debug(
|
||||
`Adding reaction '${content}' to comment failed with: ${e.message}.`,
|
||||
)
|
||||
core.error(e)
|
||||
throw e
|
||||
}
|
||||
})
|
||||
|
||||
return Promise.all(deferreds)
|
||||
Promise.all(deferreds).catch((e) => {
|
||||
throw e
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ export namespace Util {
|
||||
}
|
||||
|
||||
export function isValidEvent(event: string, actions?: string | string[]) {
|
||||
const context = github.context
|
||||
const payload = context.payload
|
||||
const { context } = github
|
||||
const { payload } = context
|
||||
if (event === context.eventName) {
|
||||
if (actions == null) {
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user