Repository: actions/stale
Pull request #332 (2021-02-24 05:06:42)

Bump ts-jest from 26.5.1 to 26.5.2
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 26.5.1 to 26.5.2.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/kulshekhar/ts-jest/blob/master/CHANGELOG.md">ts-jest's changelog</a>.</em></p>
<blockquote>
<h2><a href="https://github.com/kulshekhar/ts-jest/compare/v26.5.1...v26.5.2">26.5.2</a> (2021-02-21)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>compiler:</strong> exclude files in <code>outDir</code> from compiler source files (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2376">#2376</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/9034677f9ce0968339d3d942a70e888996fac532">9034677</a>), closes <a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2350">#2350</a> <a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2374">#2374</a></li>
<li><strong>config:</strong> define <code>matchTestFilePath</code> before <code>setupTsJestCfg</code> (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2373">#2373</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/c427fea48a24b5ce6e8b9260d3c322583b062a77">c427fea</a>), closes <a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2371">#2371</a></li>
<li><strong>config:</strong> improve emit skipped error message (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2357">#2357</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/f2808bb0b15231c67ccb9a97ed606741213c03e6">f2808bb</a>)</li>
<li><strong>typings:</strong> set correct typing for <code>tsconfig</code>/<code>tsConfig</code> option (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2377">#2377</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/d4f6aff3f181761bf25c64ff1a97dd19a69196f9">d4f6aff</a>), closes <a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2368">#2368</a></li>
</ul>
<h1><a href="https://github.com/kulshekhar/ts-jest/compare/v27.0.0-next.5...v27.0.0-next.6">27.0.0-next.6</a> (2021-02-11)</h1>
<h3>Bug Fixes</h3>
<ul>
<li><strong>config:</strong> invalidate Jest transform cache when <code>astTransformers</code> value changes (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2345">#2345</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/d726016a17a26215fad782cf57bb9b9bec807307">d726016</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li><strong>compiler:</strong> expose <code>TsCompiler</code> as public api (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2344">#2344</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/871cd6a3abb10569a04d05f72bbb41c952665ed4">871cd6a</a>)</li>
<li><strong>config:</strong> support typed config options for jest config typescript (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2335">#2335</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/3cfc37b1eba125fe861cea0415095dbe1f538520">3cfc37b</a>)</li>
<li><strong>presets:</strong> add typing for <code>presets</code> entry point (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2337">#2337</a>) (<a href="https://github.com/kulshekhar/ts-jest/commit/1a3058f3b7f8a2e377cb6a7e829cea310a06d4fa">1a3058f</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/f54068b20a58f0390ba3b287cb26b51939f5185e"><code>f54068b</code></a> refactor(config): improve cannot process error message (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2392">#2392</a>)</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/c4e45ac059d4d28366ce3e5af2fd4e4e5f4cd885"><code>c4e45ac</code></a> chore(release): 26.5.2</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/d4f6aff3f181761bf25c64ff1a97dd19a69196f9"><code>d4f6aff</code></a> fix(typings): set correct typing for <code>tsconfig</code>/<code>tsConfig</code> option (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2377">#2377</a>)</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/9034677f9ce0968339d3d942a70e888996fac532"><code>9034677</code></a> fix(compiler): exclude files in <code>outDir</code> from compiler source files (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2376">#2376</a>)</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/c427fea48a24b5ce6e8b9260d3c322583b062a77"><code>c427fea</code></a> fix(config): define <code>matchTestFilePath</code> before <code>setupTsJestCfg</code> (<a href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/2373">#2373</a>)</li>
<li><a href="https://github.com/kulshekhar/ts-jest/commit/f2808bb0b15231c67ccb9a97ed606741213c03e6"><code>f2808bb</code></a> fix(config): improve emit skipped error message and ensure <code>outDir</code> always `T...</li>
<li>See full diff in <a href="https://github.com/kulshekhar/ts-jest/compare/v26.5.1...v26.5.2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ts-jest&package-manager=npm_and_yarn&previous-version=26.5.1&new-version=26.5.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/README.md b/README.md
index 512ed47..97b4557 100644
--- a/README.md
+++ b/README.md
@@ -17,13 +17,15 @@ Warns and then closes issues and PRs that have had no activity for a specified a
 | `stale-pr-message`            | Message to post on the stale PR.                                                                                | Optional |
 | `close-issue-message`         | Message to post on the stale issue while closing it.                                                            | Optional |
 | `close-pr-message`            | Message to post on the stale PR while closing it.                                                               | Optional |
-| `stale-issue-label`           | Label to apply on the stale issue. _Defaults to **stale**_                                                      | Optional |
-| `close-issue-label`           | Label to apply on closing issue.                                                                                | Optional |
-| `stale-pr-label`              | Label to apply on the stale PR.                                                                                 | Optional |
-| `close-pr-label`              | Label to apply on the closing PR.                                                                               | Optional |
+| `stale-issue-label`           | Label to apply on the stale issue. _Defaults to **Stale**_                                                      | Optional |
+| `close-issue-label`           | Label to apply on closing issue (automatically removed if no longer closed nor locked).                         | Optional |
+| `stale-pr-label`              | Label to apply on the stale PR. _Defaults to **Stale**_                                                         | Optional |
+| `close-pr-label`              | Label to apply on the closing PR (automatically removed if no longer closed nor locked).                        | Optional |
 | `exempt-issue-labels`         | Labels on an issue exempted from being marked as stale.                                                         | Optional |
 | `exempt-pr-labels`            | Labels on the PR exempted from being marked as stale.                                                           | Optional |
 | `only-labels`                 | Only labels checked for stale issue/PR.                                                                         | Optional |
+| `only-issue-labels`           | Only labels checked for stale issue (override `only-labels`).                                                   | Optional |
+| `only-pr-labels`              | Only labels checked for stale PR (override `only-labels`).                                                      | Optional |
 | `operations-per-run`          | Maximum number of operations per run (GitHub API CRUD related). _Defaults to **30**_                            | Optional |
 | `remove-stale-when-updated`   | Remove stale label from issue/PR on updates or comments. _Defaults to **true**_                                 | Optional |
 | `debug-only`                  | Dry-run on action. _Defaults to **false**_                                                                      | Optional |
diff --git a/action.yml b/action.yml
index cbf8ade..211470c 100644
--- a/action.yml
+++ b/action.yml
@@ -88,6 +88,14 @@ inputs:
     description: 'Only issues or pull requests with all of these labels are checked if stale. Defaults to `[]` (disabled) and can be a comma-separated list of labels.'
     default: ''
     required: false
+  only-issue-labels:
+    description: 'Only issues with all of these labels are checked if stale. Defaults to `[]` (disabled) and can be a comma-separated list of labels. Override "only-labels" option regarding only the issues.'
+    default: ''
+    required: false
+  only-pr-labels:
+    description: 'Only pull requests with all of these labels are checked if stale. Defaults to `[]` (disabled) and can be a comma-separated list of labels. Override "only-labels" option regarding only the pull requests.'
+    default: ''
+    required: false
   operations-per-run:
     description: 'The maximum number of operations per run, used to control rate limiting (GitHub API CRUD related).'
     default: '30'
diff --git a/dist/index.js b/dist/index.js
index 9465aef..f1c1bdb 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -285,6 +285,23 @@ class IssuesProcessor {
                 const daysBeforeStale = issue.isPullRequest
                     ? this._getDaysBeforePrStale()
                     : this._getDaysBeforeIssueStale();
+                const onlyLabels = words_to_list_1.wordsToList(this._getOnlyLabels(issue));
+                if (onlyLabels.length > 0) {
+                    issueLogger.info(`The option "onlyLabels" was specified to only processed the issues and pull requests with all those labels (${onlyLabels.length})`);
+                    const hasAllWhitelistedLabels = onlyLabels.every((label) => {
+                        return is_labeled_1.isLabeled(issue, label);
+                    });
+                    if (!hasAllWhitelistedLabels) {
+                        issueLogger.info(`Skipping this $$type because it doesn't have all the required labels`);
+                        continue; // Don't process issues without all of the required labels
+                    }
+                    else {
+                        issueLogger.info(`All the required labels are present on this $$type. Continuing the process`);
+                    }
+                }
+                else {
+                    issueLogger.info(`The option "onlyLabels" was not specified. Continuing the process for this $$type`);
+                }
                 issueLogger.info(`Days before $$type stale: ${daysBeforeStale}`);
                 const shouldMarkAsStale = should_mark_when_stale_1.shouldMarkWhenStale(daysBeforeStale);
                 if (!staleMessage && shouldMarkAsStale) {
@@ -299,6 +316,8 @@ class IssuesProcessor {
                     issueLogger.info(`Skipping $$type because it is locked`);
                     continue; // don't process locked issues
                 }
+                // Try to remove the close label when not close/locked issue or PR
+                yield this._removeCloseLabel(issue, closeLabel);
                 if (this.options.startDate) {
                     const startDate = new Date(this.options.startDate);
                     const createdAt = new Date(issue.created_at);
@@ -460,7 +479,6 @@ class IssuesProcessor {
                     owner: github_1.context.repo.owner,
                     repo: github_1.context.repo.repo,
                     state: 'open',
-                    labels: this.options.onlyLabels,
                     per_page: 100,
                     direction: this.options.ascending ? 'asc' : 'desc',
                     page
@@ -674,13 +692,40 @@ class IssuesProcessor {
             ? this.options.daysBeforeClose
             : this.options.daysBeforePrClose;
     }
+    _getOnlyLabels(issue) {
+        if (issue.isPullRequest) {
+            if (this.options.onlyPrLabels !== '') {
+                return this.options.onlyPrLabels;
+            }
+        }
+        else {
+            if (this.options.onlyIssueLabels !== '') {
+                return this.options.onlyIssueLabels;
+            }
+        }
+        return this.options.onlyLabels;
+    }
     _removeStaleLabel(issue, staleLabel) {
         return __awaiter(this, void 0, void 0, function* () {
             const issueLogger = new issue_logger_1.IssueLogger(issue);
-            issueLogger.info(`$$type is no longer stale. Removing stale label.`);
+            issueLogger.info(`The $$type is no longer stale. Removing the stale label...`);
             return this._removeLabel(issue, staleLabel);
         });
     }
+    _removeCloseLabel(issue, closeLabel) {
+        return __awaiter(this, void 0, void 0, function* () {
+            const issueLogger = new issue_logger_1.IssueLogger(issue);
+            issueLogger.info(`The $$type is not closed nor locked. Trying to remove the close label...`);
+            if (!closeLabel) {
+                issueLogger.info(`There is no close label on this $$type. Skip`);
+                return Promise.resolve();
+            }
+            if (is_labeled_1.isLabeled(issue, closeLabel)) {
+                issueLogger.info(`The $$type has a close label "${closeLabel}". Removing the close label...`);
+                return this._removeLabel(issue, closeLabel);
+            }
+        });
+    }
 }
 exports.IssuesProcessor = IssuesProcessor;
 
@@ -1154,6 +1199,8 @@ function _getAndValidateArgs() {
         closePrLabel: core.getInput('close-pr-label'),
         exemptPrLabels: core.getInput('exempt-pr-labels'),
         onlyLabels: core.getInput('only-labels'),
+        onlyIssueLabels: core.getInput('only-issue-labels'),
+        onlyPrLabels: core.getInput('only-pr-labels'),
         operationsPerRun: parseInt(core.getInput('operations-per-run', { required: true })),
         removeStaleWhenUpdated: !(core.getInput('remove-stale-when-updated') === 'false'),
         debugOnly: core.getInput('debug-only') === 'true',
@@ -1206,7 +1253,7 @@ function _toOptionalBoolean(argumentName) {
     }
     return undefined;
 }
-_run();
+void _run();
 
 
 /***/ }),
