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.

112 lines · 5.4 KBRaw History
1// Diffinery: one Worker, everything on Cloudflare.
2// `scripts/bootstrap.sh` creates the account resources and writes
3// wrangler.deploy.jsonc (this file plus real IDs) for CI deploys.
4{
5 "$schema": "node_modules/wrangler/config-schema.json",
6 "name": "diffinery",
7 "main": "src/index.ts",
8 "compatibility_date": "2026-10-01",
9 "compatibility_flags": ["nodejs_compat"],
10 "workers_dev": false,
11 // A zone route, not a Custom Domain: diffinery.com already has DNS records, and a
12 // route runs the Worker in front of them as long as the record is proxied (orange cloud).
13 "routes": [{ "pattern": "diffinery.com/*", "zone_name": "diffinery.com" }],
14 "observability": { "enabled": true, "head_sampling_rate": 1 },
15 "upload_source_maps": true,
16 "limits": { "cpu_ms": 300000 },
17
18 "vars": {
19 "PUBLIC_URL": "https://diffinery.com",
20 "MAIL_FROM": "notifications@diffinery.com",
21 "BOOTSTRAP_ADMINS": "iletisim@canberkdemirci.com,canberkdemirci@icloud.com,iletisim@altugankarali.com",
22 "ACCESS_TEAM_DOMAIN": "",
23 "ACCESS_AUD": ""
24 },
25
26 "d1_databases": [
27 { "binding": "DB", "database_name": "diffinery", "database_id": "00000000-0000-0000-0000-000000000000", "migrations_dir": "migrations" }
28 ],
29 "r2_buckets": [{ "binding": "BUCKET", "bucket_name": "diffinery-data" }],
30 "queues": {
31 "producers": [
32 { "binding": "EVENTS", "queue": "diffinery-events" },
33 { "binding": "MAIL", "queue": "diffinery-mail" }
34 ],
35 "consumers": [
36 { "queue": "diffinery-events", "max_batch_size": 50, "max_batch_timeout": 2, "max_retries": 8, "dead_letter_queue": "diffinery-events-dlq" },
37 { "queue": "diffinery-mail", "max_batch_size": 20, "max_batch_timeout": 2, "max_retries": 8, "dead_letter_queue": "diffinery-mail-dlq" }
38 ]
39 },
40 // Cloudflare Email Sending (notifications, security alerts, invites). The sending
41 // domain is onboarded under Compute > Email Service > Email Sending (see scripts/email-sending.sh).
42 "send_email": [{ "name": "EMAIL" }],
43 "durable_objects": {
44 "bindings": [
45 { "name": "REPO", "class_name": "RepoDO" },
46 { "name": "RUNNER", "class_name": "RunnerContainer" },
47 { "name": "SANDBOX", "class_name": "SandboxContainer" },
48 { "name": "IMPORTER", "class_name": "ImportContainer" }
49 ]
50 },
51 "migrations": [
52 { "tag": "v1", "new_sqlite_classes": ["RepoDO", "RunnerContainer", "SandboxContainer"] },
53 { "tag": "v2", "new_sqlite_classes": ["ImportContainer"] }
54 ],
55 "workflows": [
56 { "name": "diffinery-run", "binding": "RUN_WORKFLOW", "class_name": "RunWorkflow" },
57 { "name": "diffinery-import", "binding": "IMPORT_WORKFLOW", "class_name": "ImportWorkflow" }
58 ],
59 "containers": [
60 { "class_name": "RunnerContainer", "image": "../../containers/runner/Dockerfile", "image_build_context": "../../containers/runner", "instance_type": "standard-2", "max_instances": 100, "rollout_active_grace_period": 3600 },
61 { "class_name": "SandboxContainer", "image": "../../containers/runner/Dockerfile", "image_build_context": "../../containers/runner", "instance_type": "standard-1", "max_instances": 50, "rollout_active_grace_period": 3600 },
62 // GitHub imports: a mirror clone of a large repository needs disk and memory.
63 { "class_name": "ImportContainer", "image": "../../containers/runner/Dockerfile", "image_build_context": "../../containers/runner", "instance_type": "standard-4", "max_instances": 20, "rollout_active_grace_period": 3600 }
64 ],
65 "triggers": { "crons": ["*/5 * * * *"] },
66
67 "env": {
68 // Local development and end-to-end tests: no Access, a fixed dev identity, no containers.
69 "dev": {
70 "routes": [],
71 "workers_dev": true,
72 "vars": {
73 "PUBLIC_URL": "http://localhost:8787",
74 "MAIL_FROM": "notifications@diffinery.com",
75 "BOOTSTRAP_ADMINS": "dev@diffinery.local",
76 "ACCESS_TEAM_DOMAIN": "",
77 "ACCESS_AUD": "",
78 "DEV_AUTH": "dev@diffinery.local",
79 // Containers do not run under wrangler dev: an import agent started by hand (or by the e2e test) claims Git transfers.
80 "IMPORT_GIT_AGENT": "external"
81 },
82 "d1_databases": [{ "binding": "DB", "database_name": "diffinery-dev", "database_id": "00000000-0000-0000-0000-000000000000", "migrations_dir": "migrations" }],
83 "r2_buckets": [{ "binding": "BUCKET", "bucket_name": "diffinery-data-dev" }],
84 "queues": {
85 "producers": [
86 { "binding": "EVENTS", "queue": "diffinery-events-dev" },
87 { "binding": "MAIL", "queue": "diffinery-mail-dev" }
88 ],
89 "consumers": [
90 { "queue": "diffinery-events-dev", "max_batch_size": 50, "max_batch_timeout": 1 },
91 { "queue": "diffinery-mail-dev", "max_batch_size": 20, "max_batch_timeout": 1 }
92 ]
93 },
94 // Local email: Miniflare captures sent messages instead of delivering them.
95 "send_email": [{ "name": "EMAIL" }],
96 "durable_objects": {
97 "bindings": [
98 { "name": "REPO", "class_name": "RepoDO" },
99 { "name": "RUNNER", "class_name": "RunnerContainer" },
100 { "name": "SANDBOX", "class_name": "SandboxContainer" },
101 { "name": "IMPORTER", "class_name": "ImportContainer" }
102 ]
103 },
104 "workflows": [
105 { "name": "diffinery-run-dev", "binding": "RUN_WORKFLOW", "class_name": "RunWorkflow" },
106 { "name": "diffinery-import-dev", "binding": "IMPORT_WORKFLOW", "class_name": "ImportWorkflow" }
107 ],
108 "triggers": { "crons": [] },
109 "containers": []
110 }
111 }
112}