g1t/apps/web/app/routes/downloads-runner.ts

46 lines2,057 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.

Fast pages, required checks on the branch, self-hosted runners, honest incidents1import { env } from "cloudflare:workers";
2
3import type { Route } from "./+types/downloads-runner";
4
5/**
6 * The self-hosted runner's releases: `g1t.sh/downloads/runner/<version>/<file>`,
7 * served from the g1t-downloads R2 bucket that scripts/runner-release.mjs
8 * publishes to. `latest/<file>` is the newest release's, as its signed
9 * `latest.json` names it; `latest.json` and `latest.json.sig` themselves
10 * are what runners check before updating.
11 */
12const TYPES: Record<string, string> = {
13 json: "application/json",
14 sig: "text/plain; charset=utf-8",
15 txt: "text/plain; charset=utf-8",
16};
17
18async function object(key: string): Promise<R2ObjectBody | null> {
19 const bucket = env.DOWNLOADS;
20 return bucket ? bucket.get(key) : null;
21}
22
23export async function loader({ params }: Route.LoaderArgs) {
24 const path = (params["*"] ?? "").replace(/^\/+/, "");
25 if (!path || path.includes("..") || !/^[A-Za-z0-9._/-]+$/.test(path)) throw new Response("Not found\n", { status: 404 });
26 let key = `runner/${path}`;
27 // `latest/<file>`: the file of the newest release.
28 if (path.startsWith("latest/")) {
29 const manifest = await object("runner/latest.json");
30 if (!manifest) throw new Response("No release yet\n", { status: 404 });
31 const { version } = (await manifest.json()) as { version: string };
32 key = `runner/${version}/${path.slice("latest/".length)}`;
33 }
34 const found = await object(key);
35 if (!found) throw new Response("Not found\n", { status: 404 });
36 const name = key.split("/").pop() ?? "g1t-runner";
37 const extension = name.includes(".") ? name.split(".").pop()! : "";
38 const headers = new Headers({
39 "content-type": TYPES[extension] ?? "application/octet-stream",
40 etag: found.httpEtag,
41 // A version's files never change; what `latest` points to does.
42 "cache-control": path.startsWith("latest") ? "public, max-age=300" : "public, max-age=31536000, immutable",
43 });
44 if (!TYPES[extension]) headers.set("content-disposition", `attachment; filename="${name}"`);
45 return new Response(found.body, { headers });
46}