diff --git a/package-lock.json b/package-lock.json
index 1a4162c..cb14446 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1568,9 +1568,9 @@
       }
     },
     "@octokit/openapi-types": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-4.0.3.tgz",
-      "integrity": "sha512-CXCe1Zzc/WhjpuAEgoUktAinZJ02l6W8q1hDkwBtaonEtO6cjo/3Pyb2J1t5y2q/SvjESDJ77xZ9UVHqQVvihw=="
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-5.2.0.tgz",
+      "integrity": "sha512-MInMij2VK5o96Ei6qaHjxBglSZWOXQs9dTZfnGX2Xnr2mhA+yk9L/QCH4RcJGISJJCBclLHuY3ytq+iRgDfX7w=="
     },
     "@octokit/plugin-paginate-rest": {
       "version": "2.2.4",
@@ -1620,14 +1620,14 @@
       }
     },
     "@octokit/rest": {
-      "version": "18.1.1",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.1.1.tgz",
-      "integrity": "sha512-ZcCHMyfGT1qtJD72usigAfUQ6jU89ZUPFb2AOubR6WZ7/RRFVZUENVm1I2yvJBUicqTujezPW9cY1+o3Mb4rNA==",
+      "version": "18.3.0",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.3.0.tgz",
+      "integrity": "sha512-R45oBVhnq3HAOGVtC6lHY7LX7TGWqbbcD4KvBHoT4QIjgJzfqKag3m/DUJwLnp8xrokz1spZmspTIXiDeQqJSA==",
       "requires": {
         "@octokit/core": "^3.2.3",
         "@octokit/plugin-paginate-rest": "^2.6.2",
         "@octokit/plugin-request-log": "^1.0.2",
-        "@octokit/plugin-rest-endpoint-methods": "4.10.3"
+        "@octokit/plugin-rest-endpoint-methods": "4.13.0"
       },
       "dependencies": {
         "@octokit/auth-token": {
@@ -1662,19 +1662,19 @@
           }
         },
         "@octokit/plugin-paginate-rest": {
-          "version": "2.9.1",
-          "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.9.1.tgz",
-          "integrity": "sha512-8wnuWGjwDIEobbBet2xAjZwgiMVTgIer5wBsnGXzV3lJ4yqphLU2FEMpkhSrDx7y+WkZDfZ+V+1cFMZ1mAaFag==",
+          "version": "2.11.0",
+          "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.11.0.tgz",
+          "integrity": "sha512-7L9xQank2G3r1dGqrVPo1z62V5utbykOUzlmNHPz87Pww/JpZQ9KyG5CHtUzgmB4n5iDRKYNK/86A8D98HP0yA==",
           "requires": {
-            "@octokit/types": "^6.8.0"
+            "@octokit/types": "^6.11.0"
           }
         },
         "@octokit/plugin-rest-endpoint-methods": {
-          "version": "4.10.3",
-          "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.10.3.tgz",
-          "integrity": "sha512-CsNQeVY34Vs9iea2Z9/TCPlebxv6KpjO9f1BUPz+14qundTSYT9kgf8j5wA1k37VstfBQ4xnuURYdnbGzJBJXw==",
+          "version": "4.13.0",
+          "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.13.0.tgz",
+          "integrity": "sha512-Ofusy7BwHkU7z4TNsVdf7wm5W3KR625KqlQj4AiWPnBvclmZU0Y2bVK8b8Mz8nW7sEX9TJcCdX6KeaincE/cLw==",
           "requires": {
-            "@octokit/types": "^6.8.3",
+            "@octokit/types": "^6.11.0",
             "deprecation": "^2.3.1"
           }
         },
@@ -1694,12 +1694,11 @@
           }
         },
         "@octokit/types": {
-          "version": "6.8.4",
-          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.8.4.tgz",
-          "integrity": "sha512-iKAMx//mBk74NwXdeKg8kdYO5zb1n6Ypk5uxwM96U35rJQv4Y8lMQxfzhN8QyzQHaZkxQsl28bn+MPEhiqXb7w==",
+          "version": "6.11.0",
+          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.11.0.tgz",
+          "integrity": "sha512-RMLAmpPZf/a33EsclBazKg02NCCj4rC69V9sUgf0SuWTjmnBD2QC1nIVtJo7RJrGnwG1+aoFBb2yTrWm/8AS7w==",
           "requires": {
-            "@octokit/openapi-types": "^4.0.3",
-            "@types/node": ">= 8"
+            "@octokit/openapi-types": "^5.2.0"
           }
         },
         "is-plain-object": {
@@ -1962,41 +1961,63 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "4.15.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.15.1.tgz",
-      "integrity": "sha512-V8eXYxNJ9QmXi5ETDguB7O9diAXlIyS+e3xzLoP/oVE4WCAjssxLIa0mqCLsCGXulYJUfT+GV70Jv1vHsdKwtA==",
+      "version": "4.15.2",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.15.2.tgz",
+      "integrity": "sha512-SHeF8xbsC6z2FKXsaTb1tBCf0QZsjJ94H6Bo51Y1aVEZ4XAefaw5ZAilMoDPlGghe+qtq7XdTiDlGfVTOmvA+Q==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "4.15.1",
-        "@typescript-eslint/types": "4.15.1",
-        "@typescript-eslint/typescript-estree": "4.15.1",
+        "@typescript-eslint/scope-manager": "4.15.2",
+        "@typescript-eslint/types": "4.15.2",
+        "@typescript-eslint/typescript-estree": "4.15.2",
         "debug": "^4.1.1"
       },
       "dependencies": {
         "@typescript-eslint/scope-manager": {
-          "version": "4.15.1",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.1.tgz",
-          "integrity": "sha512-ibQrTFcAm7yG4C1iwpIYK7vDnFg+fKaZVfvyOm3sNsGAerKfwPVFtYft5EbjzByDJ4dj1WD8/34REJfw/9wdVA==",
+          "version": "4.15.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.2.tgz",
+          "integrity": "sha512-Zm0tf/MSKuX6aeJmuXexgdVyxT9/oJJhaCkijv0DvJVT3ui4zY6XYd6iwIo/8GEZGy43cd7w1rFMiCLHbRzAPQ==",
           "dev": true,
           "requires": {
-            "@typescript-eslint/types": "4.15.1",
-            "@typescript-eslint/visitor-keys": "4.15.1"
+            "@typescript-eslint/types": "4.15.2",
+            "@typescript-eslint/visitor-keys": "4.15.2"
           }
         },
+        "@typescript-eslint/types": {
+          "version": "4.15.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.2.tgz",
+          "integrity": "sha512-r7lW7HFkAarfUylJ2tKndyO9njwSyoy6cpfDKWPX6/ctZA+QyaYscAHXVAfJqtnY6aaTwDYrOhp+ginlbc7HfQ==",
+          "dev": true
+        },
         "@typescript-eslint/typescript-estree": {
-          "version": "4.15.1",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.1.tgz",
-          "integrity": "sha512-z8MN3CicTEumrWAEB2e2CcoZa3KP9+SMYLIA2aM49XW3cWIaiVSOAGq30ffR5XHxRirqE90fgLw3e6WmNx5uNw==",
+          "version": "4.15.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.2.tgz",
+          "integrity": "sha512-cGR8C2g5SPtHTQvAymEODeqx90pJHadWsgTtx6GbnTWKqsg7yp6Eaya9nFzUd4KrKhxdYTTFBiYeTPQaz/l8bw==",
           "dev": true,
           "requires": {
-            "@typescript-eslint/types": "4.15.1",
-            "@typescript-eslint/visitor-keys": "4.15.1",
+            "@typescript-eslint/types": "4.15.2",
+            "@typescript-eslint/visitor-keys": "4.15.2",
             "debug": "^4.1.1",
             "globby": "^11.0.1",
             "is-glob": "^4.0.1",
             "semver": "^7.3.2",
             "tsutils": "^3.17.1"
           }
+        },
+        "@typescript-eslint/visitor-keys": {
+          "version": "4.15.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.2.tgz",
+          "integrity": "sha512-TME1VgSb7wTwgENN5KVj4Nqg25hP8DisXxNBojM4Nn31rYaNDIocNm5cmjOFfh42n7NVERxWrDFoETO/76ePyg==",
+          "dev": true,
+          "requires": {
+            "@typescript-eslint/types": "4.15.2",
+            "eslint-visitor-keys": "^2.0.0"
+          }
+        },
+        "eslint-visitor-keys": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
+          "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
+          "dev": true
         }
       }
     },
