From 04922836100c2aacc46086f4b1686af9b6b25ea3 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Thu, 7 May 2026 16:00:02 -0700 Subject: [PATCH] =?UTF-8?q?fix(ci):=20cp=20-r=20instead=20of=20cp=20-al=20?= =?UTF-8?q?=E2=80=94=20/opt=20and=20/workspace=20are=20different=20filesys?= =?UTF-8?q?tems?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hardlink-copy fix landed and immediately broke with: cp: cannot create hard link 'node_modules/' to '/opt/node_modules_cache/': Invalid cross-device link GitHub Actions runners mount the workspace volume at /workspace (overlay-fs layered onto the runner image), and /opt is the runner image's own filesystem. Cross-filesystem hardlinks aren't supported. Switch `cp -al` → `cp -r`. Cost: ~5s for ~200 packages of small JS files vs ~0s for the broken symlink. Still cheaper than the ~15s `bun install` fallback. Realpath of /workspace/node_modules//... stays inside /workspace, so bun build's sibling-dep resolution works. Both evals.yml and evals-periodic.yml updated. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/evals-periodic.yml | 10 +++++----- .github/workflows/evals.yml | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/evals-periodic.yml b/.github/workflows/evals-periodic.yml index 482bff62..c0ca4f3a 100644 --- a/.github/workflows/evals-periodic.yml +++ b/.github/workflows/evals-periodic.yml @@ -101,14 +101,14 @@ jobs: echo "TMPDIR=/home/runner/.cache" } >> "$GITHUB_ENV" - # Hardlink copy (cp -al) instead of symlink: bun build resolves a file's - # realpath when looking for sibling deps, which makes a symlinked - # /opt/node_modules_cache fail to resolve transitive deps. See - # evals.yml for the full explanation. + # Recursive copy (cp -r) instead of symlink: bun build resolves a + # file's realpath when looking for sibling deps. See evals.yml for the + # full explanation. cp -al would be faster but /opt and /workspace + # are on different overlay-fs layers, so cross-device hardlink fails. - name: Restore deps run: | if [ -d /opt/node_modules_cache ] && diff -q /opt/node_modules_cache/.package.json package.json >/dev/null 2>&1; then - cp -al /opt/node_modules_cache node_modules + cp -r /opt/node_modules_cache node_modules else bun install fi diff --git a/.github/workflows/evals.yml b/.github/workflows/evals.yml index d09bc541..ee658aee 100644 --- a/.github/workflows/evals.yml +++ b/.github/workflows/evals.yml @@ -110,20 +110,19 @@ jobs: echo "TMPDIR=/home/runner/.cache" } >> "$GITHUB_ENV" - # Restore pre-installed node_modules from Docker image via hardlink copy. - # Why hardlinks instead of symlink: bun build (and Node module resolution - # in general) resolves a file's realpath when walking up to find - # node_modules/. With `ln -s /opt/node_modules_cache node_modules`, - # resolution from inside socks/build/client/socksclient.js walks the - # /opt/node_modules_cache/... realpath, where there is no parent - # node_modules dir containing smart-buffer/ip-address. With `cp -al`, - # each file's realpath is /workspace/node_modules/..., so sibling deps - # resolve correctly. Speed is comparable to symlink (hardlinks share - # inodes, no actual data copy). + # Restore pre-installed node_modules from Docker image via recursive + # copy. Symlink (`ln -s`) breaks bun's module resolution because bun + # resolves a file's realpath when walking up to find node_modules/; + # from a symlinked path, realpath escapes the workspace and sibling + # deps no longer resolve. Hardlink copy (`cp -al`) fails because /opt + # and /workspace are on different overlay-fs layers ("Invalid + # cross-device link"). Recursive copy works on every layout. Cost: + # ~5s for ~200 packages of small JS files vs ~0s for symlink — still + # vastly cheaper than rerunning `bun install` (network + resolution). - name: Restore deps run: | if [ -d /opt/node_modules_cache ] && diff -q /opt/node_modules_cache/.package.json package.json >/dev/null 2>&1; then - cp -al /opt/node_modules_cache node_modules + cp -r /opt/node_modules_cache node_modules else bun install fi