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.

84 lines · 4.3 KBRaw History
1#!/usr/bin/env bash
2# Sets up an agent environment (a Claude Code cloud environment, Codex, a CI runner, a dev box) to work
3# on __DIFFINERY_REPO__, as its Settings → Agent setup page on Diffinery shows:
4#
5# curl -fsSL __DIFFINERY_URL__/__DIFFINERY_REPO__/agent-setup.sh | bash
6#
7# 1. Installs the diffinery CLI and puts it on PATH (/usr/local/bin/diffinery when that's writable),
8# skipping the download when the installed CLI is already the server's current build.
9# 2. Runs `diffinery setup --repo __DIFFINERY_REPO__`: git and gh use the token in DIFFINERY_TOKEN (gh
10# through GH_ENTERPRISE_TOKEN and GH_HOST), read from the environment each time and never written to
11# disk; the repository is cloned unless it's there (DIFFINERY_NO_CLONE=1 skips that, and
12# DIFFINERY_CLONE_DIR says where); then a self-test, one line per check, and a report to the page.
13#
14# Safe to run every time a session starts, fully non-interactive, and it never prints the token.
15# This script holds no secret: Diffinery serves the same one to anyone, with the repository's name in it.
16# It exits 1 when the CLI can't be installed or a check fails, so a broken setup isn't kept. Without
17# DIFFINERY_TOKEN it sets up what it can, says what to add, and exits 0.
18
19if [ -z "${BASH_VERSION:-}" ]; then
20 echo "This script needs bash: curl -fsSL __DIFFINERY_URL__/__DIFFINERY_REPO__/agent-setup.sh | bash" >&2
21 exit 1
22fi
23set -uo pipefail
24
25server=__DIFFINERY_URL__
26repo=__DIFFINERY_REPO__
27cli_sha256=__DIFFINERY_CLI_SHA256__
28root=${DIFFINERY_INSTALL:-$HOME/.diffinery}
29# Where the diffinery command is linked from, when it's writable (running as root).
30link_dir=${DIFFINERY_LINK_DIR:-/usr/local/bin}
31host=${server#*://}
32page="$server/$repo/settings/agent-setup"
33
34if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
35 green=$'\033[32m' red=$'\033[31m' bold=$'\033[1m' reset=$'\033[0m'
36else
37 green='' red='' bold='' reset=''
38fi
39say() { printf '%s\n' "$*"; }
40fail() {
41 say "${red}✗${reset} $*"
42 exit 1
43}
44
45say "${bold}Diffinery agent setup for $repo${reset}"
46command -v curl >/dev/null || fail "curl is required"
47command -v git >/dev/null || fail "git is required: install it in the setup script first (apt-get install -y git)"
48original_path=$PATH
49
50sha256() { if command -v sha256sum >/dev/null; then sha256sum "$1"; else shasum -a 256 "$1"; fi | cut -d' ' -f1; }
51
52# 1. The CLI.
53installed=$root/lib/diffinery.mjs
54if [ -f "$installed" ] && [ "$(sha256 "$installed")" = "$cli_sha256" ] && "$root/bin/diffinery" --version >/dev/null 2>&1; then
55 say "${green}✓${reset} diffinery CLI: already the current build"
56else
57 # With /usr/local/bin to link from (root in a container or VM), the CLI leaves startup files alone.
58 no_rc=${DIFFINERY_NO_MODIFY_PATH:-}
59 if [ -d "$link_dir" ] && [ -w "$link_dir" ]; then no_rc=1; fi
60 installer=$(curl -fsSL "$server/install") || fail "couldn't download $server/install: allow $host in the environment's network settings (Custom with $host, or Full)"
61 # The installer's own next steps (sign in through a browser, PATH) are for people: shown only if it fails.
62 if ! out=$(printf '%s\n' "$installer" | DIFFINERY_URL=$server DIFFINERY_INSTALL=$root DIFFINERY_NO_MODIFY_PATH=$no_rc bash 2>&1); then
63 printf '%s\n' "$out"
64 fail "the diffinery CLI didn't install (see above)"
65 fi
66 say "${green}✓${reset} diffinery CLI: installed $("$root/bin/diffinery" --version 2>/dev/null)"
67fi
68if [ -d "$link_dir" ] && [ -w "$link_dir" ]; then
69 ln -sfn "$root/bin/diffinery" "$link_dir/diffinery" || fail "couldn't link $link_dir/diffinery"
70fi
71
72# 2. git, gh, the clone and the self-test. The original PATH is what the PATH check looks at.
73export PATH="$root/bin:$PATH"
74if [ -z "${DIFFINERY_TOKEN:-}" ]; then
75 # Without the token git still gets its credential helper, which reads DIFFINERY_TOKEN once it's set.
76 DIFFINERY_URL=$server diffinery auth setup-git >/dev/null 2>&1 || true
77 say "${red}✗${reset} DIFFINERY_TOKEN is not set: generate a token on $page and add the Environment variables shown there."
78 say " git and the CLI are set up and will use the token once it's in the environment; run this again then to check."
79 exit 0
80fi
81if [ -n "${DIFFINERY_REPO:-}" ] && [ "$DIFFINERY_REPO" != "$repo" ]; then
82 say "note: DIFFINERY_REPO is $DIFFINERY_REPO, but this script sets up $repo"
83fi
84DIFFINERY_SETUP_PATH=$original_path diffinery setup --repo "$repo" --url "$server"