Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 228d387

Browse files
authored
feat: run checks regularly on a schedule (#235)
1 parent 64375fc commit 228d387

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ GITHUB_SECRET=
1010
DATABASE_URL="postgresql://user:password@localhost:5432/healthcheck?schema=public"
1111

1212
NEXT_PUBLIC_GITHUB_CACHE=4
13+
API_TOKEN=abcdefg

.github/workflows/checks.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Run checks
2+
permissions: read-all
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: 0 3 * * *
7+
jobs:
8+
api:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: hit api
12+
uses: fjogeleit/http-request-action@v1
13+
with:
14+
url: "https://healthcheck.eddiehubcommunity.org/api/system/checks?token=${{ secrets.API_TOKEN }}"

src/app/api/system/checks/route.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { differenceInHours } from "date-fns";
2+
3+
import prisma from "@/models/db";
4+
import getAllRepoData from "@/utils/github";
5+
import checks from "@/utils/checks";
6+
7+
export const dynamic = "force-dynamic";
8+
9+
export async function GET(request, { params }) {
10+
// protect for system calls only with valid token
11+
if (request.nextUrl.searchParams.get("token") !== process.env.API_TOKEN) {
12+
return Response.json({ error: "permission denied" }, { status: 401 });
13+
}
14+
15+
// get all repositories
16+
const repos = await prisma.repository.findMany({
17+
include: {
18+
checks: {
19+
orderBy: {
20+
createdAt: "desc",
21+
},
22+
take: 1,
23+
},
24+
user: {
25+
include: {
26+
accounts: true,
27+
},
28+
},
29+
},
30+
});
31+
32+
// filter out repositories that had checks in the last X hours
33+
let repoStatus = { ignore: [], run: [] };
34+
repos.forEach((repo) => {
35+
if (
36+
!repo.checks[0] ||
37+
differenceInHours(new Date(), repo.checks[0].createdAt) >= 24 * 7 // TODO: move to Flagsmith
38+
) {
39+
repoStatus.run.push({
40+
id: repo.id,
41+
url: repo.url,
42+
token: repo.user.accounts[0].access_token,
43+
lastChecked: repo.checks[0].createdAt,
44+
});
45+
} else {
46+
repoStatus.ignore.push({
47+
id: repo.id,
48+
url: repo.url,
49+
lastChecked: repo.checks[0].createdAt,
50+
});
51+
}
52+
});
53+
54+
// perform checks on these repositories
55+
// use the owners github token (repository->user->account.access_token)
56+
let runs = [];
57+
repoStatus.run.map(async (repo) => {
58+
const responses = await getAllRepoData(repo.url, repo.token);
59+
60+
// save github api data
61+
const githubResponseRepo = await prisma.githubResponse.create({
62+
data: {
63+
repository: {
64+
connect: {
65+
id: repo.id,
66+
},
67+
},
68+
...responses,
69+
},
70+
});
71+
72+
// perform check
73+
const results = checks(githubResponseRepo);
74+
75+
// save results
76+
await prisma.check.create({
77+
data: {
78+
repository: {
79+
connect: { id: repo.id },
80+
},
81+
githubResponse: {
82+
connect: { id: githubResponseRepo.id },
83+
},
84+
red: results.summary.error?.length || 0,
85+
amber: results.summary.warning?.length || 0,
86+
green: results.summary.success?.length || 0,
87+
healthchecks: results.checks.map((check) => check.id),
88+
data: results.checks,
89+
allData: results.allChecks,
90+
ignoreChecks: results.ignoreChecks,
91+
},
92+
});
93+
94+
runs.push({ url: repo.url });
95+
});
96+
97+
console.log(runs);
98+
99+
return Response.json(runs);
100+
}

0 commit comments

Comments
 (0)