Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
956c464
feat: add cell host adapter and aggregate cell class
patrickleet Aug 22, 2026
7a99339
feat: parent-shard game cells for Blob and bomberman tick
patrickleet Aug 22, 2026
f8c4ed4
test: add celld compose host and TodoCell worker
patrickleet Aug 22, 2026
cb94035
test: run local celld compose against Azurite
patrickleet Aug 22, 2026
6cfe9fa
feat: run Todo AggregateCell as workers-rs wasm on celld
patrickleet Aug 22, 2026
2235a98
feat: persist Todo cell event log in Durable Object SQLite
patrickleet Aug 22, 2026
c75e458
feat: enable repository snapshots on the celld host
patrickleet Aug 23, 2026
cf853da
feat: public in-process causal invoke with receipt
patrickleet Aug 23, 2026
b496019
feat: HTTP and gRPC causal wait-path with receipt
patrickleet Aug 23, 2026
d7ca126
feat: GraphQL wait-path through CommandHost, not Service
patrickleet Aug 23, 2026
4316c05
feat: GraphQL CommandHost without Service unwrap
patrickleet Aug 23, 2026
7437a2a
feat: cell sealed row and command-named wait-path HTTP
patrickleet Aug 23, 2026
c44d591
feat: GraphQL ReadStore SQL scan vs cell GET-by-pk
patrickleet Aug 23, 2026
706a2e9
feat: optional celld+NATS e2e-ui profile
patrickleet Aug 23, 2026
3169458
fix: GraphQL command status test injects CommandHost
patrickleet Aug 23, 2026
47697e0
chore: add make up-celld-nats for the optional profile
patrickleet Aug 23, 2026
ae8d8a6
fix: make up-celld-nats tolerate an occupied NATS port
patrickleet Aug 23, 2026
50f7d3f
feat: serve GraphQL WS through graphql_router_with_host
patrickleet Aug 23, 2026
9a22658
feat: add e2e-celld GraphQL host wait-dispatching Todo to celld
patrickleet Aug 23, 2026
f8a545d
docs(e2e-ui): point optional celld profile at sibling example
patrickleet Aug 23, 2026
b1f3be9
feat: add portable_command! for domain command mounts
patrickleet Aug 23, 2026
9e30559
refactor(e2e-celld): move Zitadel auth into an identity service crate
patrickleet Aug 23, 2026
633e4e1
docs: explain celld vs one-process hosts on home and README
patrickleet Aug 23, 2026
fd636b1
feat(e2e-celld): drain ChatCell outbox through MessagePublisher
patrickleet Aug 23, 2026
7bf9526
refactor: lift celld CommandHost into the framework
patrickleet Aug 23, 2026
9b2acc1
feat(e2e-celld): use Postgres for GraphQL read models
patrickleet Aug 23, 2026
3d07811
fix(replica): keep SPA nav and Eventual lists from flashing stale SQL
patrickleet Aug 23, 2026
4ba7dde
ci: run celld and e2e-celld tests on PRs and main
patrickleet Aug 23, 2026
398059e
fix(ci): unblock js-client, quality, all-features, and chat e2e
patrickleet Aug 24, 2026
260c3e3
fix: snapshot tail loads, Eventual projected, and chat Send
patrickleet Aug 24, 2026
5a459ff
fix(js): settle Eventual projected on command-free live frames only
patrickleet Aug 24, 2026
ca01b32
fix(replica): keep Atomic membership fences off @load lists
patrickleet Aug 24, 2026
0317e85
fix: keep Eventual projectors live and fill auth_users on scrape
patrickleet Aug 24, 2026
b9e2556
fix(celld): make command lifecycle durable and fast
patrickleet Aug 24, 2026
617472e
fix(replica): avoid stale celld revalidation races
patrickleet Aug 24, 2026
4afa1d8
fix(replica): preserve soft-navigation authority
patrickleet Aug 24, 2026
880bea1
fix: settle exact command projections without refetch
patrickleet Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ existing unbounded-tech quality provider plus the integration/* jobs below —
| [`test-all-features.yaml`](./test-all-features.yaml) | yes | **This repo:** workspace `--all-features` |
| [`integration-*.yaml`](./) | yes | **This repo:** broker / DB / CLI / observability / GraphQL identity+OIDC |
| [`integration-e2e-ui.yaml`](./integration-e2e-ui.yaml) | yes | **This repo:** `tests/e2e-ui` offline suite + Playwright browser e2e |
| [`integration-celld.yaml`](./integration-celld.yaml) | yes | **This repo:** `tests/e2e-celld` workspace tests + live Azurite+celld+NATS |
| [`integration-js.yaml`](./integration-js.yaml) | yes | **This repo:** install, typecheck, test, build, and packed-consumer smoke test for `js/` |
| [`on-pr-quality.yaml`](./on-pr-quality.yaml) | entry | **This repo** PR gate (not the consumer quality contract) |
| [`on-push-main-version-and-tag.yaml`](./on-push-main-version-and-tag.yaml) | entry | **This repo** main → **vnext** tag |
Expand Down
225 changes: 225 additions & 0 deletions .github/workflows/integration-celld.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
name: celld (live + e2e-celld)

# Reusable workflow: referenced via `uses: ./.github/workflows/integration-celld.yaml`
# from both the PR-quality and push-to-main pipelines.
#
# Local parity:
# make -C tests/e2e-celld test
# make -C tests/e2e-ui up && make -C tests/e2e-ui up-celld-nats
# WATCH=0 WATCH_WORKER=0 make -C tests/e2e-celld run
# E2E_UI_ORIGIN=http://localhost:5180 npx --prefix tests/e2e-ui playwright test \
# todos.user.spec.ts chat.user.spec.ts --project chromium-user
#
# Default `cargo test` (quality) still runs fixture-only celld checks and
# skips live HTTP unless CELLD_URL is set. This job sets CELLD_URL / NATS_URL.
on:
workflow_call:

env:
CARGO_TERM_COLOR: always
# Zitadel owns :18080 in the browser topology.
CELLD_HTTP_PORT: "18880"
CELLD_URL: http://127.0.0.1:18880
NATS_PORT: "14222"
NATS_URL: nats://127.0.0.1:14222
AZURE_STORAGE_USE_EMULATOR: "true"
AZURE_STORAGE_ACCOUNT_NAME: devstoreaccount1
AZURE_STORAGE_ACCOUNT_KEY: Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==

jobs:
e2e-celld:
name: e2e-celld workspace tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: tests/e2e-celld
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
toolchain: stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: tests/e2e-celld -> target
shared-key: e2e-celld-workspace
- name: Run e2e-celld workspace tests
run: cargo test --workspace --verbose

live:
name: celld live (Azurite + worker + NATS)
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
toolchain: stable
targets: wasm32-unknown-unknown

- uses: Swatinem/rust-cache@v2
with:
workspaces: |
. -> target
tests/celld/worker -> tests/celld/worker/target
shared-key: celld-live

- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: |
js/package-lock.json
tests/e2e-ui/package-lock.json
tests/e2e-ui/ui/package-lock.json

- name: Install host tools
run: sudo apt-get update && sudo apt-get install -y jq openssl curl

- name: Install esbuild
run: npm install -g esbuild

- name: Install wasm-pack and worker-build
run: |
cargo install wasm-pack --locked || cargo install wasm-pack
cargo install worker-build --locked || cargo install worker-build

- name: Install celld CLI
run: |
curl -fsSL https://celld.dev/install.sh | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"

- name: Bring up Postgres + Zitadel and bootstrap OIDC
run: make -C tests/e2e-ui up

- name: Bring up Azurite + celld + NATS
run: |
command -v celld
command -v worker-build
make -C tests/e2e-ui up-celld-nats

- name: Live celld HTTP + NATS profile tests
run: make -C tests/e2e-ui test-celld

- name: Build e2e-celld API and UI
run: |
cargo build --manifest-path tests/e2e-celld/Cargo.toml \
-p e2e-celld-runner --bin e2e-celld
make -C tests/e2e-ui ui-install
npm install --prefix tests/e2e-ui

- name: Start e2e-celld API + UI
run: |
set -euo pipefail
set -a
# shellcheck disable=SC1091
. tests/e2e-ui/e2e-ui.env
set +a
export BIND=0.0.0.0:8791
export CELLD_URL=http://127.0.0.1:18880
export NATS_URL=nats://127.0.0.1:14222
export AUTH_URL=http://localhost:5180
export AUTH_USE_SECURE_COOKIES=false
export AUTH_TRUST_HOST=true

tests/e2e-celld/target/debug/e2e-celld \
> tests/e2e-celld/.ci-runner.log 2>&1 &
echo $! > tests/e2e-celld/.ci-runner.pid

ok=0
for i in $(seq 1 120); do
code=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
"http://127.0.0.1:8791/graphql" \
-H 'content-type: application/json' \
-d '{"query":"{ __typename }"}' 2>/dev/null || echo 000)
if [ "$code" = "200" ] || [ "$code" = "401" ]; then ok=1; break; fi
sleep 0.5
done
if [ "$ok" != "1" ]; then
echo "e2e-celld API failed to become ready"
tail -120 tests/e2e-celld/.ci-runner.log
exit 1
fi

cd tests/e2e-ui/ui
PUBLIC_E2E_PROFILE=celld-nats \
E2E_API_ORIGIN=http://127.0.0.1:8791 \
npm run dev -- --host localhost --port 5180 \
> ../.ci-celld-ui.log 2>&1 &
echo $! > ../.ci-celld-ui.pid
cd ../../..

ok=0
for i in $(seq 1 60); do
code=$(curl -s -o /dev/null -w '%{http_code}' \
"http://localhost:5180/" 2>/dev/null || echo 000)
if [ "$code" = "200" ] || [ "$code" = "302" ] || [ "$code" = "303" ]; then
ok=1
break
fi
sleep 0.5
done
if [ "$ok" != "1" ]; then
echo "e2e-celld UI failed to become ready (last HTTP $code)"
tail -100 tests/e2e-ui/.ci-celld-ui.log
exit 1
fi

- name: Install Playwright + Chromium
working-directory: tests/e2e-ui
run: npx playwright install chromium --with-deps

- name: Todo + Chat browser lifecycle through celld
working-directory: tests/e2e-ui
run: >-
npx playwright test todos.user.spec.ts chat.user.spec.ts
--project chromium-user
env:
E2E_UI_ORIGIN: http://localhost:5180
E2E_API_ORIGIN: http://127.0.0.1:8791
CI: true

- name: Upload celld Playwright report
if: failure()
uses: actions/upload-artifact@v4
with:
name: celld-playwright-report
path: |
tests/e2e-ui/playwright-report
tests/e2e-ui/test-results
if-no-files-found: ignore
retention-days: 7

- name: Dump logs on failure
if: failure()
run: |
echo '=== celld compose ==='
docker compose -f tests/celld/docker-compose.yml ps -a || true
docker compose -f tests/celld/docker-compose.yml logs --tail=200 || true
echo '=== NATS profile compose ==='
docker compose -f tests/e2e-ui/celld-nats-profile/docker-compose.yml ps -a || true
docker compose -f tests/e2e-ui/celld-nats-profile/docker-compose.yml logs --tail=80 || true
echo '=== e2e-celld API ==='
tail -180 tests/e2e-celld/.ci-runner.log || true
echo '=== e2e-celld UI ==='
tail -100 tests/e2e-ui/.ci-celld-ui.log || true
echo '=== Postgres + Zitadel ==='
docker compose -f tests/e2e-ui/docker/docker-compose.yml ps -a || true
docker compose -f tests/e2e-ui/docker/docker-compose.yml logs --tail=100 || true

- name: Tear down
if: always()
run: |
[ -f tests/e2e-ui/.ci-celld-ui.pid ] && \
kill "$(cat tests/e2e-ui/.ci-celld-ui.pid)" 2>/dev/null || true
[ -f tests/e2e-celld/.ci-runner.pid ] && \
kill "$(cat tests/e2e-celld/.ci-runner.pid)" 2>/dev/null || true
lsof -ti:5180 2>/dev/null | xargs -r kill -9 2>/dev/null || true
lsof -ti:8791 2>/dev/null | xargs -r kill -9 2>/dev/null || true
make -C tests/e2e-ui down-celld-nats || true
make -C tests/e2e-ui down-celld || true
docker compose -f tests/e2e-ui/docker/docker-compose.yml down -v || true
3 changes: 3 additions & 0 deletions .github/workflows/on-pr-quality.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,6 @@ jobs:
js-client:
needs: [contracts]
uses: ./.github/workflows/integration-js.yaml

celld:
uses: ./.github/workflows/integration-celld.yaml
5 changes: 4 additions & 1 deletion .github/workflows/on-push-main-version-and-tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ jobs:
js-client:
uses: ./.github/workflows/integration-js.yaml

celld:
uses: ./.github/workflows/integration-celld.yaml

# This uses commit logs and tags from git to determine the next version number and create a tag for the release.
# Some commits such as chore: will not trigger a version bump and tag; this is by design.
version-and-tag:
name: Version and Tag
needs: [quality, all-features, postgres, nats, rabbitmq, kafka, distributed-cli, observability, graphql, e2e-ui, js-client]
needs: [quality, all-features, postgres, nats, rabbitmq, kafka, distributed-cli, observability, graphql, e2e-ui, js-client, celld]
uses: unbounded-tech/workflow-vnext-tag/.github/workflows/workflow.yaml@v1.22.2
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ tests/workshop-service/*.db

# fixture crate build artifacts
tests/fixtures/**/target/
tests/celld/worker/target/
tests/celld/worker/build/
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
members = ["distributed_macros", "distributed_cli"]
exclude = ["tests/e2e-ui"]
exclude = ["tests/e2e-ui", "tests/celld/worker"]
resolver = "2"

[workspace.package]
Expand Down Expand Up @@ -58,7 +58,7 @@ base64 = "0.23.0"
futures = { version = "0.3", optional = true }
lapin = { version = "4", optional = true }
rdkafka = { version = "0.39", features = ["cmake-build", "tokio"], optional = true }
reqwest = { version = "0.13", default-features = false, features = ["rustls"], optional = true }
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls"], optional = true }
jsonwebtoken = { version = "9", optional = true }
bitcode = { version = "0.6.9", features = ["serde"] }
event-emitter-rs = { version = "0.1.4", optional = true }
Expand All @@ -79,6 +79,10 @@ tracing = { version = "0.1", optional = true }
tracing-opentelemetry = { version = "0.33", default-features = false, optional = true }
uuid = { version = "1", features = ["v7"] }

[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
js-sys = "0.3"
uuid = { version = "1", features = ["v7", "js"] }

[build-dependencies]
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
Expand Down
Loading
Loading