64 lines · 2.2 KB
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<string, ExprValue> {
  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<Trigger> {
  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);