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.

51 lines · 3.0 KB · executableRaw History
1#!/usr/bin/env node
2// Render apps/diffinery/wrangler.deploy.jsonc from wrangler.jsonc plus values
3// discovered by scripts/bootstrap.sh (real D1 id, Access team domain and AUD).
4//
5// node scripts/render-config.mjs --d1 <uuid> [--team <x.cloudflareaccess.com>] [--aud <tag>]
6// [--public-url https://git.example.com] [--zone example.com] [--mail-from notifications@example.com]
7//
8// --public-url also points the Worker's route at that host (in --zone, by default
9// the host's last two labels) and sends email from notifications@<host>.
10// From the environment it takes RUNNER_IMAGE (scripts/runner-image.sh) and
11// TURNSTILE_SITE_KEY (scripts/turnstile.sh, through bootstrap).
12import { readFileSync, writeFileSync } from "node:fs";
13import { dirname, join } from "node:path";
14import { fileURLToPath } from "node:url";
15import { parseArgs } from "node:util";
16import { parseJsonc } from "./jsonc.mjs";
17
18const { values } = parseArgs({ options: { d1: { type: "string" }, team: { type: "string" }, aud: { type: "string" }, "public-url": { type: "string" }, zone: { type: "string" }, "mail-from": { type: "string" } } });
19if (!values.d1) throw new Error("--d1 <database id> is required");
20
21const appDir = join(dirname(fileURLToPath(import.meta.url)), "..", "apps", "diffinery");
22const cfg = parseJsonc(readFileSync(join(appDir, "wrangler.jsonc"), "utf8"));
23delete cfg.env;
24delete cfg.$schema;
25cfg.d1_databases[0].database_id = values.d1;
26if (values.team) cfg.vars.ACCESS_TEAM_DOMAIN = values.team;
27if (values.aud) cfg.vars.ACCESS_AUD = values.aud;
28if (values["public-url"]) {
29 const url = new URL(values["public-url"]);
30 if (url.protocol !== "https:" || url.pathname !== "/") throw new Error("--public-url must be an https origin, like https://git.example.com");
31 cfg.vars.PUBLIC_URL = url.origin;
32 const zone = values.zone ?? url.hostname.split(".").slice(-2).join(".");
33 cfg.routes = [{ pattern: `${url.hostname}/*`, zone_name: zone }];
34 cfg.vars.MAIL_FROM = `notifications@${url.hostname}`;
35}
36if (values["mail-from"]) cfg.vars.MAIL_FROM = values["mail-from"];
37// A runner image already in the registry (scripts/runner-image.sh): containers use it
38// instead of building the Dockerfile on every deploy.
39if (process.env.RUNNER_IMAGE) {
40 // Named as the runner reports it (`runner.image` on a job), for /meta and the Live test.
41 cfg.vars.RUNNER_IMAGE = process.env.RUNNER_IMAGE.split("/").pop();
42 for (const c of cfg.containers) {
43 c.image = process.env.RUNNER_IMAGE;
44 delete c.image_build_context;
45 }
46}
47// The site key of the Turnstile widget scripts/turnstile.sh set up for this hostname (not a
48// secret). One set in wrangler.jsonc is the operator's own and wins; turnstile.sh then leaves it alone.
49if (process.env.TURNSTILE_SITE_KEY && !cfg.vars.TURNSTILE_SITE_KEY) cfg.vars.TURNSTILE_SITE_KEY = process.env.TURNSTILE_SITE_KEY;
50writeFileSync(join(appDir, "wrangler.deploy.jsonc"), `// Generated by scripts/render-config.mjs; do not edit.\n${JSON.stringify(cfg, null, 2)}\n`);
51console.log(`wrote ${join(appDir, "wrangler.deploy.jsonc")}`);