| 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 | } |