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.

Let workflow env override runner defaults; run sync and live test on GitHub only (#14)

Workflow and step env now override the runner's CI and DIFFINERY defaults, as
on GitHub; GITHUB_* and RUNNER_* stay fixed. The DIFFINERY=true default had
replaced the workflows' DIFFINERY URL when they ran on Diffinery.


Claude-Session: https://claude.ai/code/session_01AizKXSsengXZRegJxRATkL

Co-authored-by: Claude <noreply@anthropic.com>
Canberk Demirci authored · GitHub committed signed1 parent cb1fccacommit 7a1eadcb27f569dc3122a8365f3b3e5ba0979552Browse files
5 files changed+27−4
Files (5)
modified.github/workflows/deploy.yml+1−1View file
@@ -19,7 +19,7 @@
1919 deploy:
2020 name: Deploy to Cloudflare
2121 # Production deploys from one host only. This repository is mirrored to
22- # diffinery.com (see move-to-diffinery.yml); switch this to
22+ # diffinery.com (see sync-to-diffinery.yml); switch this to
2323 # 'https://diffinery.com' to make Diffinery the one that deploys.
2424 if: ${{ github.server_url == 'https://github.com' }}
2525 runs-on: ubuntu-latest
modified.github/workflows/live-test.yml+2−1View file
@@ -24,7 +24,8 @@
2424 jobs:
2525 live:
2626 name: Containers, sandboxes, webhooks, schedules and LFS
27- if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
27+ # Runs on the host that deploys production (see the gate in deploy.yml).
28+ if: ${{ github.server_url == 'https://github.com' && (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success') }}
2829 runs-on: ubuntu-latest
2930 timeout-minutes: 30
3031 env:
modified.github/workflows/sync-to-diffinery.yml+2−0View file
@@ -26,6 +26,8 @@
2626 jobs:
2727 move:
2828 name: Copy code, secrets and variables, then check Actions on Diffinery
29+ # Runs on GitHub only; the copy on Diffinery has nothing to sync to.
30+ if: ${{ github.server_url == 'https://github.com' }}
2931 runs-on: ubuntu-latest
3032 timeout-minutes: 90
3133 environment: production
modifiedcontainers/runner/src/job.ts+12−2View file
@@ -411,9 +411,19 @@
411411 return evaluate(expr, ctx, this.statusFns(scope), this.extra());
412412 }
413413
414+ /**
415+ * Layers workflow env over the runner's defaults. Like GitHub, workflows can
416+ * override defaults such as CI or DIFFINERY, but not GITHUB_* or RUNNER_*.
417+ */
418+ withDefaults(envCtx: Record<string, string>): Record<string, string> {
419+ const env = { ...this.defaultEnv, ...envCtx };
420+ for (const [k, v] of Object.entries(this.defaultEnv)) if (/^(GITHUB|RUNNER)_/.test(k)) env[k] = v;
421+ return env;
422+ }
423+
414424 /** Builds the environment for a child process. */
415425 processEnv(envCtx: Record<string, string>, extra: Record<string, string> = {}): NodeJS.ProcessEnv {
416- const env: NodeJS.ProcessEnv = { ...this.baseEnv, ...envCtx, ...this.defaultEnv, ...extra };
426+ const env: NodeJS.ProcessEnv = { ...this.baseEnv, ...this.withDefaults(envCtx), ...extra };
417427 const basePath = envCtx.PATH ?? this.baseEnv.PATH ?? "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
418428 env.PATH = [...this.pathAccum, basePath].filter(Boolean).join(path.delimiter);
419429 return env;
@@ -580,7 +590,7 @@
580590 let cmd = argv;
581591 let cwd = o.cwd;
582592 let env = this.processEnv(o.envCtx, { ...(o.extraEnv ?? {}), ...files });
583- if (o.wrap) ({ argv: cmd, cwd, env } = o.wrap(argv, { ...o.envCtx, ...this.defaultEnv, ...(o.extraEnv ?? {}), ...files }, o.cwd));
593+ if (o.wrap) ({ argv: cmd, cwd, env } = o.wrap(argv, { ...this.withDefaults(o.envCtx), ...(o.extraEnv ?? {}), ...files }, o.cwd));
584594 const res = await exec(cmd[0]!, cmd.slice(1), {
585595 cwd,
586596 env,
modifiedcontainers/runner/test/job.test.ts+10−0View file
@@ -547,6 +547,16 @@
547547 expect(c.conclusion).toBe("success");
548548 expect(api.logText(0)).toMatch(/wd=pkg shell=\S+\.sh e=var-inp-out/);
549549 });
550+
551+ it("lets workflow env override CI and DIFFINERY but not GITHUB_* or RUNNER_*", async () => {
552+ const c = await run(
553+ makeSpec(api, [{ env: { CI: "step" }, run: 'echo "d=$DIFFINERY ci=$CI sha=$GITHUB_SHA os=$RUNNER_OS"' }], {
554+ env: { DIFFINERY: "https://diffinery.example", GITHUB_SHA: "nope", RUNNER_OS: "nope" },
555+ }),
556+ );
557+ expect(c.conclusion).toBe("success");
558+ expect(api.logText(0)).toMatch(/d=https:\/\/diffinery\.example ci=step sha=[0-9a-f]{40} os=Linux/);
559+ });
550560 });
551561
552562 describe("agent binary (esbuild bundle)", () => {