2026-10-16T15:00:04.866Z Diffinery runner: job live (Containers, registry, sandboxes, webhooks, schedules, LFS and pull requests) for codician/diffinery@b4c01c57c9d3 2026-10-16T15:00:04.877Z Runner: image diffinery-runner:0d9b89e0a449e5faecf2b19c, in ams08, WEUR, container 77c51ac20d3fe56ace7beac6652c61377e0f4135780241deefae2febfd3849eb 2026-10-16T15:00:04.877Z Runner 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 size 2026-10-16T15:00:04.877Z Host: AMD EPYC (family 25, model 1), 4 vCPUs, 2000 MHz 2026-10-16T15:00:04.878Z Workspace: /workspace/diffinery 2026-10-16T15:00:04.997Z ##[group]Run if [ "$GITHUB_EVENT_NAME" = workflow_run ]; then 2026-10-16T15:00:04.997Z # Deploy's gate skips a commit that is no longer main's tip (the newer commit's run deploys it): 2026-10-16T15:00:04.997Z # then nothing new is live, and this run would only test the site as it was. 2026-10-16T15:00:04.997Z 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) 2026-10-16T15:00:04.997Z if [ "$deployed" = skipped ]; then 2026-10-16T15:00:04.997Z echo "::notice::Deploy deployed nothing for $HEAD_SHA (main has moved on), so there is nothing new to test" 2026-10-16T15:00:04.997Z echo "skip=true" >> "$GITHUB_OUTPUT" 2026-10-16T15:00:04.997Z exit 0 2026-10-16T15:00:04.997Z fi 2026-10-16T15:00:04.997Z fi 2026-10-16T15:00:04.997Z if [ -z "$TOKEN" ]; then 2026-10-16T15:00:04.997Z # After a deploy of diffinery.com a missing token is an error: a green run would mean nothing was tested. 2026-10-16T15:00:04.997Z if [ "$GITHUB_EVENT_NAME" = workflow_run ]; then 2026-10-16T15:00:04.997Z 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." 2026-10-16T15:00:04.997Z exit 1 2026-10-16T15:00:04.997Z fi 2026-10-16T15:00:04.997Z 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." 2026-10-16T15:00:04.997Z echo "skip=true" >> "$GITHUB_OUTPUT" 2026-10-16T15:00:04.997Z exit 0 2026-10-16T15:00:04.997Z fi 2026-10-16T15:00:04.997Z login=$(curl -fsS "$DIFFINERY/api/v3/user" -H "Authorization: Bearer $TOKEN" | jq -r .login) 2026-10-16T15:00:04.997Z echo "OWNER=$login" >> "$GITHUB_ENV" 2026-10-16T15:00:04.997Z echo "testing as $login in $login/$REPO" 2026-10-16T15:00:04.997Z env: 2026-10-16T15:00:04.997Z GH_TOKEN: *** 2026-10-16T15:00:04.997Z DEPLOY_RUN: 247 2026-10-16T15:00:04.997Z ##[endgroup] 2026-10-16T15:00:06.022Z testing as cnbrkdmrci in cnbrkdmrci/live-248-1 2026-10-16T15:00:06.236Z ##[group]Run set -euo pipefail 2026-10-16T15:00:06.236Z # Layers over Cloudflare's 100 MB request limit (which hosted runners push through 2026-10-16T15:00:06.236Z # the registry relay) take minutes to push and pull. They're pushed on manual runs and 2026-10-16T15:00:06.236Z # whenever the registry, the runner image or this test changed since the last 2026-10-16T15:00:06.236Z # successful live test; other deploys push small images through the same path. 2026-10-16T15:00:06.236Z full=true 2026-10-16T15:00:06.236Z if [ "$GITHUB_EVENT_NAME" = workflow_run ]; then 2026-10-16T15:00:06.236Z api() { curl -fsS "$DIFFINERY/api/v3/repos/$GITHUB_REPOSITORY$1" -H "Authorization: Bearer $TOKEN"; } 2026-10-16T15:00:06.236Z last=$(api "/actions/runs?workflow=live-test.yml&status=success&per_page=1" | jq -r '.workflow_runs[0].head_sha // empty' || true) 2026-10-16T15:00:06.236Z if [ -n "$last" ] && files=$(api "/compare/$last...$HEAD_SHA" | jq -r '.files[].filename'); then 2026-10-16T15:00:06.236Z grep -qE '^(apps/diffinery/src/registry/|containers/runner/|\.github/workflows/live-test\.yml$)' <<<"$files" || full=false 2026-10-16T15:00:06.236Z echo "changed since $last: $(wc -l <<<"$files") files" 2026-10-16T15:00:06.236Z fi 2026-10-16T15:00:06.236Z fi 2026-10-16T15:00:06.236Z if [ "$full" = true ]; then 2026-10-16T15:00:06.236Z echo "BIG=150000000" >> "$GITHUB_ENV" 2026-10-16T15:00:06.236Z echo "BUILDX=120000000" >> "$GITHUB_ENV" 2026-10-16T15:00:06.236Z else 2026-10-16T15:00:06.236Z echo "BIG=5000000" >> "$GITHUB_ENV" 2026-10-16T15:00:06.236Z echo "BUILDX=4000000" >> "$GITHUB_ENV" 2026-10-16T15:00:06.236Z fi 2026-10-16T15:00:06.236Z echo "registry check: full=$full" 2026-10-16T15:00:06.236Z ##[endgroup] 2026-10-16T15:00:07.757Z changed since b4c01c57c9d38fa429705b6201ba1a1e6d601454: 1 files 2026-10-16T15:00:07.757Z registry check: full=false 2026-10-16T15:00:07.910Z ##[group]Run set -euo pipefail 2026-10-16T15:00:07.910Z av="$DIFFINERY/api/avatars/$OWNER" 2026-10-16T15:00:07.910Z # Keep the account's current picture, if it has one, to put it back afterwards. 2026-10-16T15:00:07.910Z had=$(curl -fsS -o before.webp -w '%{content_type}' "$av?s=256&v=1") 2026-10-16T15:00:07.910Z restore() { 2026-10-16T15:00:07.910Z if [ "$had" = image/webp ]; then 2026-10-16T15:00:07.910Z 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)"' 2026-10-16T15:00:07.910Z else 2026-10-16T15:00:07.910Z curl -fsS -o /dev/null -X DELETE "$DIFFINERY/api/v3/user/avatar" -H "Authorization: Bearer $TOKEN" 2026-10-16T15:00:07.910Z fi 2026-10-16T15:00:07.910Z } 2026-10-16T15:00:07.910Z trap restore EXIT 2026-10-16T15:00:07.910Z # A 600×400 PNG gradient; the server crops it to a square and makes small WebPs. 2026-10-16T15:00:07.910Z python3 - <<'EOF' 2026-10-16T15:00:07.910Z import struct, zlib 2026-10-16T15:00:07.910Z w, h = 600, 400 2026-10-16T15:00:07.910Z rows = 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)) 2026-10-16T15:00:07.910Z chunk = lambda t, d: struct.pack(">I", len(d)) + t + d + struct.pack(">I", zlib.crc32(t + d)) 2026-10-16T15:00:07.910Z 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"")) 2026-10-16T15:00:07.910Z EOF 2026-10-16T15:00:07.910Z url=$(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) 2026-10-16T15:00:07.910Z echo "uploaded: $url" 2026-10-16T15:00:07.910Z v=${url##*v=} 2026-10-16T15:00:07.910Z type=$(curl -fsS -o small.webp -w '%{content_type}' "$av?s=64&v=$v") 2026-10-16T15:00:07.910Z [ "$type" = image/webp ] || { echo "::error::expected image/webp, got $type"; exit 1; } 2026-10-16T15:00:07.910Z python3 - <<'EOF' 2026-10-16T15:00:07.910Z import struct, sys 2026-10-16T15:00:07.910Z b = open("small.webp", "rb").read() 2026-10-16T15:00:07.910Z ok = b[:4] == b"RIFF" and b[8:12] == b"WEBP" 2026-10-16T15:00:07.910Z if b[12:16] == b"VP8 ": 2026-10-16T15:00:07.910Z size = (struct.unpack(" 5000: 2026-10-16T15:00:07.910Z print("::error::the 64 px avatar is not a 64x64 WebP under 5 KB"); sys.exit(1) 2026-10-16T15:00:07.910Z EOF 2026-10-16T15:00:07.910Z curl -fsS -X DELETE "$DIFFINERY/api/v3/user/avatar" -H "Authorization: Bearer $TOKEN" >/dev/null 2026-10-16T15:00:07.910Z # A `v` that is not current bypasses the edge cache, so this sees the removal from any colo. 2026-10-16T15:00:07.910Z type=$(curl -fsS -o /dev/null -w '%{content_type}' "$av?s=64&v=1") 2026-10-16T15:00:07.910Z [[ "$type" == image/svg+xml* ]] || { echo "::error::after removal expected the initials SVG, got $type"; exit 1; } 2026-10-16T15:00:07.910Z echo "removed: initials again ($type)" 2026-10-16T15:00:07.910Z ##[endgroup] 2026-10-16T15:00:11.199Z uploaded: https://diffinery.com/api/avatars/cnbrkdmrci?v=1792162809 2026-10-16T15:00:11.948Z 64 px avatar: 256 bytes, (64, 64) 2026-10-16T15:00:13.503Z curl: (22) The requested URL returned error: 500 2026-10-16T15:00:18.997Z restored the previous picture: https://diffinery.com/api/avatars/cnbrkdmrci?v=1792162814 2026-10-16T15:00:19.004Z ##[error]Process completed with exit code 22. 2026-10-16T15:00:21.466Z ##[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" 2026-10-16T15:00:21.466Z curl -sS -o /dev/null -w '%{http_code}\n' -X DELETE "$DIFFINERY/api/v3/repos/$OWNER/$REPO" -H "Authorization: Bearer $TOKEN" 2026-10-16T15:00:21.466Z [ -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" 2026-10-16T15:00:21.466Z [ -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" 2026-10-16T15:00:21.466Z ##[endgroup] 2026-10-16T15:00:22.028Z package 404 2026-10-16T15:00:22.614Z 404 2026-10-16T15:00:22.684Z Host: 3% of the vCPUs' time went to other work on the host (steal) 2026-10-16T15:00:22.684Z Job completed with conclusion: failure 2026-10-16T15:00:22.687Z Resources: 0.2 of 4 vCPUs busy on average (0.5 at the 95th percentile), peak memory 0.3 GiB of 11.9 GiB, peak disk 1.1 GB of 19.3 GB