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

Commit

A signed archive link counts by the link, not by the address it comes from. `actions/checkout` in a job container without git downloads a tarball through the link `GET /repos/{owner}/{repo}/tarball/{ref}` sends it to; counted against the signed-out limit of 30 archive downloads a minute per address, jobs behind one address, as g1t's own machines are, would have used it up between them. A link is made for one commit, for 10 minutes, by a request the API already counts, so it is counted at the token rate instead. The rate limits reference says so.

Claude-Session:
https://claude.ai/code/session_01PnwTRSNaC7vEHTAuBzjhrn
Claudeagent and Claudeagentcommitted Parentc6ff9bbBrowse files
3 files+28−10/3 viewed
+5−0
3434
3535 A running job's live log, which its run's page asks for about once a
3636 second, counts as a page, not as a log download.
37+A signed archive link, the address
38+`GET /repos/{owner}/{repo}/tarball/{ref}` and `/zipball/{ref}` send you to,
39+counts by the link, at the token rate, rather than by address: jobs that
40+share an address, as g1t's own machines do, each download their tarball
41+without using up each other's limit.
3742
3843 Agents' sandboxes and workflow jobs report to g1t with their own
3944 credentials. Those reports are not rate limited.
+8−1
1111 secretKey,
1212 } from "@g1t/contracts/rate-limits";
1313
14−import { gitLimited, heavy, pageLimited, sessionCookie, unlimited, usercontentLimited } from "./front-door-limits.ts";
14+import { archiveLink, gitLimited, heavy, pageLimited, sessionCookie, unlimited, usercontentLimited } from "./front-door-limits.ts";
1515
1616 /** A binding that lets `allow` requests through per key, recording each key it was asked. */
1717 function binding(allow: number): RateLimitBinding & { keys: string[] } {
202202 assert.equal(await usercontentLimited(env, request("/avatars/" + "a".repeat(64)), "/avatars/" + "a".repeat(64)), null);
203203 assert.deepEqual(env.WEB_ANONYMOUS_LIMIT.keys, ["ip:203.0.113.9", "ip:203.0.113.9"]);
204204 });
205+
206+test("a signed archive link is known by its token, and only on an archive", () => {
207+ assert.equal(archiveLink("/acme/web/archive/abc.tar.gz", "https://g1t.sh/acme/web/archive/abc.tar.gz?token=t1"), "t1");
208+ assert.equal(archiveLink("/acme/web/archive/main.zip", "https://g1t.sh/acme/web/archive/main.zip?token=t2"), "t2");
209+ assert.equal(archiveLink("/acme/web/archive/main.zip", "https://g1t.sh/acme/web/archive/main.zip"), null);
210+ assert.equal(archiveLink("/acme/web/issues", "https://g1t.sh/acme/web/issues?token=t3"), null);
211+});
+15−0
6161 return HEAVY.test(pathname);
6262 }
6363
64+/** The signed token of an archive download link (`archive/<ref>.zip|.tar.gz?token=`), or null. */
65+export function archiveLink(pathname: string, url: string): string | null {
66+ if (!/^\/[^/]+\/[^/]+\/archive\/.+\.(?:zip|tar\.gz)$/.test(pathname)) return null;
67+ try {
68+ return new URL(url).searchParams.get("token") || null;
69+ } catch {
70+ return null;
71+ }
72+}
73+
6474 /** The session cookie's value, or null when signed out. */
6575 export function sessionCookie(cookie: string | null): string | null {
6676 const match = /(?:^|;\s*)g1t_session=([^;]+)/.exec(cookie ?? "");
107117 checks.push(secretKey("token", token).then((key) => checkLimit(env.WEB_TOKEN_LIMIT, key)));
108118 } else if (session) {
109119 checks.push(secretKey("session", session).then((key) => checkLimit(env.WEB_SESSION_LIMIT, key)));
120+ } else if (archiveLink(pathname, request.url)) {
121+ // A signed archive link (`GET /repos/{owner}/{repo}/tarball/{ref}` made
122+ // it for one commit, for 10 minutes) counts per link, as a token does:
123+ // many jobs behind one address fall back to tarballs at once.
124+ checks.push(secretKey("archive", archiveLink(pathname, request.url)!).then((key) => checkLimit(env.WEB_TOKEN_LIMIT, key)));
110125 } else {
111126 checks.push(checkLimit(env.WEB_ANONYMOUS_LIMIT, address));
112127 if (heavy(pathname)) checks.push(checkLimit(env.WEB_HEAVY_LIMIT, address));

Comments

Sign in to comment.