Ensure Copilot bootstrap can find Node.js inside AWF chroot#2160
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Security ReviewOne finding — File: agentVolumes.push(`\$\{effectiveHome}/.nvm:/host\$\{effectiveHome}/.nvm:rw`);Issue: The stated purpose is to make nvm-managed Node.js binaries readable inside the chroot. A read-only mount achieves that. With This differs from the Suggested fix: Change the mount to read-only: agentVolumes.push(`\$\{effectiveHome}/.nvm:/host\$\{effectiveHome}/.nvm:ro`);All other changes (
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Fixes Copilot-engine startup failures in AWF chroot environments by ensuring Node.js installations (notably nvm-managed) are visible inside the chroot and by adding a fail-fast bootstrap guard with clearer diagnostics.
Changes:
- Set
AWF_REQUIRE_NODE=1in generated compose env for Copilot-related invocations to enable a Node.js preflight guard. - Bind-mount
~/.nvminto the agent chroot and pre-create.nvmin the allowed home subdirectories to avoid root-owned mount sources. - Add/extend tests to validate
.nvmmount + pre-creation andAWF_REQUIRE_NODEbehavior for Copilot command invocations.
Show a summary per file
| File | Description |
|---|---|
| src/docker-manager.ts | Adds Copilot/Node preflight signaling (AWF_REQUIRE_NODE), mounts ~/.nvm, and pre-creates .nvm for chroot bind mounts. |
| src/docker-manager.test.ts | Extends tests to assert .nvm mount + pre-creation and AWF_REQUIRE_NODE set/unset behavior for Copilot vs non-Copilot commands. |
| containers/agent/entrypoint.sh | Adds an AWF_REQUIRE_NODE-gated node preflight check with a targeted error message and exit code. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/3 changed files
- Comments generated: 2
| const commandExecutableBase = path.posix.basename(commandExecutable.replace(/\\/g, '/')); | ||
| const isCopilotCommand = commandExecutableBase.toLowerCase() === 'copilot'; | ||
| if (config.copilotGithubToken || config.copilotApiKey || isCopilotCommand) { | ||
| environment.AWF_REQUIRE_NODE = '1'; | ||
| } |
There was a problem hiding this comment.
The new AWF_REQUIRE_NODE behavior is also enabled when Copilot auth env is present (copilotGithubToken/copilotApiKey), not just when the command executable is copilot. There are tests for the copilot ... command case, but none asserting the env-var-driven case; adding a test would help prevent regressions and ensure this broader gating remains intentional.
| echo "[entrypoint][ERROR] Copilot CLI requires Node.js, but 'node' is not available inside AWF chroot." | ||
| echo "[entrypoint][ERROR] Ensure Node.js is installed on the runner and reachable from PATH inside the chroot." | ||
| echo "[entrypoint][ERROR] If using setup-node or nvm, verify the install path is present and bind-mounted into /host." | ||
| echo "[entrypoint][ERROR] Example locations include /opt/hostedtoolcache/... and $HOME/.nvm/..." |
There was a problem hiding this comment.
These preflight error messages are emitted via echo to stdout; for a fail-fast guard like this, it’s more reliable to write the diagnostics to stderr (e.g., redirect each line or the whole block) so callers and log parsers treat it as an error stream.
| echo "[entrypoint][ERROR] Copilot CLI requires Node.js, but 'node' is not available inside AWF chroot." | |
| echo "[entrypoint][ERROR] Ensure Node.js is installed on the runner and reachable from PATH inside the chroot." | |
| echo "[entrypoint][ERROR] If using setup-node or nvm, verify the install path is present and bind-mounted into /host." | |
| echo "[entrypoint][ERROR] Example locations include /opt/hostedtoolcache/... and $HOME/.nvm/..." | |
| echo "[entrypoint][ERROR] Copilot CLI requires Node.js, but 'node' is not available inside AWF chroot." >&2 | |
| echo "[entrypoint][ERROR] Ensure Node.js is installed on the runner and reachable from PATH inside the chroot." >&2 | |
| echo "[entrypoint][ERROR] If using setup-node or nvm, verify the install path is present and bind-mounted into /host." >&2 | |
| echo "[entrypoint][ERROR] Example locations include /opt/hostedtoolcache/... and $HOME/.nvm/..." >&2 |
This comment has been minimized.
This comment has been minimized.
|
@copilot please address this review feedback #2160 (review) |
Addressed in I applied the requested review feedback by:
|
|
Smoke Test Results:
Overall: PASS
|
Smoke Test: Copilot BYOK (Offline) Mode
Running in BYOK offline mode ( Author: Overall: PASS ✅
|
|
Smoke test results
Warning The following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "registry.npmjs.org"See Network Configuration for more information.
|
🔥 Smoke Test Results
Overall: PASS PR by
|
Smoke Test Results: GitHub Actions Services Connectivity
All 3 checks failed.
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
Chroot Version Comparison Results
Overall: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot.
|
Copilot-engine workflows were failing before inference because
nodewas not available inside the chrooted agent environment (node: command not found). The failure path had no turns/tool calls, so startup needed a deterministic runtime fix and clearer diagnostics.Node runtime visibility in chroot
~/.nvmto agent bind mounts so nvm-managed Node installs are available in/hostchroot.~/.nvmto pre-created allowed home subdirectories to avoid root-owned auto-created mount sources.Fail-fast bootstrap guard for Copilot
AWF_REQUIRE_NODEsignal in compose generation when the invoked executable iscopilot(or Copilot auth env is configured).AWF_REQUIRE_NODE:nodeis resolvable in chroot before running the user commandTargeted test coverage
.nvmmount inclusion.nvmpre-creationAWF_REQUIRE_NODEset for Copilot invocations and unset for non-Copilot commands