From 008701ef46e6b8c04cdfab64592089e02c32642c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=9C=88?= Date: Tue, 2 Jun 2026 18:28:59 +0800 Subject: [PATCH] fix(e2e): cross-platform Docker isolation for e2e-walkthrough MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problems on macOS: - `-v $HOME:$HOME` let container's bun install overwrite host bun binary (Linux ARM64 replaced macOS ARM64) - Container couldn't reach host LLM endpoints (localhost != host) - Hardcoded `~/repos/workflow` path didn't exist on all machines Fixes: - Mount source read-only (`-v $(pwd):/workspace:ro`) + copy inside - Use container-local HOME (/root) to isolate bun/npm installs - Add `--add-host=host.docker.internal:host-gateway` for Linux compat - `docker cp` host config + sed localhost→host.docker.internal - Use `debate.yaml` instead of `solve-issue.yaml` (no $SUSPEND dep) - Fix cancel test: `--status cancelled` not `--status completed` Verified: full 6-step walkthrough passes on macOS, host bun intact. --- .workflows/e2e-walkthrough.yaml | 40 +++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/.workflows/e2e-walkthrough.yaml b/.workflows/e2e-walkthrough.yaml index 825ea63..043fb17 100644 --- a/.workflows/e2e-walkthrough.yaml +++ b/.workflows/e2e-walkthrough.yaml @@ -8,20 +8,32 @@ roles: - docker - shell procedure: | - 1. Start a Docker container with isolated storage: + 1. Start a Docker container with isolated storage. + IMPORTANT: Mount the source code READ-ONLY to prevent the container + from overwriting host files (e.g. bun install would replace macOS bun with Linux bun). + Use a container-local HOME so bun/npm installs stay inside the container. + Add host.docker.internal mapping for LLM API access from inside the container. ``` docker run -d --name uwf-e2e-$$ \ - -v $HOME:$HOME \ - -e HOME=$HOME \ + -v "$(pwd):/workspace:ro" \ + -e HOME=/root \ -e UNCAGED_WORKFLOW_STORAGE_ROOT=/tmp/uwf-e2e-storage \ - -w ~/repos/workflow \ + --add-host=host.docker.internal:host-gateway \ + -w /workspace \ node:22-bookworm \ sleep infinity ``` - 2. Inside the container, install bun, install deps, then `bun link` all packages - so that `uwf`, `uwf-hermes`, `uwf-builtin` are on PATH (from source): + NOTE: Run this from the workflow monorepo root directory. + On macOS Docker Desktop, host.docker.internal is already available; + --add-host ensures it also works on Linux Docker. + + 2. Inside the container, copy source to a writable location, install bun, install deps, + then `bun link` all packages so that `uwf`, `uwf-hermes`, `uwf-builtin` are on PATH: ``` docker exec uwf-e2e-$$ bash -c ' + # Copy source to writable location (mount is read-only) + cp -r /workspace /root/workflow + # Install bun curl -fsSL https://bun.sh/install | bash export PATH="$HOME/.bun/bin:$PATH" @@ -30,7 +42,7 @@ roles: mkdir -p $UNCAGED_WORKFLOW_STORAGE_ROOT # Install workspace deps - cd ~/repos/workflow && bun install --frozen-lockfile + cd /root/workflow && bun install # bun link each package that has a bin entry cd packages/cli-workflow && bun link && cd ../.. @@ -44,11 +56,15 @@ roles: docker exec uwf-e2e-$$ bash -c 'export PATH="$HOME/.bun/bin:$PATH" && uwf-hermes --help' docker exec uwf-e2e-$$ bash -c 'export PATH="$HOME/.bun/bin:$PATH" && uwf-builtin --help' ``` - 4. Copy host config if it exists: + 4. Copy host uwf config into the container's isolated storage. + The host config contains provider credentials and model settings needed for LLM calls. + Also rewrite any localhost URLs to host.docker.internal so the container can reach host services. ``` + docker cp ~/.uncaged/workflow/config.yaml uwf-e2e-$$:/tmp/uwf-e2e-storage/config.yaml 2>/dev/null || true docker exec uwf-e2e-$$ bash -c ' - if [ -f $HOME/.uncaged/workflow/config.yaml ]; then - cp $HOME/.uncaged/workflow/config.yaml $UNCAGED_WORKFLOW_STORAGE_ROOT/config.yaml + if [ -f $UNCAGED_WORKFLOW_STORAGE_ROOT/config.yaml ]; then + sed -i "s|localhost|host.docker.internal|g; s|127\.0\.0\.1|host.docker.internal|g" \ + $UNCAGED_WORKFLOW_STORAGE_ROOT/config.yaml fi ' ``` @@ -87,7 +103,7 @@ roles: 3. `uwf config get models.test.name` — verify it returns "test-model" Workflow registration tests: - 4. `uwf workflow add ~/repos/workflow/examples/solve-issue.yaml` — register workflow + 4. `uwf workflow add /root/workflow/examples/debate.yaml` — register a workflow (use debate.yaml as it has no $SUSPEND dependency) 5. Verify the output contains a hash 6. `uwf workflow list` — verify non-empty array 7. Capture the workflow name from the list @@ -197,7 +213,7 @@ roles: Cancel: 1. Start a second thread: `uwf thread start -p 'E2E cancel test'` 2. Cancel it: `uwf thread cancel ` - 3. Verify it appears in completed list: `uwf thread list --status completed` + 3. Verify it appears in cancelled list: `uwf thread list --status cancelled` Fork: 4. Fork from the first thread's last step: `uwf step fork `