Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

# The unplaced front Worker on the `executor.sh/*` route (src/edge/front.ts).
# After executor-cloud, so each deploy changes the edge's settings in
# executor-cloud before the Worker in front of it.
- name: Deploy executor.sh front Worker
run: bun run wrangler deploy -c wrangler.edge.jsonc
working-directory: apps/cloud
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

# Deploy marker: one event per deploy into the same Axiom dataset the
# worker traces land in, so a latency step-change lines up with its
# deploy in one query. Skipped (not failed) when the secret is absent,
Expand Down
112 changes: 112 additions & 0 deletions apps/cloud/src/edge/front.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { describe, expect, it } from "@effect/vitest";

import { frontResponse, type FrontEnv } from "./front";

/** A Worker stand-in that records what it receives and answers with `respond`. */
const recordingWorker = (respond: () => Response) => {
const received: Request[] = [];
return {
received,
worker: {
fetch: (request: Request) => {
received.push(request);
return Promise.resolve(respond());
},
},
};
};

const settings = (v2: FrontEnv["V2"], marketing?: FrontEnv["MARKETING"]): FrontEnv => ({
V2: v2,
MARKETING: marketing,
V2_SIGN_UP_URL: "https://app.executor.sh/login?mode=signup",
V2_OAUTH_STATE_PREFIX: "x2.",
V2_ANALYTICS_PROXY_PATH: "/api/0123456789abcdef",
V2_ERROR_TUNNEL_PATH: "/api/fedcba9876543210/submit",
});

const IMMUTABLE = "public, max-age=31536000, immutable";

describe("frontResponse", () => {
it("returns v2's asset with its caching, status and body unchanged, adding only the referrer policy", async () => {
const v2 = recordingWorker(
() =>
new Response("console.log(1)", {
status: 200,
headers: {
"cache-control": IMMUTABLE,
"content-type": "text/javascript",
etag: '"abc"',
},
}),
);

const response = await frontResponse(
new Request("https://executor.sh/_astro/page.abc123.js"),
settings(v2.worker),
);

expect(v2.received.map((request) => request.url)).toEqual([
"https://executor.sh/_astro/page.abc123.js",
]);
expect(response?.status).toBe(200);
expect(response?.headers.get("cache-control")).toBe(IMMUTABLE);
expect(response?.headers.get("content-type")).toBe("text/javascript");
expect(response?.headers.get("etag")).toBe('"abc"');
expect(response?.headers.get("referrer-policy")).toBe("no-referrer");
expect(await response?.text()).toBe("console.log(1)");
});

it("answers v2's redirects itself, as executor-cloud does", async () => {
const v2 = recordingWorker(() => new Response("v2"));

const response = await frontResponse(
new Request("https://executor.sh/sign-up"),
settings(v2.worker),
);

expect(v2.received).toHaveLength(0);
expect(response?.status).toBe(302);
expect(response?.headers.get("location")).toBe("https://app.executor.sh/login?mode=signup");
expect(response?.headers.get("referrer-policy")).toBe("no-referrer");
});

it("sends v1's legal pages to v1's marketing worker", async () => {
const v2 = recordingWorker(() => new Response("v2"));
const marketing = recordingWorker(() => new Response("terms"));

const response = await frontResponse(
new Request("https://executor.sh/terms"),
settings(v2.worker, marketing.worker),
);

expect(v2.received).toHaveLength(0);
expect(marketing.received.map((request) => request.url)).toEqual(["https://executor.sh/terms"]);
expect(await response?.text()).toBe("terms");
expect(response?.headers.get("referrer-policy")).toBe("no-referrer");
});

it("passes on every request executor-cloud serves itself", () => {
const v2 = recordingWorker(() => new Response("v2"));
const marketing = recordingWorker(() => new Response("terms"));
const env = settings(v2.worker, marketing.worker);

for (const request of [
new Request("https://executor.sh/", { headers: { cookie: "wos-session=sealed" } }),
new Request("https://executor.sh/login"),
new Request("https://executor.sh/mcp", { method: "POST" }),
new Request("https://executor.sh/api/auth/callback?code=c&state=s"),
new Request("https://executor.sh/api/oauth/callback?code=c&state=abc"),
new Request("https://executor.sh/acme"),
new Request("https://executor.sh/favicon.ico"),
]) {
expect(frontResponse(request, env), request.url).toBeNull();
}
expect(v2.received).toHaveLength(0);
expect(marketing.received).toHaveLength(0);
});

it("passes everything on when v2's settings are absent", () => {
expect(frontResponse(new Request("https://executor.sh/_astro/page.abc123.js"), {})).toBeNull();
});
});
47 changes: 47 additions & 0 deletions apps/cloud/src/edge/front.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// ---------------------------------------------------------------------------
// The `executor.sh` front Worker (`wrangler.edge.jsonc`, Worker
// `executor-cloud-edge`).
//
// `executor-cloud` is placed near v1's database (`placement.region` in
// wrangler.jsonc), so every request it runs crosses to Virginia first. The
// requests its edge hands to v2 or to v1's marketing worker never use that
// database, yet each paid the trip: a 2 KB `/_astro/*` file took up to 2.6 s.
// This Worker has no placement and runs the same edge decision
// (./marketing.ts) where the request lands, on a zone route
// `executor.sh/*`. A zone route runs before the Worker on the hostname's
// Custom Domain, which Cloudflare treats as the origin, so a request v1 owns
// goes on with `fetch(request)` to `executor-cloud` unchanged: same URL,
// method, headers, cookies, body stream and redirect handling as before.
//
// `executor-cloud` keeps its own copy of the edge, which answers nothing this
// Worker passes on. Deleting this Worker (or its route) returns `executor.sh`
// to exactly that, which is the rollback.
// ---------------------------------------------------------------------------