@@ -9460,9 +9481,9 @@
       }
     },
     "ts-jest": {
-      "version": "26.5.1",
-      "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.1.tgz",
-      "integrity": "sha512-G7Rmo3OJMvlqE79amJX8VJKDiRcd7/r61wh9fnvvG8cAjhA9edklGw/dCxRSQmfZ/z8NDums5srSVgwZos1qfg==",
+      "version": "26.5.2",
+      "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.2.tgz",
+      "integrity": "sha512-bwyJ2zJieSugf7RB+o8fgkMeoMVMM2KPDE0UklRLuACxjwJsOrZNo6chrcScmK33YavPSwhARffy8dZx5LJdUQ==",
       "dev": true,
       "requires": {
         "@types/jest": "26.x",
@@ -9479,9 +9500,9 @@
       },
       "dependencies": {
         "yargs-parser": {
-          "version": "20.2.5",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz",
-          "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==",
+          "version": "20.2.6",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz",
+          "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==",
           "dev": true
         }
       }
diff --git a/package.json b/package.json
index 40ffdca..52662af 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
   "dependencies": {
     "@actions/core": "^1.2.6",
     "@actions/github": "^4.0.0",
-    "@octokit/rest": "^18.1.1",
+    "@octokit/rest": "^18.3.0",
     "lodash.deburr": "^4.1.0",
     "semver": "^7.3.4"
   },
@@ -42,7 +42,7 @@
     "@types/node": "^14.14.28",
     "@types/semver": "^7.3.4",
     "@typescript-eslint/eslint-plugin": "^4.15.1",
-    "@typescript-eslint/parser": "^4.15.1",
+    "@typescript-eslint/parser": "^4.15.2",
     "@vercel/ncc": "^0.27.0",
     "eslint": "^7.20.0",
     "eslint-plugin-github": "^4.0.1",
@@ -52,7 +52,7 @@
     "jest-silent-reporter": "^0.4.0",
     "js-yaml": "^4.0.0",
     "prettier": "^2.2.1",
-    "ts-jest": "^26.5.1",
+    "ts-jest": "^26.5.2",
     "typescript": "^4.1.5"
   }
 }
