| 1 | /** |
| 2 | * Which routine event a system event is, and what makes it the same thing |
| 3 | * twice. Pure, so it is tested on its own (triggers.ts runs routines). |
| 4 | */ |
| 5 | import type { G1tEvent, RoutineEvent } from "@g1t/contracts"; |
| 6 | |
| 7 | export type Happened = { kind: RoutineEvent; repoId: string; key: string; number: number | null; data: Record<string, unknown> }; |
| 8 | |
| 9 | /** The routine event an event is, if any, and what makes it the same thing twice. */ |
| 10 | export function happened(event: Pick<G1tEvent, "type" | "repoId" | "data">): Happened | null { |
| 11 | const data = (event.data ?? {}) as Record<string, unknown>; |
| 12 | const repoId = (typeof data.repoId === "string" ? data.repoId : null) ?? event.repoId; |
| 13 | if (!repoId) return null; |
| 14 | const number = typeof data.number === "number" ? data.number : null; |
| 15 | switch (event.type) { |
| 16 | case "pull.opened": |
| 17 | case "pull.ready": |
| 18 | return number == null ? null : { kind: "pull_ready", repoId, key: `pull_ready:${repoId}:${number}`, number, data }; |
| 19 | case "pull.merged": |
| 20 | return number == null ? null : { kind: "pull_merged", repoId, key: `pull_merged:${repoId}:${number}`, number, data }; |
| 21 | case "checks.completed": { |
| 22 | const status = data.status; |
| 23 | if (number == null || (status !== "failed" && status !== "errored")) return null; |
| 24 | return { kind: "checks_failed", repoId, key: `checks_failed:${repoId}:${number}:${String(data.commit ?? "")}`, number, data }; |
| 25 | } |
| 26 | case "issue.opened": |
| 27 | return number == null ? null : { kind: "issue_opened", repoId, key: `issue_opened:${repoId}:${number}`, number, data }; |
| 28 | case "deployment.failed": |
| 29 | return { kind: "deploy_failed", repoId, key: `deploy_failed:${String(data.deploymentId ?? "")}`, number, data }; |
| 30 | default: |
| 31 | return null; |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | /** Whether a routine follows this repository: all of them, or it is on its list. */ |
| 36 | export function follows(repos: string[], full: string): boolean { |
| 37 | return !repos.length || repos.includes(full.toLowerCase()); |
| 38 | } |
| 39 | |