import { createServerFn } from "@tanstack/react-start";
import { requireViewer, viewerMiddleware } from "./middleware";
import { WORKFLOW_DIR } from "~/server/ci/spec";
import { badRequest } from "~/server/errors";
import { listRefs, resolveRevision } from "~/server/git/refs";
import { withStore } from "~/server/git/store";
import type { GitStore } from "~/server/git/store";
import { commitFileChanges } from "~/server/git/web-commit";
import { limitWrite } from "~/server/limits";
import { requireRepoAccess } from "~/server/repos";
import { repoRef } from "~/lib/validation";
import type { RepoRow } from "~/lib/types";
export const GITHUB_WORKFLOW_DIR = ".github/workflows";
const YAML_FILE = /\.ya?ml$/;
async function workflowNames(store: GitStore, treeSha: string, directory: string): Promise<Map<string, string>> {
const entry = await store.entryAtPath(treeSha, directory);
if (!entry || entry.type !== "tree") return new Map();
const files = (await store.listTree(entry.sha, directory)).filter(
(file) => file.type === "blob" && YAML_FILE.test(file.name),
);
return new Map(files.map((file) => [file.name, file.sha]));
}
/** GitHub workflow files on the default branch that have no same-named file in `.gitfor/workflows` yet. */
async function importable(repo: RepoRow) {
const revision = resolveRevision(await listRefs(repo), repo.default_branch);
if (!revision) return { headSha: null, files: [] as Array<{ name: string; sha: string }> };
return withStore(repo.artifacts_name, async (store) => {
const commit = await store.commit(revision.sha);
if (!commit) return { headSha: revision.sha, files: [] };
const [github, existing] = await Promise.all([
workflowNames(store, commit.treeSha, GITHUB_WORKFLOW_DIR),
workflowNames(store, commit.treeSha, WORKFLOW_DIR),
]);
const files = [...github].filter(([name]) => !existing.has(name)).map(([name, sha]) => ({ name, sha }));
return { headSha: revision.sha, files };
});
}