@bigrandall/rrangler 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -55,6 +55,7 @@ Mirrors wrangler — `publish` aliases to `deploy`, `kv:namespace` works too.
55
55
  | `tail <slug>` | stream runtime logs |
56
56
  | `worker env set <slug> K=V …` / `delete` | env vars (`--secret` to mask) |
57
57
  | `worker builds <slug>` / `build <slug> [--branch]` / `build-log <slug> <id>` | git builds |
58
+ | `worker git get \| set \| disconnect <slug>` | connect a repo (see [Git connect](#git-connect)) |
58
59
  | `worker cron <slug> [--dlq]` / `cron replay <slug> <runId>` | cron runs + DLQ replay |
59
60
  | `secret put <KEY> --worker <slug>` | set a secret (value from `--value` or stdin) |
60
61
  | `secret list \| delete` | manage secrets |
@@ -72,6 +73,7 @@ Mirrors wrangler — `publish` aliases to `deploy`, `kv:namespace` works too.
72
73
  | `r2 object put <bucket> <key> <file>` / `get` / `delete` | R2 objects |
73
74
  | `pages list` / `get <slug>` | Pages projects |
74
75
  | `pages env set\|delete` / `builds` / `build [--branch]` / `build-log` / `tail` | Pages ops |
76
+ | `pages git get \| set \| disconnect <slug>` | connect a repo (see [Git connect](#git-connect)) |
75
77
  | `api <METHOD> <path> [--data '<json>']` | raw API passthrough |
76
78
 
77
79
  Global flags: `--json` (machine-readable stdout), `--api`, `--token`.
@@ -93,6 +95,45 @@ Global flags: `--json` (machine-readable stdout), `--api`, `--token`.
93
95
  to it). `files` is optional — omit it to send just `main`. A `wrangler.toml`
94
96
  with `name` / `main` is read as a fallback for drop-in compatibility.
95
97
 
98
+ ## Git connect
99
+
100
+ Beyond wrangler: point a worker or Pages project at a GitHub repo so it
101
+ auto-builds on push. This is server-side (the edge build runner clones + builds)
102
+ — distinct from `deploy`, which uploads your local files directly.
103
+
104
+ ```sh
105
+ # connect a repo, monorepo subdirectory + build command
106
+ rrangler worker git set my-api \
107
+ --repo https://github.com/me/monorepo.git \
108
+ --branch main \
109
+ --root-dir apps/api \
110
+ --build-command 'npm ci && npm run build' \
111
+ --output-file dist/index.js
112
+
113
+ rrangler worker git get my-api # inspect current config
114
+ rrangler worker git disconnect my-api # back to editor/upload mode
115
+
116
+ # Pages is the same, minus the worker-only output-file/entry flags
117
+ rrangler pages git set my-site --repo … --root-dir apps/site --output-dir dist
118
+ ```
119
+
120
+ Flags (all optional; only the ones you pass change — it's a partial update):
121
+
122
+ | flag | meaning |
123
+ | --- | --- |
124
+ | `--repo <url>` | HTTPS clone URL (empty to clear) |
125
+ | `--branch <b>` | production branch (default `main`) |
126
+ | `--root-dir <path>` | **monorepo**: subdir the project lives in; build runs there, output paths are relative to it |
127
+ | `--build-command '<cmd>'` | shell build (blank = zero-config) |
128
+ | `--output-dir <d>` | build output dir |
129
+ | `--output-file <f>` / `--output-entry <e>` | worker-only: single-bundle file / entry |
130
+ | `--git-token <t>` | PAT for private repos (`-` to clear; omit to keep) |
131
+ | `--use-app-auth` / `--no-app-auth` | use the GitHub App for clones instead of a PAT |
132
+ | `--build-env '<json>'` | build-time env vars, as a JSON object |
133
+
134
+ Setting git config doesn't trigger a build — run one with
135
+ `rrangler worker build <slug>` / `pages build <slug>` afterwards.
136
+
96
137
  ## Beyond wrangler
97
138
 
98
139
  - `doctor` — one-shot health + capability probe (what your token can actually do).
package/bin/rrangler.mjs CHANGED
@@ -29,6 +29,9 @@ const ROUTES = {
29
29
  "worker build-log": cmd.workerBuildLog,
30
30
  "worker env set": cmd.workerEnvSet,
31
31
  "worker env delete": cmd.workerEnvDelete,
32
+ "worker git get": cmd.workerGitGet,
33
+ "worker git set": cmd.workerGitSet,
34
+ "worker git disconnect": cmd.workerGitDisconnect,
32
35
  "worker cron": cmd.workerCron,
33
36
  "worker cron replay": cmd.workerCronReplay,
34
37
 
@@ -68,6 +71,9 @@ const ROUTES = {
68
71
  "pages get": cmd.pagesGet,
69
72
  "pages env set": cmd.pagesEnvSet,
70
73
  "pages env delete": cmd.pagesEnvDelete,
74
+ "pages git get": cmd.pagesGitGet,
75
+ "pages git set": cmd.pagesGitSet,
76
+ "pages git disconnect": cmd.pagesGitDisconnect,
71
77
  "pages builds": cmd.pagesBuilds,
72
78
  "pages build": cmd.pagesBuild,
73
79
  "pages build-log": cmd.pagesBuildLog,
@@ -132,6 +138,11 @@ ${style.bold("workers")}
132
138
  rrangler worker builds <slug>
133
139
  rrangler worker build <slug> [--branch b] trigger a git build
134
140
  rrangler worker build-log <slug> <buildId> [--tail N]
141
+ rrangler worker git get <slug> show git-connect config
142
+ rrangler worker git set <slug> [--repo url] [--branch b] [--root-dir path]
143
+ [--build-command '…'] [--output-file f | --output-dir d] [--output-entry e]
144
+ [--git-token t|-] [--use-app-auth|--no-app-auth] [--build-env '<json>']
145
+ rrangler worker git disconnect <slug>
135
146
  rrangler worker cron <slug> [--dlq] [--limit N]
136
147
  rrangler worker cron replay <slug> <runId>
137
148
  rrangler secret put <KEY> --worker <slug> [--value v]
@@ -171,6 +182,11 @@ ${style.bold("pages")}
171
182
  rrangler pages build <slug> [--branch b]
172
183
  rrangler pages build-log <slug> <buildId>
173
184
  rrangler pages tail <slug>
185
+ rrangler pages git get <slug> show git-connect config
186
+ rrangler pages git set <slug> [--repo url] [--branch b] [--root-dir path]
187
+ [--build-command '…'] [--output-dir d] [--git-token t|-]
188
+ [--use-app-auth|--no-app-auth] [--build-env '<json>']
189
+ rrangler pages git disconnect <slug>
174
190
 
175
191
  ${style.bold("power")}
176
192
  rrangler api <METHOD> <path> [--data '<json>'] raw API call
@@ -185,7 +201,7 @@ async function main() {
185
201
  return;
186
202
  }
187
203
  if (argv[0] === "--version" || argv[0] === "-v" || argv[0] === "version") {
188
- process.stdout.write("rrangler 0.1.0\n");
204
+ process.stdout.write("rrangler 0.2.0\n");
189
205
  return;
190
206
  }
191
207
 
@@ -190,6 +190,118 @@ export async function workerEnvDelete({ pos }) {
190
190
  ok(`deleted ${del.join(", ")} from ${w.slug}`);
191
191
  }
192
192
 
193
+ // ── git connect (workers + pages share the same shape) ─────────────
194
+
195
+ // Flag → API-body key. `kind` adds the worker-only output-file/entry.
196
+ function gitBodyFromFlags(flags, kind) {
197
+ const map = {
198
+ repo: "repoUrl",
199
+ "repo-url": "repoUrl",
200
+ branch: "branch",
201
+ root: "rootDir",
202
+ "root-dir": "rootDir",
203
+ "build-command": "buildCommand",
204
+ "output-dir": "outputDir",
205
+ // NB: not `--token` — that's the global API-auth override flag.
206
+ "git-token": "token",
207
+ pat: "token",
208
+ };
209
+ if (kind === "worker") {
210
+ map["output-file"] = "outputFile";
211
+ map["output-entry"] = "outputEntry";
212
+ }
213
+ const body = {};
214
+ for (const [flag, key] of Object.entries(map)) {
215
+ if (flag in flags) body[key] = flags[flag] === true ? "" : String(flags[flag]);
216
+ }
217
+ // --use-app-auth / --no-app-auth toggle GitHub-App clone auth.
218
+ if ("use-app-auth" in flags) body.useAppAuth = flags["use-app-auth"] !== "false";
219
+ if ("no-app-auth" in flags) body.useAppAuth = false;
220
+ if ("build-env" in flags) {
221
+ try {
222
+ body.buildEnv = JSON.parse(String(flags["build-env"]));
223
+ } catch {
224
+ throw new Error("--build-env must be a valid JSON object string");
225
+ }
226
+ }
227
+ return body;
228
+ }
229
+
230
+ function printGit(g) {
231
+ if (!g) return;
232
+ const rows = [
233
+ ["repo", g.repoUrl || "—"],
234
+ ["branch", g.branch || "(default: main)"],
235
+ ["root / subdir", g.rootDir || "(repo root)"],
236
+ ["build command", g.buildCommand || "(none — zero-config)"],
237
+ ];
238
+ if ("outputFile" in g) rows.push(["output file", g.outputFile || "—"]);
239
+ rows.push(["output dir", g.outputDir || "—"]);
240
+ if ("outputEntry" in g) rows.push(["output entry", g.outputEntry || "—"]);
241
+ rows.push(["github app auth", g.useAppAuth ? "yes" : "no"]);
242
+ rows.push(["token", g.hasToken ? "set" : "—"]);
243
+ rows.push(["last built", g.lastBuiltCommit || "—"]);
244
+ table(["field", "value"], rows);
245
+ }
246
+
247
+ const GIT_SET_USAGE =
248
+ "[--repo url] [--branch b] [--root-dir path] [--build-command '…'] " +
249
+ "[--output-dir d] [--git-token t|-] [--use-app-auth|--no-app-auth] [--build-env '<json>']";
250
+
251
+ export async function workerGitGet({ pos, flags }) {
252
+ const w = await resolveWorker(pos[0]);
253
+ const res = await api("GET", `workers/${w.id}/git`);
254
+ if (asJson(flags)) return printJson(res);
255
+ printGit(res.git);
256
+ }
257
+
258
+ export async function workerGitSet({ pos, flags }) {
259
+ const body = gitBodyFromFlags(flags, "worker");
260
+ if (Object.keys(body).length === 0) {
261
+ throw new Error(
262
+ `usage: rrangler worker git set <slug> ${GIT_SET_USAGE} [--output-file f] [--output-entry e]`,
263
+ );
264
+ }
265
+ const w = await resolveWorker(pos[0]);
266
+ const res = await api("POST", `workers/${w.id}/git`, { json: body });
267
+ if (asJson(flags)) return printJson(res);
268
+ ok(`git config updated on ${w.slug}`);
269
+ printGit(res.git);
270
+ }
271
+
272
+ export async function workerGitDisconnect({ pos, flags }) {
273
+ const w = await resolveWorker(pos[0]);
274
+ const res = await api("DELETE", `workers/${w.id}/git`);
275
+ if (asJson(flags)) return printJson(res);
276
+ ok(`disconnected ${w.slug} from git`);
277
+ }
278
+
279
+ export async function pagesGitGet({ pos, flags }) {
280
+ const p = await resolvePages(pos[0]);
281
+ const res = await api("GET", `pages/${p.id}/git`);
282
+ if (asJson(flags)) return printJson(res);
283
+ printGit(res.git);
284
+ }
285
+
286
+ export async function pagesGitSet({ pos, flags }) {
287
+ const body = gitBodyFromFlags(flags, "pages");
288
+ if (Object.keys(body).length === 0) {
289
+ throw new Error(`usage: rrangler pages git set <slug> ${GIT_SET_USAGE}`);
290
+ }
291
+ const p = await resolvePages(pos[0]);
292
+ const res = await api("POST", `pages/${p.id}/git`, { json: body });
293
+ if (asJson(flags)) return printJson(res);
294
+ ok(`git config updated on ${p.slug}`);
295
+ printGit(res.git);
296
+ }
297
+
298
+ export async function pagesGitDisconnect({ pos, flags }) {
299
+ const p = await resolvePages(pos[0]);
300
+ const res = await api("DELETE", `pages/${p.id}/git`);
301
+ if (asJson(flags)) return printJson(res);
302
+ ok(`disconnected ${p.slug} from git`);
303
+ }
304
+
193
305
  export async function workerCron({ pos, flags }) {
194
306
  const w = await resolveWorker(pos[0]);
195
307
  const out = await api("GET", `workers/${w.id}/cron-runs`, { query: { dlq: flags.dlq ? 1 : undefined, limit: flags.limit } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigrandall/rrangler",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "wrangler-compatible CLI for RandallFlare — the self-hosted Cloudflare-Workers edge platform in bigrandall.io. Deploy workers, manage D1/KV/R2, tail logs, run locally on workerd.",
5
5
  "type": "module",
6
6
  "bin": {