import { marketingProxyRequest, v2EdgeResponse, type V2EdgeEnv } from "./marketing";
import { withPrivateReferrerPolicy } from "./referrer-policy";

/** The front Worker's bindings and settings (`wrangler.edge.jsonc`). */
export interface FrontEnv extends V2EdgeEnv {
/** v1's marketing worker, which serves v1's legal pages. */
readonly MARKETING?: { readonly fetch: (request: Request) => Promise<Response> };
}

/**
* Answer an `executor.sh` request that v2 or v1's marketing worker owns,
* exactly as `executor-cloud`'s entry does, including its `no-referrer`
* policy. Returns `null` for every request `executor-cloud` serves itself.
*/
export const frontResponse = (request: Request, env: FrontEnv): Promise<Response> | null => {
const v2 = v2EdgeResponse(request, env);
if (v2) return v2.then(withPrivateReferrerPolicy);
const marketingRequest = marketingProxyRequest(request);
if (marketingRequest && env.MARKETING) {
return env.MARKETING.fetch(marketingRequest).then(withPrivateReferrerPolicy);
}
return null;
};

export default {
fetch: (request, env) => frontResponse(request, env) ?? fetch(request),
} satisfies ExportedHandler<FrontEnv>;
98 changes: 98 additions & 0 deletions apps/cloud/src/edge/production-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { describe, expect, it } from "@effect/vitest";
import { Schema } from "effect";
import { unstable_readConfig } from "wrangler";

import { frontResponse } from "./front";
import { parseV2Edge, v2EdgeResponse, type V2EdgeEnv, type V2Service } from "./marketing";

// The deployed edge reads its v2 settings from wrangler.jsonc. These tests read
Expand All @@ -18,6 +19,23 @@ const config = Schema.decodeUnknownSync(WranglerConfig)(
unstable_readConfig({ config: fileURLToPath(new URL("../../wrangler.jsonc", import.meta.url)) }),
);

// The front Worker (wrangler.edge.jsonc) runs the same edge on executor.sh
// before `executor-cloud`, with its own copy of the settings.
const EdgeWranglerConfig = Schema.Struct({
main: Schema.String,
vars: Schema.Record(Schema.String, Schema.Unknown),
services: Schema.Array(Schema.Struct({ binding: Schema.String, service: Schema.String })),
routes: Schema.Array(
Schema.Struct({ pattern: Schema.String, zone_name: Schema.optional(Schema.String) }),
),
placement: Schema.optional(Schema.Unknown),
});
const edgeConfig = Schema.decodeUnknownSync(EdgeWranglerConfig)(
unstable_readConfig({
config: fileURLToPath(new URL("../../wrangler.edge.jsonc", import.meta.url)),
}),
);

