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.

Containers, registry, sandboxes, webhooks, schedules, LFS and pull requests

took 7m 32s Raw logs
Failed at Agent sandbox
Process completed with exit code 5.

base="$DIFFINERY/api/v3/repos/$OWNER/$REPO/diffinery/sandboxes"
id=$(curl -fsS --retry 1 --retry-delay 15 -X POST "$base" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{}' | jq -r .id)
echo "sandbox $id"
for i in $(seq 1 40); do
  out=$(curl -sS -X POST "$base/$id/exec" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{"cmd":"cat README.md && git lfs ls-files | wc -l"}' || true)
  jq -e '.exitCode == 0' >/dev/null 2>&1 <<<"$out" && break
  sleep 6
done
echo "$out" | jq '{exitCode, stdout}'
curl -sS -X POST "$base/$id/close" -H "Authorization: Bearer $TOKEN" >/dev/null || true
jq -e --arg r "# $REPO" '.exitCode == 0 and (.stdout | contains($r))' >/dev/null <<<"$out" || { echo "::error::the sandbox did not run the command in the repository"; exit 1; }
sandbox 2c1b2bcda006400e93290ffc09cefba8
jq: parse error: Invalid numeric literal at line 1, column 7
Set up job
Diffinery runner: job live (Containers, registry, sandboxes, webhooks, schedules, LFS and pull requests) for codician/diffinery@18106774c0d9Runner: image diffinery-runner:4d3bf17f06575e64ab4155b3, in cdg07, WEUR, container 7b99f79ae3863f5f6ae6aa6de86eb9604de9773053a6562ac846f200e0f9369cRunner size: large (4 vCPU, 12 GiB of memory, 20 GB of disk), this job uses what a smaller runner doesn't have; runs-on: diffinery-large (or -medium, -small, -tiny) sets a sizeHost: AMD EPYC (family 25, model 17), 4 vCPUs, 2550 MHzWorkspace: /workspace/diffineryHost: 0% of the vCPUs' time went to other work on the host (steal)Job completed with conclusion: failureResources: 0.0 of 4 vCPUs busy on average (0.1 at the 95th percentile), peak memory 0.4 GiB of 11.9 GiB, peak disk 1.1 GB of 19.2 GB
Check the token1s
##[group]Run if [ "$GITHUB_EVENT_NAME" = workflow_run ]; then  # Deploy's gate skips a commit that is no longer main's tip (the newer commit's run deploys it):  # then nothing new is live, and this run would only test the site as it was.  deployed=$(curl -fsS "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/actions/runs/$DEPLOY_RUN/jobs" -H "Authorization: Bearer $GH_TOKEN" | jq -r '[.jobs[] | select(.name == "Deploy to Cloudflare") | .conclusion][0] // "unknown"' || echo unknown)  if [ "$deployed" = skipped ]; then    echo "::notice::Deploy deployed nothing for $HEAD_SHA (main has moved on), so there is nothing new to test"    echo "skip=true" >> "$GITHUB_OUTPUT"    exit 0  fifiif [ -z "$TOKEN" ]; then  # After a deploy of diffinery.com a missing token is an error: a green run would mean nothing was tested.  if [ "$GITHUB_EVENT_NAME" = workflow_run ]; then    echo "::error::DIFFINERY_LIVE_TOKEN is not set in the production environment, so nothing was tested. Create a write token at $DIFFINERY/settings/tokens and save it as a production environment secret."    exit 1  fi  echo "::warning::DIFFINERY_LIVE_TOKEN is not set, so the live test is skipped. Create a write token at $DIFFINERY/settings/tokens and save it as a production environment secret."  echo "skip=true" >> "$GITHUB_OUTPUT"  exit 0filogin=$(curl -fsS "$DIFFINERY/api/v3/user" -H "Authorization: Bearer $TOKEN" | jq -r .login)echo "OWNER=$login" >> "$GITHUB_ENV"echo "testing as $login in $login/$REPO"env:  GH_TOKEN: ***  DEPLOY_RUN: 1047##[endgroup]testing as cnbrkdmrci in cnbrkdmrci/live-1048-1
Choose the registry check's image sizes1s
##[group]Run set -euo pipefail# Layers over Cloudflare's 100 MB request limit (which hosted runners push through# the registry relay) take minutes to push and pull. They're pushed on manual runs and# whenever the registry, the runner image or this test changed since the last# successful live test; other deploys push small images through the same path.full=trueif [ "$GITHUB_EVENT_NAME" = workflow_run ]; then  api() { curl -fsS "$DIFFINERY/api/v3/repos/$GITHUB_REPOSITORY$1" -H "Authorization: Bearer $TOKEN"; }  last=$(api "/actions/runs?workflow=live-test.yml&status=success&per_page=1" | jq -r '.workflow_runs[0].head_sha // empty' || true)  if [ -n "$last" ] && files=$(api "/compare/$last...$HEAD_SHA" | jq -r '.files[].filename'); then    grep -qE '^(apps/diffinery/src/registry/|containers/runner/|\.github/workflows/live-test\.yml$)' <<<"$files" || full=false    echo "changed since $last: $(wc -l <<<"$files") files"  fifiif [ "$full" = true ]; then  echo "BIG=150000000" >> "$GITHUB_ENV"  echo "BUILDX=120000000" >> "$GITHUB_ENV"else  echo "BIG=5000000" >> "$GITHUB_ENV"  echo "BUILDX=4000000" >> "$GITHUB_ENV"fiecho "registry check: full=$full"##[endgroup]changed since 86148f73cd8b3215ae82063fabbb9a5bde718327: 1 filesregistry check: full=false
Profile picture upload (WASM resize in the Worker)5s
##[group]Run set -euo pipefailav="$DIFFINERY/api/avatars/$OWNER"# Keep the account's current picture, if it has one, to put it back afterwards.had=$(curl -fsS -o before.webp -w '%{content_type}' "$av?s=256&v=1")restore() {  if [ "$had" = image/webp ]; then    curl -fsS -X PUT "$DIFFINERY/api/v3/user/avatar" -H "Authorization: Bearer $TOKEN" -H "content-type: image/webp" --data-binary @before.webp | jq -r '"restored the previous picture: \(.avatar_url)"'  else    curl -fsS -o /dev/null -X DELETE "$DIFFINERY/api/v3/user/avatar" -H "Authorization: Bearer $TOKEN"  fi}trap restore EXIT# A 600×400 PNG gradient; the server crops it to a square and makes small WebPs.python3 - <<'EOF'import struct, zlibw, h = 600, 400rows = b"".join(b"\0" + bytes(c for x in range(w) for c in (x * 255 // w, y * 255 // h, 128)) for y in range(h))chunk = lambda t, d: struct.pack(">I", len(d)) + t + d + struct.pack(">I", zlib.crc32(t + d))open("avatar.png", "wb").write(b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0)) + chunk(b"IDAT", zlib.compress(rows)) + chunk(b"IEND", b""))EOFurl=$(curl -fsS -X PUT "$DIFFINERY/api/v3/user/avatar" -H "Authorization: Bearer $TOKEN" -H "content-type: image/png" --data-binary @avatar.png | jq -r .avatar_url)echo "uploaded: $url"v=${url##*v=}type=$(curl -fsS -o small.webp -w '%{content_type}' "$av?s=64&v=$v")[ "$type" = image/webp ] || { echo "::error::expected image/webp, got $type"; exit 1; }python3 - <<'EOF'import struct, sysb = open("small.webp", "rb").read()ok = b[:4] == b"RIFF" and b[8:12] == b"WEBP"if b[12:16] == b"VP8 ":    size = (struct.unpack("<H", b[26:28])[0] & 0x3FFF, struct.unpack("<H", b[28:30])[0] & 0x3FFF)elif b[12:16] == b"VP8X":    size = (int.from_bytes(b[24:27], "little") + 1, int.from_bytes(b[27:30], "little") + 1)else:    size = Noneprint(f"64 px avatar: {len(b)} bytes, {size}")if not ok or size != (64, 64) or len(b) > 5000:    print("::error::the 64 px avatar is not a 64x64 WebP under 5 KB"); sys.exit(1)EOFcurl -fsS -X DELETE "$DIFFINERY/api/v3/user/avatar" -H "Authorization: Bearer $TOKEN" >/dev/null# A `v` that is not current bypasses the edge cache, so this sees the removal from any colo.type=$(curl -fsS -o /dev/null -w '%{content_type}' "$av?s=64&v=1")[[ "$type" == image/svg+xml* ]] || { echo "::error::after removal expected the initials SVG, got $type"; exit 1; }echo "removed: initials again ($type)"##[endgroup]uploaded: https://diffinery.com/api/avatars/cnbrkdmrci?v=179296823164 px avatar: 256 bytes, (64, 64)removed: initials again (image/svg+xml; charset=utf-8)restored the previous picture: https://diffinery.com/api/avatars/cnbrkdmrci?v=1792968233
Public docs are served without signing in1s
##[group]Run set -euo pipefailcheck() { # path, content type, text it must contain  body=$(curl -fsS -D /tmp/h "$DIFFINERY$1")  grep -qi "content-type: $2" /tmp/h || { echo "::error::$1 is not $2"; exit 1; }  grep -qF -- "$3" <<<"$body" || { echo "::error::$1 doesn't contain: $3"; exit 1; }  echo "$1 ok ($(wc -c <<<"$body") bytes)"}check /docs "text/html" "Overview"check /docs/actions/workflow-syntax "text/html" "View as Markdown"check /docs/quickstart.md "text/markdown" "# Quickstart"check /llms.txt "text/plain" "/docs/actions/workflow-syntax.md"check /llms-full.txt "text/plain" "# REST API reference"check /docs/api/openapi.json "application/json" '"openapi": "3.1.0"'check /-/cli/diffinery.mjs "text/javascript" "#!/usr/bin/env node"md=$(curl -fsS -H "Accept: text/markdown" "$DIFFINERY/docs/agents/mcp")grep -q "^# MCP" <<<"$md" || { echo "::error::Accept: text/markdown didn't return Markdown"; exit 1; }curl -fsS "$DIFFINERY/-/cli/diffinery.mjs" -o /tmp/diffinery.mjs && node /tmp/diffinery.mjs --version##[endgroup]/docs ok (104154 bytes)/docs/actions/workflow-syntax ok (190219 bytes)/docs/quickstart.md ok (17955 bytes)/llms.txt ok (32378 bytes)/llms-full.txt ok (2851870 bytes)/docs/api/openapi.json ok (865461 bytes)/-/cli/diffinery.mjs ok (259606 bytes)diffinery 0.1.0
Email sending is configured0s
##[group]Run set -euo pipefails=$(curl -sS -w '\n%{http_code}' "$DIFFINERY/api/v3/diffinery/admin/email" -H "Authorization: Bearer $TOKEN")code=${s##*$'\n'}; s=${s%$'\n'*}# Only a site administrator's token reads the email settings, and the live-test account isn't one.if [ "$code" = 403 ]; then echo "::notice::skipped: the live-test token isn't a site administrator's"; exit 0; fi[ "$code" = 200 ] || { echo "::error::/diffinery/admin/email answered $code"; exit 1; }echo "$s" | jq '{sending, queue, from, last_24h}'[ "$(jq -r .sending <<<"$s")" = true ] || { echo "::error::the Worker has no Email Sending binding"; exit 1; }[ "$(jq -r .queue <<<"$s")" = true ] || { echo "::error::the Worker has no mail queue binding"; exit 1; }failed=$(jq -r .last_24h.failed <<<"$s")[ "$failed" = 0 ] || echo "::warning::$failed emails failed in the last 24 hours; see Settings -> Email in site administration"##[endgroup]{  "sending": true,  "queue": true,  "from": "notifications@diffinery.com",  "last_24h": {    "sent": 12,    "failed": 0,    "skipped": 0  }}
Create a throwaway repository with a webhook2s
##[group]Run set -euo pipefailapi() { curl -fsS -X "$1" "$DIFFINERY/api/v3$2" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" ${3:+--data "$3"}; }api POST /user/repos "{\"name\":\"$REPO\",\"private\":true}" >/dev/null# Webhooks may only reach public hosts other than Diffinery itself; the push's delivery goes to example.com.code=$(curl -sS -o /dev/null -w '%{http_code}' -X POST "$DIFFINERY/api/v3/repos/$OWNER/$REPO/hooks" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data "{\"config\":{\"url\":\"$DIFFINERY/healthz\"},\"events\":[\"push\"]}")[ "$code" = 422 ] || { echo "::error::a webhook to Diffinery itself answered $code, not 422"; exit 1; }api POST "/repos/$OWNER/$REPO/hooks" "{\"config\":{\"url\":\"https://example.com/diffinery-live-test\"},\"events\":[\"push\"]}" >/dev/nullecho "created $OWNER/$REPO"##[endgroup]created cnbrkdmrci/live-1048-1
Wait for jobs to start on the deployed runner image15s
##[group]Run set -euo pipefail# A deploy's container rollout updates instances over a while after it starts, and an# instance not yet updated starts jobs on the previous runner image. Jobs report their# image (`runner.image`), so a probe workflow runs until three jobs in a row land on the# image the deploy set (/meta's runner_image) before the Docker and registry checks.api() { curl -fsS -X "$1" "$DIFFINERY/api/v3$2" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" ${3:+--data "$3"}; }expected=$(api GET /meta | jq -r '.runner_image // empty')if [ -z "$expected" ]; then  echo "::warning::/meta doesn't name the deployed runner image, so jobs aren't checked against it"  exit 0fiecho "DEPLOYED_RUNNER_IMAGE=$expected" >> "$GITHUB_ENV"mkdir -p src/.github/workflows && cd srcgit init -q -b maingit config user.name "Live test" && git config user.email "live-test@diffinery.com"cat > .github/workflows/probe.yml <<'EOF'on: workflow_dispatchjobs:  probe:    runs-on: ubuntu-latest    strategy:      matrix:        n: [1, 2, 3]    steps:      - run: echo "probe ok"EOFgit add -A && git commit -q -m "Runner image probe"git push -q "https://x-token:${TOKEN}@${DIFFINERY#https://}/$OWNER/$REPO.git" maindeadline=$(( $(date +%s) + 15 * 60 ))while :; do  before=$(api GET "/repos/$OWNER/$REPO/actions/runs?event=workflow_dispatch" | jq '.workflow_runs | length')  api POST "/repos/$OWNER/$REPO/actions/workflows/probe.yml/dispatches" '{"ref":"main"}' >/dev/null  run=""  # Up to 10 minutes: a job turned away from a replaced image starts again after 30 s, 1, 2 and 4 minutes.  for i in $(seq 1 120); do    runs=$(api GET "/repos/$OWNER/$REPO/actions/runs?event=workflow_dispatch")    if [ "$(jq '.workflow_runs | length' <<<"$runs")" -gt "$before" ]; then      run=$(jq -c '.workflow_runs[0]' <<<"$runs")      [ "$(jq -r .status <<<"$run")" = completed ] && break    fi    sleep 5  done  [ -n "$run" ] || { echo "::error::the probe workflow didn't start"; exit 1; }  probe=$(api GET "/repos/$OWNER/$REPO/actions/runs/$(jq -r .id <<<"$run")/jobs")  images=$(jq -r '.jobs[] | .runner.image // "no image reported"' <<<"$probe")  echo "probe jobs ran on: $(sort <<<"$images" | uniq -c | sed 's/^ *//' | paste -sd ','), started again $(jq '[.jobs[].placementTries // 0] | add // 0' <<<"$probe") time(s) in all"  [ "$(grep -cxF "$expected" <<<"$images" || true)" = 3 ] && { echo "jobs start on $expected"; exit 0; }  if [ "$(date +%s)" -ge "$deadline" ]; then    echo "::error::15 minutes after the deploy, jobs still start on a runner image other than the deployed $expected"    exit 1  fi  sleep 20done##[endgroup]probe jobs ran on: 3 diffinery-runner:4d3bf17f06575e64ab4155b3, started again 0 time(s) in alljobs start on diffinery-runner:4d3bf17f06575e64ab4155b3
Push workflows and an LFS file5s
##[group]Run set -euo pipefailmkdir -p src/.github/workflows && cd srcgit init -q -b maingit config user.name "Live test" && git config user.email "live-test@diffinery.com"git lfs install --local >/dev/nullgit lfs track "*.bin" >/dev/nullhead -c 3145728 /dev/urandom > blob.binsha256sum blob.bin | cut -d' ' -f1 > ../blob.shaecho "# $REPO" > README.mdcat > .github/workflows/ci.yml <<'EOF'on: pushjobs:  hosted:    runs-on: ubuntu-latest    strategy:      matrix:        n: [1, 2]    steps:      - uses: actions/checkout@v4      - run: echo "live ok ${{ matrix.n }} $(cat README.md)"      # Passwordless sudo, as on GitHub's runners (`sudo apt-get install ...` is common).      - run: sudo -n true && echo "sudo ok $(sudo -n id -u)"  docker:    runs-on: ubuntu-latest    services:      cache:        image: redis:7-alpine        ports: ["6379"]        options: --health-cmd "redis-cli ping" --health-interval 1s --health-retries 30    steps:      - run: |          printf 'FROM alpine:3.20\nRUN echo built > /msg\nCMD ["cat", "/msg"]\n' > Dockerfile          docker build -q -t live-image .          echo "docker ok $(docker run --rm live-image)"          exec 3<>/dev/tcp/127.0.0.1/${{ job.services.cache.ports['6379'] }}          printf 'PING\r\n' >&3          read -r line <&3          echo "service ok ${line%$'\r'}"  # Container registry: a layer pushed with the job's GITHUB_TOKEN (over Cloudflare's  # 100 MB request limit on full runs), plus the docker/*-action route most ghcr.io  # workflows use. __BIG__ and __BUILDX__ are the layer sizes.  publish:    runs-on: ubuntu-latest    permissions:      packages: write    steps:      - run: |          image="diffinery.com/${GITHUB_REPOSITORY,,}"          echo "${{ secrets.GITHUB_TOKEN }}" | docker login diffinery.com -u "${{ github.actor }}" --password-stdin          head -c __BIG__ /dev/urandom > big.bin          sha256sum big.bin | cut -d' ' -f1 > big.sha          printf 'FROM scratch\nCOPY big.bin big.sha /\n' > Dockerfile          docker build -q -t "$image:live" .          docker push "$image:live"          echo "pushed $(cat big.sha)"  buildx:    runs-on: ubuntu-latest    permissions:      packages: write    steps:      - run: |          echo "IMAGE=diffinery.com/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"          head -c __BUILDX__ /dev/urandom > big.bin          printf 'FROM scratch\nCOPY big.bin /\n' > Dockerfile      - uses: docker/setup-buildx-action@v3      - uses: docker/login-action@v3        with:          registry: diffinery.com          username: ${{ github.actor }}          password: ${{ secrets.GITHUB_TOKEN }}      - uses: docker/build-push-action@v6        with:          context: .          push: true          tags: ${{ env.IMAGE }}:buildx  pull:    needs: [publish, buildx]    runs-on: ubuntu-latest    permissions:      packages: read    steps:      - run: |          image="diffinery.com/${GITHUB_REPOSITORY,,}"          echo "${{ secrets.GITHUB_TOKEN }}" | docker login diffinery.com -u "${{ github.actor }}" --password-stdin          docker pull -q "$image:live"          id=$(docker create "$image:live" true)          docker cp "$id:/big.bin" big.bin && docker cp "$id:/big.sha" big.sha          [ "$(sha256sum big.bin | cut -d' ' -f1)" = "$(cat big.sha)" ] && echo "registry ok $(stat -c %s big.bin) bytes"          docker pull -q "$image:buildx"          id=$(docker create "$image:buildx" true)          docker cp "$id:/big.bin" buildx.bin          echo "buildx ok $(stat -c %s buildx.bin) bytes"EOFcat > .github/workflows/tick.yml <<'EOF'on:  schedule:    - cron: "*/5 * * * *"jobs:  tick:    runs-on: ubuntu-latest    steps:      - run: echo "scheduled ok"EOFsed -i "s/__BIG__/$BIG/g; s/__BUILDX__/$BUILDX/g" .github/workflows/ci.ymlgit add -A && git commit -q -m "Live test"git push -q "https://x-token:${TOKEN}@${DIFFINERY#https://}/$OWNER/$REPO.git" maingit lfs ls-files##[endgroup]warning: re-init: ignored --initial-branch=main5f5ff32c96 * blob.bin
Web UI features (highlighting, settings pages, view transitions, base permission, invitations)3s
##[group]Run set -euo pipefailpage() { curl -fsS "$DIFFINERY$1" -H "Authorization: Bearer $TOKEN"; }has() { grep -qF -- "$2" <<<"$1" || { echo "::error::$3"; exit 1; }; }html=$(page "/$OWNER/$REPO/blob/main/.github/workflows/ci.yml")has "$html" '<td class="sh">' "the workflow file is not syntax highlighted"has "$html" "--shiki-dark" "highlighted code has no dark theme colours"has "$html" "@view-transition{navigation:auto}" "pages don't opt in to view transitions"has "$html" "prefers-reduced-motion:no-preference" "view transitions ignore reduced motion"has "$(page /settings/appearance)" 'name="appearance"' "Settings -> Appearance has no theme choice"has "$(page /notifications)" 'href="/settings/notifications"' "the notifications page doesn't link to notification settings"code=$(curl -sS -o /tmp/out -w '%{http_code}' -X POST "$DIFFINERY/api/v3/user/repos" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data "{\"name\":\"$REPO-internal\",\"visibility\":\"internal\"}")[ "$code" = 422 ] || { echo "::error::visibility internal got $code, expected 422"; curl -sS -o /dev/null -X DELETE "$DIFFINERY/api/v3/repos/$OWNER/$REPO-internal" -H "Authorization: Bearer $TOKEN"; exit 1; }org=$(page /api/v3/user/orgs | jq -r '.[0].login // empty')if [ -n "$org" ]; then  perm=$(page "/api/v3/orgs/$org" | jq -r '.default_repository_permission // empty')  case "$perm" in none|read|write|admin) echo "$org's base permission: $perm" ;; *) echo "::error::GET /orgs/$org has no default_repository_permission"; exit 1 ;; esac  # A malformed rename is refused before anything is written (422 for owners, 403 for everyone else).  code=$(curl -sS -o /tmp/out -w '%{http_code}' -X PATCH "$DIFFINERY/api/v3/orgs/$org" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{"name":123}')  case "$code" in 422|403) ;; *) echo "::error::PATCH /orgs/$org with a numeric name got $code"; cat /tmp/out; exit 1 ;; esacfipage "/api/v3/repos/$OWNER/$REPO/invitations" | jq -e 'type == "array"' >/dev/null || { echo "::error::GET /repos/$OWNER/$REPO/invitations doesn't list pending invitations"; exit 1; }tools=$(curl -fsS -X POST "$DIFFINERY/mcp" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" -H "accept: application/json, text/event-stream" --data '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq -r '.result.tools[].name')for t in get_organization list_invitations revoke_invitation; do grep -qx "$t" <<<"$tools" || { echo "::error::the MCP server has no $t tool"; exit 1; }; doneecho "highlighting, Appearance, notification settings link, view transitions, visibility, organization and invitation checks passed"##[endgroup]codician's base permission: writehighlighting, Appearance, notification settings link, view transitions, visibility, organization and invitation checks passed
Diffy placeholders, Actions settings, milestones and variables5s
##[group]Run set -euo pipefailpage() { curl -fsS "$DIFFINERY$1" -H "Authorization: Bearer $TOKEN"; }api() { curl -fsS -X "$1" "$DIFFINERY/api/v3$2" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" ${3:+--data "$3"}; }code() { curl -sS -o /tmp/out -w '%{http_code}' -X "$1" "$DIFFINERY/api/v3$2" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" ${3:+--data "$3"}; }fail() { echo "::error::$1"; cat /tmp/out 2>/dev/null || true; exit 1; }has() { grep -qF -- "$2" <<<"$1" || fail "$3"; }R="/repos/$OWNER/$REPO"has "$(page /new/import)" 'diffy/hello-world' "the importer's placeholder isn't Diffy"has "$(page "/$OWNER/$REPO/settings/actions")" 'Allow GitHub Actions to create and approve pull requests' "repository settings have no Actions page"# Milestones: created closed, checked before an issue edit is saved, shown in the response, and filterable.[ "$(api POST "$R/milestones" '{"title":"Shipped","state":"closed"}' | jq -r .state)" = closed ] || fail "POST milestones ignored state"ms=$(api POST "$R/milestones" '{"title":"Live v1"}' | jq -r .number)n=$(api POST "$R/issues" '{"title":"Planned"}' | jq -r .number)[ "$(code PATCH "$R/issues/$n" '{"title":"Renamed","milestone":999999}')" = 422 ] || fail "an unknown milestone wasn't refused with 422"[ "$(api GET "$R/issues/$n" | jq -r .title)" = Planned ] || fail "a refused milestone edit saved the title"[ "$(api PATCH "$R/issues/$n" "{\"milestone\":$ms}" | jq -r .milestone.number)" = "$ms" ] || fail "PATCH issue doesn't return the new milestone"[ "$(api GET "$R/issues?milestone=$ms&state=all" | jq -r '[.[].number] | join(",")')" = "$n" ] || fail "issues aren't filtered by milestone"loc=$(curl -sS -o /dev/null -w '%{redirect_url}' "$DIFFINERY/$OWNER/$REPO/milestone/$ms" -H "Authorization: Bearer $TOKEN")has "$loc" "/issues?milestone=$ms" "the milestone link doesn't open its issue list"# Repository variable deletes ignore letter case.[ "$(code PUT "$R/actions/variables/LIVE_CASE" '{"value":"x"}')" = 204 ] || fail "couldn't set a repository variable"[ "$(code DELETE "$R/actions/variables/live_case")" = 204 ] || fail "couldn't delete a repository variable"[ "$(code GET "$R/actions/variables/LIVE_CASE")" = 404 ] || fail "deleting a variable in lower case left it in place"org=$(page /api/v3/user/orgs | jq -r '.[0].login // empty')if [ -n "$org" ]; then  # Deleting an organization variable or secret that doesn't exist is a 404 (403 for someone who isn't an admin).  for path in variables secrets; do    c=$(code DELETE "/orgs/$org/actions/$path/LIVE_NEVER_SET_$GITHUB_RUN_ID")    case "$c" in 404|403) ;; *) fail "DELETE of a missing organization $path entry got $c" ;; esac  donefiecho "Diffy placeholders, Actions settings page, milestone and variable checks passed"##[endgroup]Diffy placeholders, Actions settings page, milestone and variable checks passed
Hosted Actions jobs (and Docker) run in Cloudflare Containers34s
##[group]Run set -euo pipefailapi() { curl -fsS "$DIFFINERY/api/v3$1" -H "Authorization: Bearer $TOKEN"; }for i in $(seq 1 90); do  run=$(api "/repos/$OWNER/$REPO/actions/runs?event=push" | jq -c '.workflow_runs[0] // empty')  [ -n "$run" ] && [ "$(jq -r .status <<<"$run")" = completed ] && break  sleep 10doneecho "$run" | jq '{id, status, conclusion}'id=$(jq -r .id <<<"$run")jobs=$(api "/repos/$OWNER/$REPO/actions/runs/$id/jobs")# placementTries: times a job went back in line (no machine, or a runner on a replaced image turned away).# restarts: times it started over because the platform replaced its runner before its steps ran.jq -r '.jobs[] | "  \(.name): \(.conclusion)\(if .failure then " - " + (.failure.message // "") else "" end)\(try " (\((.completed_at | fromdateiso8601) - (.started_at | fromdateiso8601))s)" catch "")\(if (.placementTries // 0) > 0 then ", started again \(.placementTries) time(s)" else "" end)\(if (.restarts // 0) > 0 then ", restarted \(.restarts) time(s) after its runner was replaced" else "" end)"' <<<"$jobs"if [ "$(jq -r .conclusion <<<"$run")" != success ]; then  for job in $(jq -r '.jobs[] | select(.conclusion == "failure" or .conclusion == "timed_out") | .id' <<<"$jobs"); do    echo "::group::Last log lines of job $job"    api "/repos/$OWNER/$REPO/actions/jobs/$job/logs" | tail -n 80 || true    echo "::endgroup::"  done  echo "::error::the push run did not succeed"  exit 1fiif [ -n "${DEPLOYED_RUNNER_IMAGE:-}" ]; then  # Every job ran the deployed runner, so these checks test what was just deployed.  stale=$(jq -r --arg want "$DEPLOYED_RUNNER_IMAGE" '.jobs[] | select(.runner.image != $want) | "\(.name) on \(.runner.image // "no image reported")"' <<<"$jobs")  [ -z "$stale" ] || { echo "::error::jobs ran on a runner image other than the deployed $DEPLOYED_RUNNER_IMAGE: $(paste -sd ';' <<<"$stale")"; exit 1; }  echo "every job ran on $DEPLOYED_RUNNER_IMAGE"fifor job in $(jq -r '.jobs[] | select(.name | startswith("hosted")) | .id' <<<"$jobs"); do  log=$(api "/repos/$OWNER/$REPO/actions/jobs/$job/logs")  grep -F "live ok" <<<"$log" | grep -F "# $REPO" || { echo "::error::job $job did not print its line (checkout or run step failed)"; exit 1; }  grep -F "sudo ok 0" <<<"$log" || { echo "::error::job $job could not run sudo without a password"; exit 1; }donejob=$(jq -r '.jobs[] | select(.name == "docker") | .id' <<<"$jobs")log=$(api "/repos/$OWNER/$REPO/actions/jobs/$job/logs")grep -F "docker ok built" <<<"$log" || { echo "::error::docker build or run failed on a hosted runner"; exit 1; }grep -F "service ok +PONG" <<<"$log" || { echo "::error::the redis service container was not reachable"; exit 1; }job=$(jq -r '.jobs[] | select(.name == "pull") | .id' <<<"$jobs")log=$(api "/repos/$OWNER/$REPO/actions/jobs/$job/logs")grep -F "registry ok $BIG bytes" <<<"$log" || { echo "::error::the image pushed with a $BIG-byte layer did not come back intact from the registry"; exit 1; }grep -F "buildx ok $BUILDX bytes" <<<"$log" || { echo "::error::the image pushed by docker/build-push-action did not come back from the registry"; exit 1; }api "/users/$OWNER/packages/container/${REPO,,}/versions" | jq -c '.[] | {tags: .metadata.container.tags, size, platforms}'##[endgroup]{  "id": "8be72600a22e4e87bb2454ecb0ae042b",  "status": "completed",  "conclusion": "success"}  hosted (1): success (2s)  hosted (2): success (2s)  publish: success (10s)  docker: success (13s)  buildx: success (20s)  pull: success (8s)every job ran on diffinery-runner:4d3bf17f06575e64ab4155b32026-10-25T22:44:23.104Z live ok 1 # live-1048-12026-10-25T22:44:23.206Z sudo ok 02026-10-25T22:44:23.997Z live ok 2 # live-1048-12026-10-25T22:44:24.164Z sudo ok 02026-10-25T22:44:33.902Z docker ok built2026-10-25T22:44:33.904Z service ok +PONG2026-10-25T22:44:49.487Z registry ok 5000000 bytes2026-10-25T22:44:52.331Z buildx ok 4000000 bytes{"tags":["buildx"],"size":4001849,"platforms":["linux/amd64","unknown/unknown"]}{"tags":["live"],"size":5002317,"platforms":["linux/amd64","unknown/unknown"]}
An organization's packages page keeps its tabs1s
##[group]Run set -euo pipefailorg=$(curl -fsS "$DIFFINERY/api/v3/user/orgs" -H "Authorization: Bearer $TOKEN" | jq -r '.[0].login // empty')[ -n "$org" ] || { echo "$OWNER is in no organization; skipped"; exit 0; }html=$(curl -fsS "$DIFFINERY/$org/-/packages" -H "Authorization: Bearer $TOKEN")grep -qF "<a href=\"/$org/-/packages\" class=\"on\">" <<<"$html" || { echo "::error::$org's packages page lost the organization's tab bar"; exit 1; }grep -qF "href=\"/$org?tab=repositories\"" <<<"$html" || { echo "::error::$org's packages page has no Repositories tab"; exit 1; }echo "$org's packages page shows the organization's tabs with Packages selected"##[endgroup]codician's packages page shows the organization's tabs with Packages selected
Git LFS round trip2s
##[group]Run set -euo pipefailgit clone -q "https://x-token:${TOKEN}@${DIFFINERY#https://}/$OWNER/$REPO.git" clone[ "$(sha256sum clone/blob.bin | cut -d' ' -f1)" = "$(cat blob.sha)" ] || { echo "::error::the LFS file came back different"; exit 1; }echo "LFS file matches ($(stat -c %s clone/blob.bin) bytes)"##[endgroup]LFS file matches (3145728 bytes)
Webhook delivered0s
##[group]Run set -euo pipefailfor i in $(seq 1 30); do  hook=$(curl -fsS "$DIFFINERY/api/v3/repos/$OWNER/$REPO/hooks" -H "Authorization: Bearer $TOKEN" | jq -c '.[0]')  # GitHub's hook shape: the target is config.url, the last delivery's status last_response.code.  [ "$(jq -r '.last_response.code // empty' <<<"$hook")" != "" ] && break  sleep 5doneecho "$hook" | jq '{target: .config.url, last_response, updated_at}'[ "$(jq -r '.last_response.code // empty' <<<"$hook")" != "" ] || { echo "::error::the push webhook was never delivered"; exit 1; }##[endgroup]{  "target": "https://example.com/diffinery-live-test",  "last_response": {    "code": 405,    "status": "failed",    "message": null  },  "updated_at": "2026-10-25T22:44:21Z"}
Tokens can't mint tokens (API or web forms)1s
##[group]Run set -euo pipefail# Revokes anything a failed check minted, then fails.minted() { echo "::error::$1"; curl -fsS "$DIFFINERY/api/v3/diffinery/tokens" -H "Authorization: Bearer $TOKEN" | jq -r '.[] | select(.name == "live-test escalation") | .id' | while read -r id; do curl -sS -o /dev/null -X DELETE "$DIFFINERY/api/v3/diffinery/tokens/$id" -H "Authorization: Bearer $TOKEN"; done; exit 1; }code=$(curl -sS -o /tmp/out -w '%{http_code}' -X POST "$DIFFINERY/api/v3/diffinery/tokens" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{"name":"live-test escalation","scopes":["read"],"expires_in_days":1}')[ "$code" = 403 ] || minted "an admin token minted a token through the API ($code)"grep -q "browser session" /tmp/out || minted "unexpected refusal: $(cat /tmp/out)"code=$(curl -sS -o /dev/null -w '%{http_code}' -X POST "$DIFFINERY/api/v3/diffinery/agents" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{"login":"live-test-escalation"}')[ "$code" = 403 ] || { echo "::error::an admin token created an agent ($code); disable live-test-escalation by hand"; exit 1; }# A web form with a token and a forged double-submit CSRF pair.code=$(curl -sS -o /dev/null -w '%{http_code}' -X POST "$DIFFINERY/settings/tokens" -H "Authorization: Bearer $TOKEN" -H "cookie: dfy_csrf=forged" --data "_csrf=forged&name=live-test%20escalation&scope=read&days=1")[ "$code" = 403 ] || minted "a token submitted the web token form ($code)"echo "tokens can't mint tokens or agents, through the API or the web forms"##[endgroup]tokens can't mint tokens or agents, through the API or the web forms
Agent sandbox6m 13s
##[group]Run set -euo pipefailbase="$DIFFINERY/api/v3/repos/$OWNER/$REPO/diffinery/sandboxes"id=$(curl -fsS --retry 1 --retry-delay 15 -X POST "$base" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{}' | jq -r .id)echo "sandbox $id"for i in $(seq 1 40); do  out=$(curl -sS -X POST "$base/$id/exec" -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" --data '{"cmd":"cat README.md && git lfs ls-files | wc -l"}' || true)  jq -e '.exitCode == 0' >/dev/null 2>&1 <<<"$out" && break  sleep 6doneecho "$out" | jq '{exitCode, stdout}'curl -sS -X POST "$base/$id/close" -H "Authorization: Bearer $TOKEN" >/dev/null || truejq -e --arg r "# $REPO" '.exitCode == 0 and (.stdout | contains($r))' >/dev/null <<<"$out" || { echo "::error::the sandbox did not run the command in the repository"; exit 1; }##[endgroup]sandbox 2c1b2bcda006400e93290ffc09cefba8jq: parse error: Invalid numeric literal at line 1, column 7##[error]Process completed with exit code 5.
Agent jails (bubblewrap, no network but the allowlist proxy and the model proxy)
Pull requests and the merge queue
Import a public GitHub repository
Scheduled workflow0s
##[group]Run set -euo pipefail# The cron trigger fires every 5 minutes, so allow two windows.for i in $(seq 1 75); do  run=$(curl -fsS "$DIFFINERY/api/v3/repos/$OWNER/$REPO/actions/runs?event=schedule" -H "Authorization: Bearer $TOKEN" | jq -c '.workflow_runs[0] // empty')  [ -n "$run" ] && [ "$(jq -r .status <<<"$run")" = completed ] && break  sleep 10doneif [ -z "$run" ]; then  # Whether the scheduler stopped ticking (last_tick_at is old) or ticked without starting the run  # (site administrators only: another token prints the 403).  echo "scheduler: $(curl -sS "$DIFFINERY/api/v3/diffinery/admin/scheduler" -H "Authorization: Bearer $TOKEN") (now $(date -u +%FT%TZ))"  echo "::error::no scheduled run started"  exit 1fiecho "$run" | jq '{id, event, status, conclusion}'[ "$(jq -r .conclusion <<<"$run")" = success ] || { echo "::error::the scheduled run did not succeed"; exit 1; }##[endgroup]{  "id": "3148274127894a029faa4ae70125651a",  "event": "schedule",  "status": "completed",  "conclusion": "success"}
Delete the throwaway repositories2s
##[group]Run curl -sS -o /dev/null -w 'package %{http_code}\n' -X DELETE "$DIFFINERY/api/v3/users/$OWNER/packages/container/${REPO,,}" -H "Authorization: Bearer $TOKEN"curl -sS -o /dev/null -w '%{http_code}\n' -X DELETE "$DIFFINERY/api/v3/repos/$OWNER/$REPO" -H "Authorization: Bearer $TOKEN"[ -z "${PR_REPO:-}" ] || curl -sS -o /dev/null -w '%{http_code}\n' -X DELETE "$DIFFINERY/api/v3/repos/$OWNER/$PR_REPO" -H "Authorization: Bearer $TOKEN"[ -z "${IMPORT_REPO:-}" ] || curl -sS -o /dev/null -w '%{http_code}\n' -X DELETE "$DIFFINERY/api/v3/repos/$OWNER/$IMPORT_REPO" -H "Authorization: Bearer $TOKEN"##[endgroup]package 204204