294 lines · 11.7 KB
import { z } from "zod";
import { placeholders } from "../db";
import { repoDb } from "../scoped-db";
import { badRequest, forbidden, notFoundError } from "../errors";
import { limitWrite } from "../limits";
import { assertNotArchived } from "../repos";
import { cacheQuotaBytes, deleteCacheEntry } from "../ci/cache-api";
import { deleteConfigValue, listSecretNames, listVariables, upsertSecret, upsertVariable } from "../ci/config-admin";
import type { ConfigScope } from "../ci/config-admin";
import { pendingDeployments, reviewDeployment, visibleOutputs } from "../ci/deployments";
import type { DeploymentRow, EnvironmentRow } from "../ci/deployments";
import type { WorkflowJobRow, WorkflowRunRow } from "../ci/jobs";
import { rerunTrigger } from "../ci/rerun";
import { loadRunByNumber } from "../ci/run-control";
import { scheduleWorkflows } from "../ci/scheduler";
import { listRefs, resolveRevision } from "../git/refs";
import { combinedState, listCommitStatuses } from "../statuses";
import { noContent, readJson, requireScopedAdminWrite, requireScopedRepo, requireTokenWrite } from "./http";
import type { ApiContext } from "./http";
import { secretName } from "~/lib/validation";

const MAX_VALUE_BYTES = 48 * 1024;
const DEPLOYMENT_PAGE = 50;
const CACHE_PAGE = 100;

const rerunInput = z.object({ failed_only: z.boolean().default(false) });
const dispatchInput = z.object({
  path: z.string().min(1),
  ref: z.string().min(1),
  inputs: z.record(z.string(), z.string()).default({}),
});
const valueInput = z.object({ value: z.string().min(1).max(MAX_VALUE_BYTES) });
const reviewInput = z.object({ approve: z.boolean() });

function configName(raw: string): string {
  const parsed = secretName.safeParse(raw);
  if (!parsed.success) throw badRequest(parsed.error.issues.map((issue) => issue.message).join("; "));
  return parsed.data.toUpperCase();
}