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 · 3.7 KBRaw History
1name: End-to-end
2
3on:
4 push:
5 branches: [main]
6 pull_request:
7
8permissions:
9 contents: read
10
11concurrency:
12 group: e2e-${{ github.ref }}
13 cancel-in-progress: true
14
15jobs:
16 # The suite in parallel shards of about the same length: the git, pull request and
17 # Actions file split in three (its real histories and large pushes on their own), agents, security, and
18 # every other test/e2e/*.test.mjs file (so a new file runs without editing this).
19 # Only the last shard needs a browser (passkeys).
20 e2e:
21 name: End-to-end (${{ matrix.name }})
22 runs-on: ubuntu-latest
23 timeout-minutes: 20
24 strategy:
25 fail-fast: false
26 matrix:
27 include:
28 - name: git, PRs, Actions
29 shard: core
30 - name: real histories
31 shard: histories
32 - name: large pushes
33 shard: large
34 - name: agent reviews, tasks, Today
35 shard: agents
36 - name: security
37 shard: security
38 - name: passkeys, registry, email
39 shard: rest
40 steps:
41 - uses: actions/checkout@v4
42 - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
43 - uses: actions/setup-node@v4
44 with:
45 node-version: 22
46 cache: pnpm
47 - run: pnpm install --frozen-lockfile
48 - run: pnpm -r --if-present build
49 - if: matrix.shard == 'rest'
50 run: pnpm --filter @diffinery/app exec playwright install --with-deps chromium
51 # Agent runs (terminal tasks, and headless runs in the agents shard) are in a bubblewrap jail
52 # (containers/runner/src/jail.ts); Ubuntu's AppArmor otherwise keeps
53 # it from creating user namespaces. Diffinery's own runner image already has bwrap and no sudo, running as root.
54 - if: matrix.shard == 'rest' || matrix.shard == 'agents'
55 run: |
56 as_root() { if [ "$(id -u)" = 0 ]; then "$@"; else sudo "$@"; fi; }
57 if ! command -v bwrap >/dev/null; then
58 as_root apt-get install -y --no-install-recommends bubblewrap || { as_root apt-get update -qq && as_root apt-get install -y --no-install-recommends bubblewrap; }
59 fi
60 as_root sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 2>/dev/null || true
61 bwrap --unshare-all --ro-bind / / --dev /dev --proc /proc -- true
62 - name: Run the shard's tests
63 working-directory: apps/diffinery
64 run: |
65 # Shards of similar length; a new test file runs in "rest" unless it's added to another.
66 core='/e2e\.test\.mjs$'
67 agents='/(agentic|review|tasks)\.test\.mjs$'
68 security='/(security|status)\.test\.mjs$'
69 # The core file's real histories and large pushes take minutes each (jquery's alone 2 to 3 on
70 # Diffinery's runners): two shards of their own, so no part of the file runs into node's
71 # per-file timeout, which is the --test-timeout here.
72 histories='^real histories:'
73 large='^(large files|large pushes):'
74 opts=(--test-timeout=600000)
75 case "${{ matrix.shard }}" in
76 core) files=$(ls test/e2e/*.test.mjs | grep -E "$core"); opts+=(--test-skip-pattern="$histories" --test-skip-pattern="$large") ;;
77 histories) files=$(ls test/e2e/*.test.mjs | grep -E "$core"); opts=(--test-timeout=900000 --test-name-pattern="$histories") ;;
78 large) files=$(ls test/e2e/*.test.mjs | grep -E "$core"); opts+=(--test-name-pattern="$large") ;;
79 agents) files=$(ls test/e2e/*.test.mjs | grep -E "$agents") ;;
80 security) files=$(ls test/e2e/*.test.mjs | grep -E "$security") ;;
81 *) files=$(ls test/e2e/*.test.mjs | grep -vE "$core|$agents|$security") ;;
82 esac
83 echo "$files"
84 node --test --test-concurrency=1 "${opts[@]}" $files