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.

Cut-off prep: the GitHub sync runs only by hand, and a script points a checkout at Diffinery (#179)

The last commit GitHub's copy gets. Pushes to GitHub no longer sync to Diffinery,
the manual run gains a secrets-only option (to copy secrets into a fresh import), and
scripts/use-diffinery.sh switches a checkout cloned from GitHub to
diffinery.com/codician/diffinery with DIFFINERY_TOKEN from a credential helper.


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

Co-authored-by: Claude <noreply@anthropic.com>
Canberk Demirci authored · GitHub committed signed1 parent 87cf8fecommit ec73e4444df45c559747eec0d1e4db8dcb842582Browse files
2 files changed+49−2
modified.github/workflows/sync-to-diffinery.yml+11−2View file
@@ -7,14 +7,21 @@
77 #
88 # Secrets go straight from GitHub's secret store to Diffinery's over HTTPS and are
99 # never printed. Needs DIFFINERY_LIVE_TOKEN (an admin token on diffinery.com).
10+#
11+# Manual only since the cut-off: Diffinery (codician/diffinery) is this repository's home,
12+# GitHub's copy is frozen, and pushes here are no longer copied over. The file stays as a
13+# record and for one last manual run if ever needed.
1014 on:
11- push:
1215 workflow_dispatch:
1316 inputs:
1417 allow_secrets:
1518 description: Reason for pushing past Diffinery's push protection (admins only, audited). Leave empty normally.
1619 type: string
1720 default: ""
21+ secrets_only:
22+ description: Only copy the secrets and variables (to a repository that already has the code, such as a fresh import)
23+ type: boolean
24+ default: false
1825
1926 permissions:
2027 contents: read
@@ -92,11 +99,13 @@
9299 done
93100
94101 - uses: actions/checkout@v4
102+ if: ${{ !inputs.secrets_only }}
95103 with:
96104 fetch-depth: 0
97105 lfs: true
98106
99107 - name: Push the branch or tag (a manual run pushes all of them)
108+ if: ${{ !inputs.secrets_only }}
100109 env:
101110 ALLOW_SECRETS: ${{ inputs.allow_secrets }}
102111 run: |
@@ -135,7 +144,7 @@
135144
136145 - name: Wait for Actions on Diffinery
137146 # Pushes to main start CI (and, once Diffinery deploys, the deploy) there.
138- if: github.ref == 'refs/heads/main'
147+ if: ${{ github.ref == 'refs/heads/main' && !inputs.secrets_only }}
139148 # A backstop above the script's own 75-minute deadline, in case a request hangs.
140149 timeout-minutes: 80
141150 run: scripts/diffinery-wait-runs.sh "$ORG/$NAME" "${{ steps.push.outputs.want }}" 75
addedscripts/use-diffinery.sh+38−0View file
@@ -1,0 +1,38 @@
1+#!/usr/bin/env bash
2+# Points a checkout cloned from GitHub at this repository's home on Diffinery
3+# (diffinery.com/codician/diffinery). GitHub stopped receiving changes at the cut-off.
4+#
5+# scripts/use-diffinery.sh
6+#
7+# Needs DIFFINERY_TOKEN. Git reads it through a credential helper that looks at the
8+# environment, so the token is never written to disk or put on a command line. GitHub
9+# stays as a fetch-only remote named "github". When the checkout is clean, the current
10+# branch moves forward to Diffinery's copy of it, or to Diffinery's main if the branch
11+# is new and starts from GitHub's frozen main.
12+set -euo pipefail
13+[ -n "${DIFFINERY_TOKEN:-}" ] || { echo "DIFFINERY_TOKEN is not set" >&2; exit 1; }
14+url=${DIFFINERY_REPO_URL:-https://diffinery.com/codician/diffinery.git}
15+
16+git config --global credential.https://diffinery.com.helper \
17+ '!f() { [ "$1" = get ] && printf "username=x-token\npassword=%s\n" "$DIFFINERY_TOKEN"; }; f'
18+
19+if [ "$(git remote get-url origin 2>/dev/null || true)" != "$url" ]; then
20+ if git remote get-url origin >/dev/null 2>&1 && ! git remote get-url github >/dev/null 2>&1; then git remote rename origin github; fi
21+ if git remote get-url origin >/dev/null 2>&1; then git remote set-url origin "$url"; else git remote add origin "$url"; fi
22+fi
23+git remote get-url github >/dev/null 2>&1 && git remote set-url --push github nothing-goes-back-to-github
24+git fetch -q origin
25+git remote set-head origin -a >/dev/null 2>&1 || true
26+
27+branch=$(git symbolic-ref -q --short HEAD || true)
28+if [ -n "$branch" ] && [ -z "$(git status --porcelain)" ]; then
29+ for base in "origin/$branch" origin/main; do
30+ if git rev-parse -q --verify "$base" >/dev/null && git merge-base --is-ancestor HEAD "$base"; then
31+ git merge -q --ff-only "$base"
32+ echo "$branch is now at $base ($(git rev-parse --short HEAD))"
33+ break
34+ fi
35+ done
36+ if git rev-parse -q --verify "origin/$branch" >/dev/null; then git branch -q --set-upstream-to="origin/$branch"; fi
37+fi
38+echo "origin is $url. Push there; use https://diffinery.com/api/v3 with the same token for pull requests."