diff --git a/e2es/testData/repos.json b/e2es/testData/repos.json
index 40e3595..595a6a7 100644
--- a/e2es/testData/repos.json
+++ b/e2es/testData/repos.json
@@ -13,7 +13,8 @@
"topics": ["composer", "govpress", "packagist", "php"],
"openIssues": 0,
"dependencies": [],
- "openPrsCount": 0
+ "openPrsCount": 0,
+ "openBotPrCount": 0
},
{
"name": "govuk-blogs",
@@ -27,7 +28,8 @@
"topics": ["govpress", "wordpress-theme"],
"openIssues": 1,
"dependencies": [],
- "openPrsCount": 0
+ "openPrsCount": 0,
+ "openBotPrCount": 1
},
{
"name": "php-missing",
@@ -41,7 +43,8 @@
"topics": ["composer", "govpress", "packagist", "php"],
"openIssues": 7,
"dependencies": [],
- "openPrsCount": 2
+ "openPrsCount": 2,
+ "openBotPrCount": 3
}
]
}
diff --git a/index.njk b/index.njk
index db6f739..91fd518 100644
--- a/index.njk
+++ b/index.njk
@@ -37,7 +37,8 @@
Language |
Topics |
{{macros.sortableTableHeader("Open issues count", "openIssues", sortDirection, sortBy)}}
- {{macros.sortableTableHeader("Open PRs count", "openPrsCount", sortDirection, sortBy)}}
+ {{macros.sortableTableHeader("Bot PR count", "openBotPrCount", sortDirection, sortBy)}}
+ {{macros.sortableTableHeader("Open PR count", "openPrCount", sortDirection, sortBy)}}
{{macros.sortableTableHeader("Updated at", "updatedAt", sortDirection, sortBy)}}
Dependencies |
@@ -50,7 +51,8 @@
{{ repo.language }} |
{{ repo.topics | join(", ")}} |
{{ repo.openIssues }} |
- {{ repo.openPrsCount }} |
+ {{ repo.openBotPrCount }} |
+ {{ repo.openPrCount }} |
{{ repo.updatedAt }} |
{% if repo.dependencies.length %}
diff --git a/utils/githubApi/fetchOpenPrs.js b/utils/githubApi/fetchOpenPrs.js
index b724770..cc77fe7 100644
--- a/utils/githubApi/fetchOpenPrs.js
+++ b/utils/githubApi/fetchOpenPrs.js
@@ -8,11 +8,20 @@ export const getOpenPRsForRepo = async ({ octokit, repository }) => {
return octokit.request(repository.pulls_url).then(handlePrsApiResponse);
};
+const depdencyUpdateBots = ["renovate[bot]", "dependabot[bot]"];
+
/**
* Returns the length of the PRs array or 0 if there are no PRs
* @param {any} {data}
* @returns {number}
*/
export const handlePrsApiResponse = ({ data }) => {
- return { openPrCount: data?.length || 0 };
+ const openBotPrCount = data.reduce((acc, pr) => {
+ if (depdencyUpdateBots.includes(pr?.user?.login)) {
+ return acc + 1;
+ }
+ return acc;
+ }, 0);
+
+ return { openPrCount: data?.length || 0, openBotPrCount };
};
diff --git a/utils/githubApi/fetchOpenPrs.test.js b/utils/githubApi/fetchOpenPrs.test.js
index 3439cbb..4f02ee4 100644
--- a/utils/githubApi/fetchOpenPrs.test.js
+++ b/utils/githubApi/fetchOpenPrs.test.js
@@ -2,20 +2,66 @@ import { describe, it } from "node:test";
import expect from "node:assert";
import { handlePrsApiResponse } from "./fetchOpenPrs.js";
-describe("handlePrsApiResponse", () => {
+describe.only("handlePrsApiResponse", () => {
describe("openPRCount", () => {
it("returns the length of the array containing PRs", () => {
const actual = handlePrsApiResponse({ data: [1, 2, 3] });
- const expected = { openCount: 3 };
+ const expected = { openPrCount: 3, openBotPrCount: 0 };
expect.deepEqual(actual, expected);
});
it("returns 0 if there are no open PRs", () => {
const actual = handlePrsApiResponse({ data: [] });
- const expected = { openCount: 0 };
+ const expected = { openPrCount: 0, openBotPrCount: 0 };
- expect.equal(actual, expected);
+ expect.deepEqual(actual, expected);
+ });
+ });
+
+ describe("openBotPrCount", () => {
+ it("returns 1 if there is a PR authored by dependabot", () => {
+ const dependabotPr = { user: { login: "dependabot[bot]" } };
+ const actual = handlePrsApiResponse({ data: [dependabotPr] });
+
+ expect.equal(actual.openBotPrCount, 1);
+ });
+
+ it("returns 1 if there is a PR authored by renovate", () => {
+ const renovatePr = { user: { login: "renovate[bot]" } };
+ const actual = handlePrsApiResponse({ data: [renovatePr] });
+
+ expect.equal(actual.openBotPrCount, 1);
+ });
+
+ it("returns 0 if there is a PR authored by other authors", () => {
+ const humanPr = { user: { login: "rich" } };
+ const actual = handlePrsApiResponse({ data: [humanPr] });
+
+ expect.equal(actual.openBotPrCount, 0);
+ });
+
+ it("handles a variety of PR authors correctly", () => {
+ const dependabotPr = {
+ user: {
+ login: "dependabot[bot]",
+ },
+ };
+ const renovatePr = {
+ user: {
+ login: "renovate[bot]",
+ },
+ };
+ const humanPr = {
+ user: {
+ login: "rich",
+ },
+ };
+ const actual = handlePrsApiResponse({
+ data: [dependabotPr, renovatePr, humanPr],
+ });
+
+ expect.equal(actual.openBotPrCount, 2);
});
});
});
diff --git a/utils/sorting.js b/utils/sorting.js
index 366fa46..3f2f175 100644
--- a/utils/sorting.js
+++ b/utils/sorting.js
@@ -41,15 +41,18 @@ export const sortByUpdatedAt = (repos, sortDirection) => {
/**
* Sorts repositories based on the specified type and direction.
- * @param {"openPrsCount"|"openIssues"} sortBy - The type of sorting to apply, either by open PRs count or open issues.
+ * @param {"openPrCount"|"openBotPrCount"|"openIssues"|} sortBy - The type of sorting to apply, either by open PRs count or open issues.
* @param {SortDirection} sortDirection - The direction to sort, either "asc" for ascending or "desc" for descending.
* @param {UiRepo[]} repos - An array of repository objects to sort.
* @returns {UiRepo[]} The sorted array of repository objects.
*/
export const sortByType = (repos, sortDirection, sortBy) => {
switch (sortBy) {
- case "openPrsCount":
- return sortByNumericValue(repos, sortDirection, "openPrsCount");
+ case "openPrCount":
+ return sortByNumericValue(repos, sortDirection, "openPrCount");
+
+ case "openBotPrCount":
+ return sortByNumericValue(repos, sortDirection, "openBotPrCount");
case "openIssues":
return sortByNumericValue(repos, sortDirection, "openIssues");