diff --git a/src/classes/issue.spec.ts b/src/classes/issue.spec.ts
index 8cbd3d9..8d852b2 100644
--- a/src/classes/issue.spec.ts
+++ b/src/classes/issue.spec.ts
@@ -28,6 +28,8 @@ describe('Issue', (): void => {
       exemptIssueLabels: '',
       exemptPrLabels: '',
       onlyLabels: '',
+      onlyIssueLabels: '',
+      onlyPrLabels: '',
       operationsPerRun: 0,
       removeStaleWhenUpdated: false,
       repoToken: '',
diff --git a/src/classes/issue.ts b/src/classes/issue.ts
index 816de1f..d48add6 100644
--- a/src/classes/issue.ts
+++ b/src/classes/issue.ts
@@ -15,7 +15,7 @@ export class Issue implements IIssue {
   updated_at: IsoDateString;
   readonly labels: ILabel[];
   readonly pull_request: Object | null | undefined;
-  readonly state: string;
+  readonly state: string | 'closed' | 'open';
   readonly locked: boolean;
   readonly milestone: IMilestone | undefined;
   readonly assignees: IAssignee[];
diff --git a/src/classes/issues-processor.ts b/src/classes/issues-processor.ts
index 758950b..cbed3f5 100644
--- a/src/classes/issues-processor.ts
+++ b/src/classes/issues-processor.ts
@@ -120,6 +120,34 @@ export class IssuesProcessor {
       const daysBeforeStale: number = issue.isPullRequest
         ? this._getDaysBeforePrStale()
         : this._getDaysBeforeIssueStale();
+      const onlyLabels: string[] = wordsToList(this._getOnlyLabels(issue));
+
+      if (onlyLabels.length > 0) {
+        issueLogger.info(
+          `The option "onlyLabels" was specified to only processed the issues and pull requests with all those labels (${onlyLabels.length})`
+        );
+
+        const hasAllWhitelistedLabels: boolean = onlyLabels.every(
+          (label: Readonly<string>): boolean => {
+            return isLabeled(issue, label);
+          }
+        );
+
+        if (!hasAllWhitelistedLabels) {
+          issueLogger.info(
+            `Skipping this $$type because it doesn't have all the required labels`
+          );
+          continue; // Don't process issues without all of the required labels
+        } else {
+          issueLogger.info(
+            `All the required labels are present on this $$type. Continuing the process`
+          );
+        }
+      } else {
+        issueLogger.info(
+          `The option "onlyLabels" was not specified. Continuing the process for this $$type`
+        );
+      }
 
       issueLogger.info(`Days before $$type stale: ${daysBeforeStale}`);
 
@@ -140,6 +168,9 @@ export class IssuesProcessor {
         continue; // don't process locked issues
       }
 
+      // Try to remove the close label when not close/locked issue or PR
+      await this._removeCloseLabel(issue, closeLabel);
+
       if (this.options.startDate) {
         const startDate: Date = new Date(this.options.startDate);
         const createdAt: Date = new Date(issue.created_at);
@@ -395,7 +426,6 @@ export class IssuesProcessor {
           owner: context.repo.owner,
           repo: context.repo.repo,
           state: 'open',
-          labels: this.options.onlyLabels,
           per_page: 100,
           direction: this.options.ascending ? 'asc' : 'desc',
           page
@@ -657,14 +687,55 @@ export class IssuesProcessor {
       : this.options.daysBeforePrClose;
   }
 
+  private _getOnlyLabels(issue: Issue): string {
+    if (issue.isPullRequest) {
+      if (this.options.onlyPrLabels !== '') {
+        return this.options.onlyPrLabels;
+      }
+    } else {
+      if (this.options.onlyIssueLabels !== '') {
+        return this.options.onlyIssueLabels;
+      }
+    }
+
+    return this.options.onlyLabels;
+  }
+
   private async _removeStaleLabel(
     issue: Issue,
     staleLabel: Readonly<string>
   ): Promise<void> {
     const issueLogger: IssueLogger = new IssueLogger(issue);
 
-    issueLogger.info(`$$type is no longer stale. Removing stale label.`);
+    issueLogger.info(
+      `The $$type is no longer stale. Removing the stale label...`
+    );
 
     return this._removeLabel(issue, staleLabel);
   }
+
+  private async _removeCloseLabel(
+    issue: Issue,
+    closeLabel: Readonly<string | undefined>
+  ): Promise<void> {
+    const issueLogger: IssueLogger = new IssueLogger(issue);
+
+    issueLogger.info(
+      `The $$type is not closed nor locked. Trying to remove the close label...`
+    );
+
+    if (!closeLabel) {
+      issueLogger.info(`There is no close label on this $$type. Skip`);
+
+      return Promise.resolve();
+    }
+
+    if (isLabeled(issue, closeLabel)) {
+      issueLogger.info(
+        `The $$type has a close label "${closeLabel}". Removing the close label...`
+      );
+
+      return this._removeLabel(issue, closeLabel);
+    }
+  }
 }
diff --git a/src/interfaces/issues-processor-options.ts b/src/interfaces/issues-processor-options.ts
index bb95eba..28027e9 100644
--- a/src/interfaces/issues-processor-options.ts
+++ b/src/interfaces/issues-processor-options.ts
@@ -19,6 +19,8 @@ export interface IIssuesProcessorOptions {
   closePrLabel: string;
   exemptPrLabels: string;
   onlyLabels: string;
+  onlyIssueLabels: string;
+  onlyPrLabels: string;
   operationsPerRun: number;
   removeStaleWhenUpdated: boolean;
   debugOnly: boolean;
diff --git a/src/main.ts b/src/main.ts
index 14e949c..f5dd905 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -39,6 +39,8 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
     closePrLabel: core.getInput('close-pr-label'),
     exemptPrLabels: core.getInput('exempt-pr-labels'),
     onlyLabels: core.getInput('only-labels'),
+    onlyIssueLabels: core.getInput('only-issue-labels'),
+    onlyPrLabels: core.getInput('only-pr-labels'),
     operationsPerRun: parseInt(
       core.getInput('operations-per-run', {required: true})
     ),
@@ -106,4 +108,4 @@ function _toOptionalBoolean(
   return undefined;
 }
 
-_run();
+void _run();


Test patch:
diff --git a/__tests__/constants/default-processor-options.ts b/__tests__/constants/default-processor-options.ts
index 23fe99b..da7b7ca 100644
--- a/__tests__/constants/default-processor-options.ts
+++ b/__tests__/constants/default-processor-options.ts
@@ -19,6 +19,8 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
   closePrLabel: '',
   exemptPrLabels: '',
   onlyLabels: '',
+  onlyIssueLabels: '',
+  onlyPrLabels: '',
   operationsPerRun: 100,
   debugOnly: true,
   removeStaleWhenUpdated: false,
diff --git a/__tests__/main.spec.ts b/__tests__/main.spec.ts
index 46ea62f..fcb5544 100644
--- a/__tests__/main.spec.ts
+++ b/__tests__/main.spec.ts
@@ -2112,3 +2112,111 @@ test('processing a pull request opened since 2 days and with the option "daysBef
   expect(processor.staleIssues.length).toEqual(1);
   expect(processor.closedIssues.length).toEqual(0);
 });
+
+test('processing a previously closed issue with a close label will remove the close label', async () => {
+  expect.assertions(1);
+  const opts: IIssuesProcessorOptions = {
+    ...DefaultProcessorOptions,
+    closeIssueLabel: 'close',
+    staleIssueLabel: 'stale'
+  };
+  const now: Date = new Date();
+  const oneWeekAgo: Date = new Date(now.getDate() - 7);
+  const TestIssueList: Issue[] = [
+    generateIssue(
+      opts,
+      1,
+      'An opened issue with a close label',
+      oneWeekAgo.toDateString(),
+      now.toDateString(),
+      false,
+      ['close'],
+      false,
+      false
+    )
+  ];
+  const processor = new IssuesProcessor(
+    opts,
+    async () => 'abot',
+    async p => (p === 1 ? TestIssueList : []),
+    async () => [],
+    async () => new Date().toDateString()
+  );
+
+  // process our fake issue list
+  await processor.processIssues(1);
+
+  expect(processor.removedLabelIssues).toHaveLength(1);
+});
+
+test('processing a closed issue with a close label will not remove the close label', async () => {
+  expect.assertions(1);
+  const opts: IIssuesProcessorOptions = {
+    ...DefaultProcessorOptions,
+    closeIssueLabel: 'close',
+    staleIssueLabel: 'stale'
+  };
+  const now: Date = new Date();
+  const oneWeekAgo: Date = new Date(now.getDate() - 7);
+  const TestIssueList: Issue[] = [
+    generateIssue(
+      opts,
+      1,
+      'A closed issue with a close label',
+      oneWeekAgo.toDateString(),
+      now.toDateString(),
+      false,
+      ['close'],
+      true,
+      false
+    )
+  ];
+  const processor = new IssuesProcessor(
+    opts,
+    async () => 'abot',
+    async p => (p === 1 ? TestIssueList : []),
+    async () => [],
+    async () => new Date().toDateString()
+  );
+
+  // process our fake issue list
+  await processor.processIssues(1);
+
+  expect(processor.removedLabelIssues).toHaveLength(0);
+});
+
+test('processing a locked issue with a close label will not remove the close label', async () => {
+  expect.assertions(1);
+  const opts: IIssuesProcessorOptions = {
+    ...DefaultProcessorOptions,
+    closeIssueLabel: 'close',
+    staleIssueLabel: 'stale'
+  };
+  const now: Date = new Date();
+  const oneWeekAgo: Date = new Date(now.getDate() - 7);
+  const TestIssueList: Issue[] = [
+    generateIssue(
+      opts,
+      1,
+      'A closed issue with a close label',
+      oneWeekAgo.toDateString(),
+      now.toDateString(),
+      false,
+      ['close'],
+      false,
+      true
+    )
+  ];
+  const processor = new IssuesProcessor(
+    opts,
+    async () => 'abot',
+    async p => (p === 1 ? TestIssueList : []),
+    async () => [],
+    async () => new Date().toDateString()
+  );
+
+  // process our fake issue list
+  await processor.processIssues(1);
+
+  expect(processor.removedLabelIssues).toHaveLength(0);
+});
diff --git a/__tests__/only-labels.spec.ts b/__tests__/only-labels.spec.ts
new file mode 100644
index 0000000..2ca5167
--- /dev/null
+++ b/__tests__/only-labels.spec.ts
@@ -0,0 +1,1152 @@
+import {Issue} from '../src/classes/issue';
+import {IssuesProcessor} from '../src/classes/issues-processor';
+import {IIssue} from '../src/interfaces/issue';
+import {IIssuesProcessorOptions} from '../src/interfaces/issues-processor-options';
+import {DefaultProcessorOptions} from './constants/default-processor-options';
+import {generateIssue} from './functions/generate-issue';
+
+let issuesProcessorBuilder: IssuesProcessorBuilder;
+let issuesProcessor: IssuesProcessor;
+
+describe('only-labels option', (): void => {
+  beforeEach((): void => {
+    issuesProcessorBuilder = new IssuesProcessorBuilder();
+  });
+
+  test('should stale when not set even if the issue has no label', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .emptyOnlyLabels()
+      .issuesOrPrs([{labels: []}])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(1);
+  });
+
+  test('should stale when not set even if the issue has a label', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .emptyOnlyLabels()
+      .issuesOrPrs([{labels: [{name: 'label'}]}])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(1);
+  });
+
+  test('should not stale when set and the issue has no label', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .onlyLabels('dummy-label')
+      .issuesOrPrs([{labels: []}])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(0);
+  });
+
+  test('should not stale when set and the issue has a different label', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .onlyLabels('dummy-label')
+      .issuesOrPrs([
+        {
+          labels: [
+            {
+              name: 'label'
+            }
+          ]
+        }
+      ])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(0);
+  });
+
+  test('should not stale when set and the issue has different labels', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .onlyLabels('dummy-label')
+      .issuesOrPrs([
+        {
+          labels: [
+            {
+              name: 'label-1'
+            },
+            {
+              name: 'label-2'
+            }
+          ]
+        }
+      ])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(0);
+  });
+
+  test('should stale when set and the issue has the same label', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .onlyLabels('dummy-label')
+      .issuesOrPrs([
+        {
+          labels: [
+            {
+              name: 'dummy-label'
+            }
+          ]
+        }
+      ])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(1);
+  });
+
+  test('should not stale when set and the issue has only one of the same label', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .onlyLabels('dummy-label-1,dummy-label-2')
+      .issuesOrPrs([
+        {
+          labels: [
+            {
+              name: 'dummy-label-1'
+            }
+          ]
+        }
+      ])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(0);
+  });
+
+  test('should stale when set and the issue has all the same labels', async (): Promise<void> => {
+    expect.assertions(1);
+    issuesProcessor = issuesProcessorBuilder
+      .onlyLabels('dummy-label-1,dummy-label-2')
+      .issuesOrPrs([
+        {
+          labels: [
+            {
+              name: 'dummy-label-1'
+            },
+            {
+              name: 'dummy-label-2'
+            }
+          ]
+        }
+      ])
+      .build();
+
+    await issuesProcessor.processIssues();
+
+    expect(issuesProcessor.staleIssues).toHaveLength(1);
+  });
+});
+
+describe('only-issue-labels option', (): void => {
+  beforeEach((): void => {
+    issuesProcessorBuilder = new IssuesProcessorBuilder();
+  });
+
+  describe('when the only-labels options is not set', (): void => {
+    beforeEach((): void => {
+      issuesProcessorBuilder.emptyOnlyLabels();
+    });
+
+    test('should stale when not set even if the issue has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyIssueLabels()
+        .issues([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should stale when not set even if the issue has a label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyIssueLabels()
+        .issues([{labels: [{name: 'dummy-label'}]}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the issue has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has a different label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has different labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'label-1'
+              },
+              {
+                name: 'label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the issue has the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the issue has only one of the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label-1,dummy-label-2')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the issue has all the same labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label-1,dummy-label-2')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              },
+              {
+                name: 'dummy-label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+  });
+
+  describe('when the only-labels options is set (same as only-issue-labels)', (): void => {
+    beforeEach((): void => {
+      issuesProcessorBuilder.onlyLabels('dummy-label');
+    });
+
+    test('should not stale when not set even if the issue has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyIssueLabels()
+        .issues([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when not set even if the issue has a label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyIssueLabels()
+        .issues([{labels: [{name: 'label'}]}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has a different label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has different labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'label-1'
+              },
+              {
+                name: 'label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the issue has the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the issue has only one of the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label-1,dummy-label-2')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the issue has all the same labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label-1,dummy-label-2')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              },
+              {
+                name: 'dummy-label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+  });
+
+  describe('when the only-labels options is set (different than only-issue-labels)', (): void => {
+    beforeEach((): void => {
+      issuesProcessorBuilder.onlyLabels('dummy-only-label');
+    });
+
+    test('should not stale when not set even if the issue has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyIssueLabels()
+        .issues([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when not set even if the issue has a label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyIssueLabels()
+        .issues([{labels: [{name: 'label'}]}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has a different label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the issue has different labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'label-1'
+              },
+              {
+                name: 'label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the issue has the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the issue has only one of the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label-1,dummy-label-2')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the issue has all the same labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyIssueLabels('dummy-label-1,dummy-label-2')
+        .issues([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              },
+              {
+                name: 'dummy-label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+  });
+});
+
+describe('only-pr-labels option', (): void => {
+  beforeEach((): void => {
+    issuesProcessorBuilder = new IssuesProcessorBuilder();
+  });
+
+  describe('when the only-labels options is not set', (): void => {
+    beforeEach((): void => {
+      issuesProcessorBuilder.emptyOnlyLabels();
+    });
+
+    test('should stale when not set even if the pr has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyPrLabels()
+        .prs([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should stale when not set even if the pr has a label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyPrLabels()
+        .prs([{labels: [{name: 'dummy-label'}]}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the pr has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has a different label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has different labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'label-1'
+              },
+              {
+                name: 'label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the pr has the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the pr has only one of the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label-1,dummy-label-2')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the pr has all the same labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label-1,dummy-label-2')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              },
+              {
+                name: 'dummy-label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+  });
+
+  describe('when the only-labels options is set (same as only-pr-labels)', (): void => {
+    beforeEach((): void => {
+      issuesProcessorBuilder.onlyLabels('dummy-label');
+    });
+
+    test('should not stale when not set even if the pr has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyPrLabels()
+        .prs([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when not set even if the pr has a label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyPrLabels()
+        .prs([{labels: [{name: 'label'}]}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has a different label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has different labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'label-1'
+              },
+              {
+                name: 'label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the pr has the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the pr has only one of the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label-1,dummy-label-2')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the pr has all the same labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label-1,dummy-label-2')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              },
+              {
+                name: 'dummy-label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+  });
+
+  describe('when the only-labels options is set (different than only-pr-labels)', (): void => {
+    beforeEach((): void => {
+      issuesProcessorBuilder.onlyLabels('dummy-only-label');
+    });
+
+    test('should not stale when not set even if the pr has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyPrLabels()
+        .prs([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when not set even if the pr has a label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .emptyOnlyPrLabels()
+        .prs([{labels: [{name: 'label'}]}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has no label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([{labels: []}])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has a different label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should not stale when set and the pr has different labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'label-1'
+              },
+              {
+                name: 'label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the pr has the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+
+    test('should not stale when set and the pr has only one of the same label', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label-1,dummy-label-2')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(0);
+    });
+
+    test('should stale when set and the pr has all the same labels', async (): Promise<void> => {
+      expect.assertions(1);
+      issuesProcessor = issuesProcessorBuilder
+        .onlyPrLabels('dummy-label-1,dummy-label-2')
+        .prs([
+          {
+            labels: [
+              {
+                name: 'dummy-label-1'
+              },
+              {
+                name: 'dummy-label-2'
+              }
+            ]
+          }
+        ])
+        .build();
+
+      await issuesProcessor.processIssues();
+
+      expect(issuesProcessor.staleIssues).toHaveLength(1);
+    });
+  });
+});
+
+class IssuesProcessorBuilder {
+  private _options: IIssuesProcessorOptions = {
+    ...DefaultProcessorOptions,
+    daysBeforeStale: 0
+  };
+  private _issues: Issue[] = [];
+
+  onlyLabels(labels: string): IssuesProcessorBuilder {
+    this._options.onlyLabels = labels;
+
+    return this;
+  }
+
+  onlyIssueLabels(labels: string): IssuesProcessorBuilder {
+    this._options.onlyIssueLabels = labels;
+
+    return this;
+  }
+
+  onlyPrLabels(labels: string): IssuesProcessorBuilder {
+    this._options.onlyPrLabels = labels;
+
+    return this;
+  }
+
+  emptyOnlyLabels(): IssuesProcessorBuilder {
+    return this.onlyLabels('');
+  }
+
+  emptyOnlyIssueLabels(): IssuesProcessorBuilder {
+    return this.onlyIssueLabels('');
+  }
+
+  emptyOnlyPrLabels(): IssuesProcessorBuilder {
+    return this.onlyPrLabels('');
+  }
+
+  issuesOrPrs(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
+    this._issues = issues.map(
+      (issue: Readonly<Partial<IIssue>>, index: Readonly<number>): Issue =>
+        generateIssue(
+          this._options,
+          index,
+          issue.title ?? 'dummy-title',
+          issue.updated_at ?? new Date().toDateString(),
+          issue.created_at ?? new Date().toDateString(),
+          !!issue.pull_request,
+          issue.labels ? issue.labels.map(label => label.name) : []
+        )
+    );
+
+    return this;
+  }
+
+  issues(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
+    this.issuesOrPrs(
+      issues.map(
+        (issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
+          return {
+            ...issue,
+            pull_request: null
+          };
+        }
+      )
+    );
+
+    return this;
+  }
+
+  prs(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
+    this.issuesOrPrs(
+      issues.map(
+        (issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
+          return {
+            ...issue,
+            pull_request: {key: 'value'}
+          };
+        }
+      )
+    );
+
+    return this;
+  }
+
+  build(): IssuesProcessor {
+    return new IssuesProcessor(
+      this._options,
+      async () => 'abot',
+      async p => (p === 1 ? this._issues : []),
+      async () => [],
+      async () => new Date().toDateString()
+    );
+  }
+}