Skip to content

Commit

Permalink
Merge pull request #31 from dxw/add-open-prs
Browse files Browse the repository at this point in the history
Add open PRs to dashboard
  • Loading branch information
richpjames authored Sep 13, 2024
2 parents c4a0da0 + d331b2d commit 58dc14b
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 22 deletions.
2 changes: 2 additions & 0 deletions index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<th class="py-2 pl-2" scope="col">Language</th>
<th class="py-2 pl-2" scope="col">Topics</th>
<th class="py-2 pl-2" scope="col">Open issues count</th>
<th class="py-2 pl-2" scope="col">Open PRs count</th>
<th class="py-2 pl-2 last:pr-2" scope="col">Last updated</th>
<th class="py-2 pl-2 last:pr-2" scope="col">Dependencies</th>
</tr>
Expand All @@ -47,6 +48,7 @@
<td class="py-2 pl-2">{{ repo.language }}</td>
<td class="py-2 pl-2">{{ repo.topics | join(", ")}}</td>
<td class="py-2 pl-2">{{ repo.openIssues }}</td>
<td class="py-2 pl-2">{{ repo.openPrsCount }}</td>
<td class="py-2 pl-2 last:pr-2">{{ repo.updatedAt }}</td>

{% if repo.dependencies.length %}
Expand Down
22 changes: 17 additions & 5 deletions dataScripts/fetchAllRepos.js → utils/githubApi/fetchAllRepos.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import { OctokitApp } from "../octokitApp.js";
import { OctokitApp } from "../../octokitApp.js";
import { writeFile, mkdir } from "fs/promises";
import { mapRepoFromApiForStorage } from "../utils.js";
import path from "path";
import { getDependenciesForRepo } from "../renovate/dependencyDashboard.js";
import {
getDependenciesForRepo,
getOpenPRsForRepo,
} from "../renovate/dependencyDashboard.js";

const fetchAllRepos = async () => {
const repos = [];

await OctokitApp.app.eachRepository(async ({ repository, octokit }) => {
if (repository.archived) return;

repository.dependencies = await getDependenciesForRepo({
repository,
octokit,
await Promise.all([
await getDependenciesForRepo({
repository,
octokit,
}),
await getOpenPRsForRepo({
repository,
octokit,
}),
]).then(([dependencies, openPrsCount]) => {
repository.dependencies = dependencies;
repository.openPrsCount = openPrsCount;
});

repos.push(mapRepoFromApiForStorage(repository));
Expand Down
5 changes: 5 additions & 0 deletions utils/githubApi/fetchOpenPrs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const getOpenPRsForRepo = ({ octokit, repository }) => {
return octokit.request(repository.pulls_url).then(handlePrsApiResponse);
};

export const handlePrsApiResponse = ({ data }) => data?.length || 0;
13 changes: 13 additions & 0 deletions utils/githubApi/fetchOpenPrs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { describe, it } from "node:test";
import expect from "node:assert";
import { handlePrsApiResponse } from "./fetchOpenPrs.js";

describe("handlePrsApiResponse", () => {
it("returns the length of the array containing PRs", () => {
expect.equal(handlePrsApiResponse({ data: [1, 2, 3] }), 3);
});

it("returns 0 if there are no open PRs", () => {
expect.equal(handlePrsApiResponse({ data: undefined }), 0);
});
});
1 change: 1 addition & 0 deletions utils.js → utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,5 @@ export const mapRepoFromApiForStorage = (repo) => ({
topics: repo.topics,
openIssues: repo.open_issues,
dependencies: repo.dependencies,
openPrsCount: repo.openPrsCount,
});
4 changes: 3 additions & 1 deletion utils.test.js → utils/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it } from "node:test";
import expect from "node:assert";
import { mapRepoFromStorageToUi, mapRepoFromApiForStorage } from "./utils.js";
import { mapRepoFromStorageToUi, mapRepoFromApiForStorage } from "./index.js";

describe("mapRepoFromStorageToUi", () => {
it("converts the ISO8601 date to a human-readable date", () => {
Expand Down Expand Up @@ -253,6 +253,7 @@ describe("mapRepoFromStorageToUi", () => {
pull: false,
},
dependencies: repoDependencies,
openPrsCount: 0,
};

const repoToSave = {
Expand All @@ -270,6 +271,7 @@ describe("mapRepoFromStorageToUi", () => {
topics: ["delivery-plus", "internal", "tech-ops"],
openIssues: 2,
dependencies: repoDependencies,
openPrsCount: 0,
};

expect.deepEqual(mapRepoFromApiForStorage(apiRepo), repoToSave);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ const LINE_SEPARATOR_REGEX = /\r?\n|\r|\n/g;
// Group 2: ^7.20.2
const DEPENDENCY_NAME_AND_VERSION_REGEX = /`(\S+?) (.*)`/;

const issueIsRenovateDependencyDashboard = (issue) => issue.user.login === "renovate[bot]" && issue.pull_request === undefined;
const issueIsRenovateDependencyDashboard = (issue) =>
issue.user.login === "renovate[bot]" && issue.pull_request === undefined;

const parseDependenciesFromDashboard = (issue) => issue
.body
.split(LINE_SEPARATOR_REGEX)
.map(parseDependencyFromLine)
.filter((dependency) => dependency !== null);
const parseDependenciesFromDashboard = (issue) =>
issue.body
.split(LINE_SEPARATOR_REGEX)
.map(parseDependencyFromLine)
.filter((dependency) => dependency !== null);

const parseDependencyFromLine = (line) => {
const match = line.match(DEPENDENCY_NAME_AND_VERSION_REGEX);
Expand All @@ -41,18 +42,20 @@ const parseDependencyFromLine = (line) => {
}

return new Dependency(match[1], match[2]);
}
};

export const handleIssuesApiResponse = (response) => {
const dependencyDashboardIssue = response.data.find(issueIsRenovateDependencyDashboard);
const dependencyDashboardIssue = response.data.find(
issueIsRenovateDependencyDashboard
);

if (!dependencyDashboardIssue) {
return [];
}

return parseDependenciesFromDashboard(dependencyDashboardIssue);
}
};

export const getDependenciesForRepo = ({ octokit, repository }) => {
return octokit.request(repository.issues_url).then(handleIssuesApiResponse);
};

Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ describe("handleIssuesApiResponse", () => {
user: {
login: "renovate[bot]",
},
body: "# Dependency Dashboard\nList of dependencies:\n- `libquux v4.1.1.rc4`\n- `@xyzzy/utils \"~> 22.04 Questing Quokka\"`\n\nHere's some more:\n- `baz-framework ^0.1`",
}
]
body: '# Dependency Dashboard\nList of dependencies:\n- `libquux v4.1.1.rc4`\n- `@xyzzy/utils "~> 22.04 Questing Quokka"`\n\nHere\'s some more:\n- `baz-framework ^0.1`',
},
],
};

const expectedDependencies = [
Expand All @@ -37,7 +37,7 @@ describe("handleIssuesApiResponse", () => {

expect.deepEqual(
handleIssuesApiResponse(issuesApiResponse),
expectedDependencies,
expectedDependencies
);
});

Expand All @@ -58,14 +58,14 @@ describe("handleIssuesApiResponse", () => {
pull_request: {},
body: "Configure Renovate",
},
]
],
};

const expectedDependencies = [];

expect.deepEqual(
handleIssuesApiResponse(issuesApiResponse),
expectedDependencies,
expectedDependencies
);
});
});

0 comments on commit 58dc14b

Please sign in to comment.