diff --git a/.github/actions/issue-closer/action.yml b/.github/actions/issue-closer/action.yml index 8b5cd4778..5eafa9265 100644 --- a/.github/actions/issue-closer/action.yml +++ b/.github/actions/issue-closer/action.yml @@ -1,5 +1,5 @@ name: Issue matching auto-closer -description: Automatically close issues based on regexs matching. +description: Automatically close issues. author: arkon branding: icon: alert-circle @@ -8,15 +8,6 @@ inputs: repo-token: required: true description: GitHub token - type: - required: true - description: Either "body" or "title", indicating what to run the regex against. - regex: - required: true - description: Regular expression pattern which if matched closes the issue. - message: - required: true - description: Message to post when closing the issue. runs: using: node12 main: dist/index.js diff --git a/.github/actions/issue-closer/package.json b/.github/actions/issue-closer/package.json index 5ec164429..41138730e 100644 --- a/.github/actions/issue-closer/package.json +++ b/.github/actions/issue-closer/package.json @@ -1,7 +1,7 @@ { "name": "issue-closer", "version": "1.0.0", - "description": "GitHub action to automatically close issues based on regexs matching", + "description": "GitHub action to automatically close issues", "main": "lib/action.js", "scripts": { "postinstall": "ncc build src/main.ts" diff --git a/.github/actions/issue-closer/src/main.ts b/.github/actions/issue-closer/src/main.ts index 2e8d12e94..c33dec3ab 100644 --- a/.github/actions/issue-closer/src/main.ts +++ b/.github/actions/issue-closer/src/main.ts @@ -1,71 +1,101 @@ import * as core from '@actions/core'; import * as github from '@actions/github'; +interface Rule { + type: 'title' | 'body'; + regex: string; + message: string; +} + async function run() { - try { - const type: string = core.getInput('type', {required: true}); - const regex: string = core.getInput('regex', {required: true}); - const message: string = core.getInput('message', {required: true}); + try { + // Get client and context + const client: github.GitHub = new github.GitHub( + core.getInput('repo-token', {required: true}) + ); + const context = github.context; + const payload = context.payload; - if (type !== 'title' && type !== 'body') { - throw new Error( - '`type` must be either "title" or "body".' - ); + // Do nothing if it's wasn't being opened or it's not an issue + if (payload.action !== 'opened' || !payload.issue) { + return; + } + + if (!payload.sender) { + throw new Error('Internal error, no sender provided by GitHub'); + } + + const issue: {owner: string; repo: string; number: number} = context.issue; + + const rules: Rule[] = [ + // No source name or short description provided in title + { + type: 'title', + regex: ".*<(Source Name|short description)>*", + message: "You did not fill out the description in the title" + }, + + // Body acknowledgement section not removed + { + type: 'body', + regex: ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*", + message: "The acknowledgment section was not removed" + }, + + // Body requested information not filled out + { + type: 'body', + regex: ".*\\* (Tachiyomi version|Android version|Device|Name|Link|Extension version): \\?.*", + message: "The requested information was not filled out" + } + ]; + + const results = rules + .map(rule => { + const text = rule.type === 'title' ? payload?.issue?.title : payload?.issue?.body; + const regexMatches: boolean = check(rule.regex, text); + + if (regexMatches) { + return rule.message; + } + }) + .filter(Boolean); + + if (results.length > 0) { + // Comment and close + const message = ['@${issue.user.login} this issue was automatically closed because:\n', ...results].join('\n- '); + + await client.issues.createComment({ + owner: issue.owner, + repo: issue.repo, + issue_number: issue.number, + body: evalTemplate(message, payload) + }); + + await client.issues.update({ + owner: issue.owner, + repo: issue.repo, + issue_number: issue.number, + state: 'closed' + }); + } + } catch (error) { + core.setFailed(error.message); } - - // Get client and context - const client: github.GitHub = new github.GitHub( - core.getInput('repo-token', {required: true}) - ); - const context = github.context; - const payload = context.payload; - - // Do nothing if it's wasn't being opened or it's not an issue - if (payload.action !== 'opened' || !payload.issue) { - return; - } - - if (!payload.sender) { - throw new Error('Internal error, no sender provided by GitHub'); - } - - const issue: {owner: string; repo: string; number: number} = context.issue; - - const text = type === 'title' ? payload?.issue?.title : payload?.issue?.body; - const regexMatches: boolean = check(regex, text); - - if (regexMatches) { - // Comment and close - await client.issues.createComment({ - owner: issue.owner, - repo: issue.repo, - issue_number: issue.number, - body: evalTemplate(message, payload) - }); - await client.issues.update({ - owner: issue.owner, - repo: issue.repo, - issue_number: issue.number, - state: 'closed' - }); - } - } catch (error) { - core.setFailed(error.message); - } } function check(patternString: string, text: string | undefined): boolean { - const pattern: RegExp = new RegExp(patternString); + const pattern: RegExp = new RegExp(patternString); - if (text?.match(pattern)) { - return true; - } else { - return false; - } + if (text?.match(pattern)) { + return true; + } else { + return false; + } } function evalTemplate(template: string, params: any) { - return Function(...Object.keys(params), `return \`${template}\``)(...Object.values(params)); + return Function(...Object.keys(params), `return \`${template}\``)(...Object.values(params)); } run(); diff --git a/.github/workflows/issue_closer.yml b/.github/workflows/issue_closer.yml index e017af549..5642dbc6f 100644 --- a/.github/workflows/issue_closer.yml +++ b/.github/workflows/issue_closer.yml @@ -12,25 +12,7 @@ jobs: node-version: 14 - name: Install dependencies run: cd ./.github/actions/issue-closer && npm install - - - name: Autoclose when no source name or short description provided in title + - name: Autoclose issue uses: ./.github/actions/issue-closer with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - type: title - regex: ".*<(Source Name|short description)>*" - message: "@${issue.user.login} this issue was automatically closed because you did not fill out the description in the title." - - name: Autoclose when body acknowledgement section not removed - uses: ./.github/actions/issue-closer - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - type: body - regex: ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*" - message: "@${issue.user.login} this issue was automatically closed because the acknowledgment section was not removed." - - name: Autoclose when body requested information not filled out - uses: ./.github/actions/issue-closer - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - type: body - regex: ".*\\* (Tachiyomi version|Android version|Device|Name|Link|Extension version): \\?.*" - message: "@${issue.user.login} this issue was automatically closed because the requested information was not filled out." \ No newline at end of file + repo-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file