180 lines · 6.9 KB
import { z } from "zod";
import { repoDb } from "../scoped-db";
import { notFoundError } from "../errors";
import { limitWrite } from "../limits";
import { canAdministerAccount } from "../repos";
import { approveRunRow, cancelRunRow, loadRunByNumber } from "../ci/run-control";
import { listRepoRunners, mintRegistrationToken, removeRepoRunner, repoScope } from "../ci/runner-registration";
import { forkRunsAllowed, setForkRunsAllowed } from "../ci/runner-policy";
import {
  hasAccountScope,
  noContent,
  readJson,
  requireAccountScope,
  requireScopedAdminWrite,
  requireScopedRepo,
} from "./http";
import { requireOwnerAdmin } from "../ci/config-admin";
import { listOwnerRunners, removeOwnerRunner } from "../ci/runner-owner";
import type { ApiContext } from "./http";

const MAX_RUNS_LISTED = 20;
const MAX_JOBS_LISTED = 200;

const registrationInput = z.object({
  scope: z.enum(["repository", "owner"]).default("repository"),
  labels: z.array(z.string().trim().min(1).max(32)).max(20).default([]),
  isolation: z.enum(["container", "none"]).default("container"),
});
const policyInput = z.object({ allow_fork_pull_requests: z.boolean() });

export async function createRegistrationToken(ctx: ApiContext, owner: string, name: string): Promise<Response> {
  const data = await readJson(ctx.request, registrationInput);
  await limitWrite(ctx.viewer);
  if (data.scope === "owner") requireAccountScope(ctx);
  const { repo } = await requireScopedAdminWrite(ctx, owner, name);
  const scope = await repoScope(repo, data.scope, ctx.viewer);
  const minted = await mintRegistrationToken(scope, ctx.viewer.id, data.labels, data.isolation);
  return Response.json({ token: minted.token, expires_at: minted.expiresAt }, { status: 201 });
}