Complete coveralls/sonarqube/snyk backend quality integration
swadhinbiswas committed 8 months ago
4e7efaa
1 parent 2b09e30
commit 4e7efaa
1 file changed
+25 -1
Showing 1 changed file+25-1
▼src/lib/code-quality.ts
+25-1
| @@ -9,6 +9,7 @@ import { eq, and, desc } from "drizzle-orm"; | ||
9 | 9 | import { logger } from "./logger"; |
10 | 10 | import { repositories } from "@/db/schema/repositories"; |
11 | 11 | import { pullRequests } from "@/db/schema/pull-requests"; |
12 | +import { assertOnlineFeature } from "./air-gapped"; | |
12 | 13 | |
13 | 14 | // ============================================================================ |
14 | 15 | // SCHEMA DEFINITIONS |
| @@ -183,6 +184,7 @@ export async function processCodecovWebhook(payload: { | ||
183 | 184 | totals: { coverage: number; lines: number; hits: number }; |
184 | 185 | pull?: { pullid: number }; |
185 | 186 | }): Promise<CoverageReport> { |
187 | + assertOnlineFeature("Codecov integration"); | |
186 | 188 | const db = getDatabase(); |
187 | 189 | |
188 | 190 | const repo = await db.query.repositories.findFirst({ |
| @@ -238,6 +240,7 @@ export async function fetchCodecovCoverage(options: { | ||
238 | 240 | commitSha: string; |
239 | 241 | token: string; |
240 | 242 | }): Promise<{ coverage: number; url: string } | null> { |
243 | + assertOnlineFeature("Codecov integration"); | |
241 | 244 | try { |
242 | 245 | const response = await fetch( |
243 | 246 | `https://codecov.io/api/v2/github/${options.owner}/repos/${options.repo}/commits/${options.commitSha}`, |
| @@ -271,7 +274,9 @@ export async function processCoverallsWebhook(payload: { | ||
271 | 274 | covered_percent: number; |
272 | 275 | covered_lines: number; |
273 | 276 | relevant_lines: number; |
277 | + pull_request_number?: number; | |
274 | 278 | }): Promise<CoverageReport> { |
279 | + assertOnlineFeature("Coveralls integration"); | |
275 | 280 | const db = getDatabase(); |
276 | 281 | |
277 | 282 | const repo = await db.query.repositories.findFirst({ |
| @@ -283,7 +288,7 @@ export async function processCoverallsWebhook(payload: { | ||
283 | 288 | const report = { |
284 | 289 | id: crypto.randomUUID(), |
285 | 290 | repositoryId: repo.id, |
286 | - pullRequestId: null, | |
291 | + pullRequestId: null as string | null, | |
287 | 292 | commitSha: payload.commit_sha, |
288 | 293 | provider: "coveralls", |
289 | 294 | coverage: payload.covered_percent, |
| @@ -296,9 +301,23 @@ export async function processCoverallsWebhook(payload: { | ||
296 | 301 | createdAt: new Date(), |
297 | 302 | }; |
298 | 303 | |
304 | + if (typeof payload.pull_request_number === "number") { | |
305 | + const pr = await db.query.pullRequests.findFirst({ | |
306 | + where: and( | |
307 | + eq(schema.pullRequests.repositoryId, repo.id), | |
308 | + eq(schema.pullRequests.number, payload.pull_request_number) | |
309 | + ), | |
310 | + }); | |
311 | + if (pr) report.pullRequestId = pr.id; | |
312 | + } | |
313 | + | |
299 | 314 | // @ts-expect-error - Drizzle multi-db union type issue |
300 | 315 | await db.insert(schema.coverageReports).values(report); |
301 | 316 | |
317 | + if (report.pullRequestId) { | |
318 | + await updatePRCoverageCheck(report.pullRequestId, report as CoverageReport); | |
319 | + } | |
320 | + | |
302 | 321 | return report as CoverageReport; |
303 | 322 | } |
304 | 323 | |
| @@ -315,6 +334,7 @@ export async function triggerSonarAnalysis(options: { | ||
315 | 334 | branch?: string; |
316 | 335 | pullRequestId?: string; |
317 | 336 | }): Promise<boolean> { |
337 | + assertOnlineFeature("SonarQube integration"); | |
318 | 338 | const db = getDatabase(); |
319 | 339 | |
320 | 340 | const config = await db.query.codeQualityConfigs?.findFirst({ |
| @@ -395,6 +415,7 @@ export async function fetchSonarQubeStatus(options: { | ||
395 | 415 | status: "OK" | "WARN" | "ERROR"; |
396 | 416 | issues: CodeQualityIssue[]; |
397 | 417 | } | null> { |
418 | + assertOnlineFeature("SonarQube integration"); | |
398 | 419 | try { |
399 | 420 | const response = await fetch( |
400 | 421 | `${options.serverUrl}/api/qualitygates/project_status?projectKey=${options.projectKey}`, |
| @@ -457,6 +478,7 @@ export async function runSnykScan(options: { | ||
457 | 478 | apiToken: string; |
458 | 479 | targetFile?: string; |
459 | 480 | }): Promise<CodeQualityIssue[]> { |
481 | + assertOnlineFeature("Snyk integration"); | |
460 | 482 | const db = getDatabase(); |
461 | 483 | const issues: CodeQualityIssue[] = []; |
462 | 484 | |
| @@ -538,6 +560,7 @@ export async function getSnykVulnerabilities(options: { | ||
538 | 560 | cve?: string; |
539 | 561 | fixedIn?: string; |
540 | 562 | }[]> { |
563 | + assertOnlineFeature("Snyk integration"); | |
541 | 564 | try { |
542 | 565 | const response = await fetch( |
543 | 566 | `https://api.snyk.io/v1/vuln/${options.packageManager}/${encodeURIComponent(options.packageName)}/${options.version}`, |
| @@ -660,6 +683,7 @@ export async function handleQualityWebhook( | ||
660 | 683 | webhookSecret: string, |
661 | 684 | payload: Record<string, unknown> |
662 | 685 | ): Promise<boolean> { |
686 | + assertOnlineFeature("Code quality webhooks"); | |
663 | 687 | const db = getDatabase(); |
664 | 688 | |
665 | 689 | const config = await db.query.codeQualityConfigs?.findFirst({ |
666 | 690 | |