251 lines · 9.1 KB
import { env } from "cloudflare:workers";
import { repoDb } from "../scoped-db";
import { randomId } from "../crypto";
import { clearWorkflowCompileError, setCommitStatus } from "../statuses";
import { CAPS } from "../limits";
import { publicUrl } from "../events/emit";
import { withStore } from "../git/store";
import { compileWorkflow } from "./compile";
import { resolveWorkflowActions } from "./actions/resolve";
import type { CompiledJob, CompileInput, EventContext } from "./compile";
import { loadVariables } from "./config-values";
import { isScratchRepo } from "../sites/config";
import { isJobTokenPush } from "./job-token";
import { allocateRunNumber, insertRun, reuseSuccessfulJobs, supersedePendingApprovals } from "./run-insert";
import { parseWorkflow, WORKFLOW_DIR } from "./spec";
import { workflowMatches } from "./triggers";
import type { Trigger } from "./triggers";
import { accountDisableState } from "../account-disable";
import type { RepoRow } from "~/lib/types";

const WORKFLOW_FILE = /\.ya?ml$/;
const MAX_WORKFLOW_FILES = 30;
const MAX_WORKFLOW_BYTES = 128 * 1024;
const MAX_JOBS_PER_RUN = 50;
const MAX_STEP_ROWS_PER_RUN = 800;

type WorkflowFile = { path: string; source: string; tooLarge: boolean };

export async function readWorkflowFiles(sourceRepo: RepoRow, sha: string): Promise<WorkflowFile[]> {
  return withStore(sourceRepo.artifacts_name, async (store) => {
    const commit = await store.commit(sha);
    if (!commit) return [];
    const directory = await store.entryAtPath(commit.treeSha, WORKFLOW_DIR);
    if (!directory || directory.type !== "tree") return [];
    const entries = (await store.listTree(directory.sha, WORKFLOW_DIR))
      .filter((entry) => entry.type !== "tree" && WORKFLOW_FILE.test(entry.name))
      .slice(0, MAX_WORKFLOW_FILES);
    const files = await Promise.all(
      entries.map(async (entry) => {
        const bytes = await store.blob(entry.sha);