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.

g1t.sh
54 linesCodeBlameRaw

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.

A sandbox's request to an allowed host that fails upstream no longer resets the sandbox's connection. The runner Worker sent each one on with a bare fetch, so a reset or a failure upstream (as under npm ci's many tarball fetches) was thrown out of the outbound handler, and npm saw ECONNRESET and gave up. Forwarding is now one function (forward.ts) that egress() and the brokered-secret helper both use: a GET or HEAD with no body is tried twice more, after 250 ms and then a second, and what still fails comes back as a 502 whose plain-text body names the host and the error, with x-g1t-egress: upstream-failed, which npm and most tools retry. A request with a body is never sent twice. Each failure is one line of the Worker's log, with the host, the method and the error.1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { RETRY_WAITS_MS, forward } from "./forward.ts";
5
6/** A fetch that throws `failures` times, then answers 200; it counts its calls. */
7function flaky(failures: number) {
8 const calls: Request[] = [];
9 const send = async (request: Request) => {
10 calls.push(request);
11 if (calls.length <= failures) throw new Error("Network connection lost.");
12 return new Response("ok");
13 };
14 return { calls, send };
15}
16
17const waits: number[] = [];
18const sleep = async (ms: number) => {
19 waits.push(ms);
20};
21
22test("a GET that fails is tried again, and its answer comes back", async () => {
23 waits.length = 0;
24 const { calls, send } = flaky(2);
25 const response = await forward(new Request("https://registry.npmjs.org/react"), send, sleep);
26 assert.equal(response.status, 200);
27 assert.equal(await response.text(), "ok");
28 assert.equal(calls.length, 3);
29 assert.deepEqual(waits, [...RETRY_WAITS_MS]);
30});
31
32test("one that keeps failing gets a 502 naming the host and why, never a throw", async () => {
33 const { calls, send } = flaky(10);
34 const response = await forward(new Request("https://Registry.npmjs.org:443/react"), send, sleep);
35 assert.equal(calls.length, 3);
36 assert.equal(response.status, 502);
37 assert.equal(response.headers.get("x-g1t-egress"), "upstream-failed");
38 assert.match(response.headers.get("content-type") ?? "", /^text\/plain/);
39 const body = await response.text();
40 assert.match(body, /registry\.npmjs\.org could not be reached/);
41 assert.match(body, /Network connection lost\./);
42});
43
44test("a POST is never sent twice", async () => {
45 const { calls, send } = flaky(1);
46 const response = await forward(new Request("https://api.example.com/upload", { method: "POST", body: "data" }), send, sleep);
47 assert.equal(calls.length, 1);
48 assert.equal(response.status, 502);
49});
50
51test("an answer, even an error, is passed on as it is", async () => {
52 const response = await forward(new Request("https://example.com/"), async () => new Response("no", { status: 503 }), sleep);
53 assert.equal(response.status, 503);
54});