Skip to content

g1t/apps/web/app/lib/security-suite.server.ts

42 lines2,000 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1/**
2 * What the security pages ask the services for beyond one call: the
3 * activation's price (always the price book's, through billing), and
4 * "Set up code scanning", which commits the starter workflow on a new
5 * branch as the person asking and opens it as their pull request, as
6 * "Add CI" does.
7 */
8import { type RepoPath, STARTER_WORKFLOW_PATH, type User, type Viewer } from "@g1t/contracts";
9
10import { billing, repos, work } from "./services.server";
11import { codeScanningBranch, codeScanningPullBody, codeScanningWorkflow } from "./security-suite";
12
13/** The Security and quality activation's monthly price, in cents, or null. */
14export async function activationPrice(workspace: string, viewer: Viewer): Promise<number | null> {
15 const states = await billing.features(workspace, viewer).catch(() => null);
16 if (!states?.ok) return null;
17 return states.value.find((state) => state.plan.feature === "security")?.plan.monthlyCents ?? null;
18}
19
20export async function setupCodeScanning(user: User, path: RepoPath): Promise<{ ok: true; number: number } | { ok: false; message: string }> {
21 const repo = await repos.get(path, user);
22 if (!repo.ok) return { ok: false, message: repo.error.message };
23 const defaultBranch = repo.value.defaultBranch;
24 const branches = await repos.branches(path, user);
25 const branch = codeScanningBranch(branches.ok ? branches.value.map((known) => known.name) : []);
26 const committed = await repos.commitFile(path, user, {
27 branch,
28 path: STARTER_WORKFLOW_PATH,
29 content: codeScanningWorkflow(defaultBranch),
30 message: "Add code scanning",
31 });
32 if (!committed.ok) return { ok: false, message: committed.error.message };
33 const opened = await work.openPull(user, path, {
34 branch,
35 title: "Add code scanning",
36 body: codeScanningPullBody(defaultBranch),
37 agent: user.username,
38 runtime: "external",
39 });
40 if (!opened.ok) return { ok: false, message: opened.error.message };
41 return { ok: true, number: opened.value.number };
42}