Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

47 linesCodeBlameRaw
1/**
2 * A screenshot of a project's production deployed elsewhere, for its
3 * overview: of the address its reported production deployment gives, else
4 * the one set for it (lib/production-image.ts `externalTarget`). The
5 * address is always the project's own, never one the request names, and
6 * the og service visits only public ones. For anyone who can see the
7 * project: it shows a public address. Kept by the browser for an hour; the
8 * overview's `?v=` changes with each reported deploy and each day.
9 */
10import { env } from "cloudflare:workers";
11
12import type { Route } from "./+types/production-elsewhere";
13import { reportedProduction } from "../../lib/deployments";
14import { externalTarget } from "../../lib/production-image";
15import { deployments } from "../../lib/services.server";
16import { getViewer } from "../../lib/session.server";
17import { projectFor } from "../../lib/access.server";
18
19const HOUR = "private, max-age=3600";
20const BRIEF = "private, max-age=60";
21
22export async function loader({ params, context }: Route.LoaderArgs) {
23 const viewer = getViewer(context);
24 const none = (status: number) => new Response(null, { status, headers: { "cache-control": BRIEF } });
25 if (!env.SCREENSHOTS) return none(404);
26 const project = await projectFor(context, params).catch(() => null);
27 if (!project?.ok) return none(404);
28 const repo = project.value.source.kind === "hosted" ? project.value.source.repo : { namespace: params.owner, name: params.repo };
29 const environments = await deployments.environments(repo, viewer).catch(() => null);
30 const reported = reportedProduction(environments?.ok ? environments.value.environments : []);
31 const target = externalTarget(project.value, reported, Date.now());
32 if (!target) return none(404);
33 const shot = await env.SCREENSHOTS.externalImage({ url: target.url, commit: target.commit, since: target.since ?? undefined }).catch(
34 (error: unknown) => (console.warn("screenshot:", error), null),
35 );
36 if (!shot) return none(404);
37 return new Response(shot.body, {
38 headers: {
39 "content-type": shot.contentType,
40 "cache-control": HOUR,
41 "x-content-type-options": "nosniff",
42 // A picture of someone's site: shown, never run.
43 "content-security-policy": "default-src 'none'; sandbox",
44 "last-modified": new Date(shot.capturedAt).toUTCString(),
45 },
46 });
47}