Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

3 files changed+10−2
modifiedapps/diffinery/src/git/protocol.ts+3−0View file
@@ -289,6 +289,9 @@
289289 reason?: string;
290290 }
291291
292+/** The platform's error for a Durable Object stopped by a new version of its code. */
293+export const resetByDeploy = (e: unknown) => e instanceof Error && /durable object reset because its code was updated/i.test(e.message);
294+
292295 /**
293296 * The unpack status for a push that couldn't be unpacked or stored. Running out of memory says to
294297 * split the push, the wording clients (and the GitHub importer, which then pushes smaller chunks)
modifiedapps/diffinery/src/http/git.ts+2−2View file
@@ -7,6 +7,7 @@
77 import { importPushAllowed } from "../imports/service.js";
88 import { loadRepo, repoStub } from "./common.js";
99 import type { Caller } from "../repo/types.js";
10+import { resetByDeploy } from "../git/protocol.js";
1011
1112 /**
1213 * Git smart HTTP (protocol v2 for fetch/clone, v0 for push) and the Git LFS
@@ -80,8 +81,7 @@
8081
8182 const PUSH_TRIES = 2;
8283
83-/** The platform's error for a Durable Object stopped by a new version of its code. */
84-export const resetByDeploy = (e: unknown) => e instanceof Error && /durable object reset because its code was updated/i.test(e.message);
84+export { resetByDeploy };
8585
8686 /** A fetch's wants and haves; git's own negotiation stays far below this. */
8787 const MAX_UPLOAD_PACK_REQUEST = 16 * 1024 * 1024;
modifiedapps/diffinery/src/repo/RepoDO.ts+5−0View file
@@ -44,6 +44,7 @@
4444 parseReceivePack,
4545 reportStatus,
4646 type ReceiveRequest,
47+ resetByDeploy,
4748 unpackFailure,
4849 type RefEntry,
4950 type RefResult,
@@ -576,6 +577,8 @@
576577 req = head.req;
577578 packAt = head.packOffset;
578579 } catch (e) {
580+ // A deploy that stops this object mid-push is the Worker's to retry (http/git.ts receiveWithRetry).
581+ if (resetByDeploy(e)) throw e;
579582 return reportStatus({ commands: [], capabilities: new Set<string>(), pushOptions: [], pack: null }, unpackFailure(e), []);
580583 }
581584 }
@@ -613,6 +616,7 @@
613616 );
614617 }
615618 } catch (e) {
619+ if (resetByDeploy(e)) throw e;
616620 unpackError = unpackFailure(e);
617621 }
618622 const results: RefResult[] = [];
@@ -664,6 +668,7 @@
664668 try {
665669 await contents.write();
666670 } catch (e) {
671+ if (resetByDeploy(e)) throw e;
667672 for (const c of req.commands) results.push({ ref: c.ref, ok: false, reason: "unpacker error" });
668673 return reportStatus(req, unpackFailure(e), results);
669674 }