import { loadRepoById } from "../repos"; import { loadPull } from "../pulls"; import { toExprValue } from "./event-triggers"; import type { CompileInput } from "./compile"; import type { ExprValue } from "./expressions"; import type { WorkflowRunRow } from "./jobs"; import type { Trigger, TriggerEvent } from "./triggers"; import type { RepoRow, Viewer } from "~/lib/types"; const EVENTS: TriggerEvent[] = [ "push", "pull_request", "release", "workflow_dispatch", "schedule", "issues", "issue_comment", "pull_request_review", "workflow_run", "create", "delete", ]; function isTriggerEvent(value: string): value is TriggerEvent { return (EVENTS as string[]).includes(value); } function storedEvent(runRow: WorkflowRunRow): Record { if (!runRow.context) return {}; const context: CompileInput = JSON.parse(runRow.context); const event = toExprValue(context.event.event); return event && typeof event === "object" && !Array.isArray(event) ? event : {}; } /** Rebuilds a run's trigger (event, ref, payload and inputs) so a re-run sees the same `github` context. */ export async function rerunTrigger(repo: RepoRow, runRow: WorkflowRunRow, viewer: Viewer): Promise { const sourceRepo = (await loadRepoById(runRow.source_repo_id)) ?? repo; const pull = runRow.pr_number ? await loadPull(repo.id, runRow.pr_number) : null; const event = isTriggerEvent(runRow.event) ? runRow.event : "push"; const payload = storedEvent(runRow); const action = typeof payload.action === "string" && payload.action ? payload.action : null; const inputs = payload.inputs && typeof payload.inputs === "object" && !Array.isArray(payload.inputs) ? payload.inputs : {}; return { event, action: action ?? (event === "pull_request" ? "synchronize" : event === "release" ? "published" : null), ref: runRow.ref, sha: runRow.sha, actorId: viewer.id, actorName: viewer.name, title: runRow.title, prNumber: runRow.pr_number, headRef: pull?.head_ref ?? null, baseRef: pull?.base_ref ?? null, changedPaths: null, inputs, workflowPath: runRow.workflow_path, sourceRepo, payload, depth: runRow.trigger_depth, cron: typeof payload.schedule === "string" ? payload.schedule : undefined, }; }