const stringVar = (name: string): string | undefined => {
const value = config.vars[name];
return typeof value === "string" ? value : undefined;
Expand All @@ -34,6 +52,20 @@ const shipped: V2EdgeEnv = {
V2_ERROR_TUNNEL_PATH: stringVar("V2_ERROR_TUNNEL_PATH"),
};

const edgeStringVar = (name: string): string | undefined => {
const value = edgeConfig.vars[name];
return typeof value === "string" ? value : undefined;
};

/** The front Worker's shipped settings, with the same stand-in. */
const frontShipped: V2EdgeEnv = {
V2: standIn,
V2_SIGN_UP_URL: edgeStringVar("V2_SIGN_UP_URL"),
V2_OAUTH_STATE_PREFIX: edgeStringVar("V2_OAUTH_STATE_PREFIX"),
V2_ANALYTICS_PROXY_PATH: edgeStringVar("V2_ANALYTICS_PROXY_PATH"),
V2_ERROR_TUNNEL_PATH: edgeStringVar("V2_ERROR_TUNNEL_PATH"),
};

describe("production v2 edge settings", () => {
it("binds V2 to the unplaced marketing gateway", () => {
const bindings = config.services.filter((service) => service.binding === "V2");
Expand Down Expand Up @@ -66,6 +98,40 @@ describe("production v2 edge settings", () => {
});
});

describe("the executor.sh front Worker's settings", () => {
it("runs the front entry on a zone route for every executor.sh path", () => {
expect(edgeConfig.main).toMatch(/src\/edge\/front\.ts$/);
expect(edgeConfig.routes).toEqual([{ pattern: "executor.sh/*", zone_name: "executor.sh" }]);
});

// Placement would send every request it answers to the placed region,
// which is the trip this Worker exists to avoid.
it("is not placed", () => {
expect(edgeConfig.placement).toBeUndefined();
});

it("ships the same v2 settings as executor-cloud", () => {
const v2Vars = (vars: Readonly<Record<string, unknown>>) =>
Object.fromEntries(Object.entries(vars).filter(([name]) => name.startsWith("V2_")));
expect(Object.keys(v2Vars(edgeConfig.vars)).toSorted()).toEqual([
"V2_ANALYTICS_PROXY_PATH",
"V2_ERROR_TUNNEL_PATH",
"V2_OAUTH_STATE_PREFIX",
"V2_SIGN_UP_URL",
]);
expect(v2Vars(edgeConfig.vars)).toEqual(v2Vars(config.vars));
});

it("binds the same v2 and marketing Workers as executor-cloud", () => {
const bound = (services: typeof config.services) =>
services
.filter((service) => service.binding === "V2" || service.binding === "MARKETING")
.toSorted((a, b) => a.binding.localeCompare(b.binding));
expect(bound(edgeConfig.services)).toEqual(bound(config.services));
expect(bound(edgeConfig.services)).toHaveLength(2);
});
});

// v2 publishes the exact set of executor.sh requests v1's edge forwards to it.
// `v2-edge-contract.json` is a verbatim copy of v2's edge contract; update it
// only together with v2's contract, never by hand here. Every case runs
Expand Down Expand Up @@ -133,6 +199,38 @@ describe("v2's edge contract", () => {
});
}

// The front Worker answers the same requests the same way: everything the
// contract forwards reaches v2 once, and nothing else reaches it.
const runFrontCase = async (method: string, target: string) => {
const calls: Request[] = [];
const v2: V2Service = {
fetch: (request) => {
calls.push(request);
return Promise.resolve(new Response("v2"));
},
};
const request = new Request(`${contract.origin}${target}`, { method });
const response = await frontResponse(request, { ...frontShipped, V2: v2 });
return { request, calls, response };
};

for (const { method, target } of forwarded) {
it(`front Worker forwards ${method} ${target} to v2`, async () => {
const { request, calls, response } = await runFrontCase(method, target);
expect(calls).toHaveLength(1);
expect(calls[0]?.url).toBe(request.url);
expect(calls[0]?.method).toBe(method);
expect(await response?.text()).toBe("v2");
});
}

for (const { method, target } of contract.cases.filter((c) => !c.forwards)) {
it(`front Worker does not forward ${method} ${target} to v2`, async () => {
const { calls } = await runFrontCase(method, target);
expect(calls).toHaveLength(0);
});
}

// Sign-up is not forwarded: the edge redirects it to v2's sign-up page.
it("lists both sign-up paths as not forwarded", () => {
expect(signUps.map((c) => c.target).toSorted()).toEqual(["/sign-up", "/signup"]);
Expand Down
46 changes: 46 additions & 0 deletions apps/cloud/wrangler.edge.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
// The `executor.sh` front Worker (src/edge/front.ts). It answers the
// requests v1's edge hands to v2 or to v1's marketing worker where they
// land, and passes every other request on to `executor-cloud`, the Worker
// on the `executor.sh` Custom Domain. Deployed after `executor-cloud` by
// .github/workflows/deploy.yml.
"name": "executor-cloud-edge",
"compatibility_date": "2025-04-01",
"main": "src/edge/front.ts",
"workers_dev": false,
"preview_urls": false,
// A zone route runs before the Custom Domain's Worker; see front.ts.
"routes": [
{
"pattern": "executor.sh/*",
"zone_name": "executor.sh",
},
],
// No `placement`, on purpose: this Worker exists to run where the request
// lands. `executor-cloud` stays placed for v1's own requests.
"observability": {
"enabled": true,
"redact_query_string": true,
},
"logpush": true,
// The same Workers and v2 settings as `executor-cloud`'s wrangler.jsonc,
// which keeps its own copy of the edge. src/edge/production-config.test.ts
// fails when the two differ.
"services": [
{
"binding": "MARKETING",
"service": "executor-marketing",
},
{
"binding": "V2",
"service": "executor-next-marketing-v2",
},
],
"vars": {
"V2_SIGN_UP_URL": "https://app.executor.sh/login?mode=signup",
"V2_OAUTH_STATE_PREFIX": "x2.",
"V2_ANALYTICS_PROXY_PATH": "/api/00e2e1f082a6ef17",
"V2_ERROR_TUNNEL_PATH": "/api/fd6fab1fbb4883e1/submit",
},
}
Loading