fix(install): prevent nvm/login shell from resetting PATH in subshells#651
fix(install): prevent nvm/login shell from resetting PATH in subshells#651cv merged 12 commits intoNVIDIA:mainfrom
Conversation
Two issues caused install_nemoclaw() subshells to lose the caller's PATH, making install-preflight tests fail on macOS while passing in CI: 1. `bash -lc` sourced /etc/profile which runs path_helper on macOS, resetting PATH to system defaults and hiding the caller's binaries. Fix: replace `bash -lc` with `bash -c` — the parent shell already has the correct PATH, so a login shell is unnecessary. 2. `ensure_nvm_loaded()` unconditionally sourced nvm.sh, which also resets PATH. Fix: skip sourcing when node is already on PATH. Also export `info` and `warn` helpers via `declare -f` so pre_extract_openclaw can use them in the subshell. Additionally: - Fix SC2206 shellcheck warning in version_gte() by using `read -ra` instead of unquoted word splitting into arrays. - Add .shellcheckrc to suppress SC2059 (printf format string with color vars) and SC1091 (dynamically sourced files) across the project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdded ShellCheck configuration file to suppress linting rules, refactored shell script helpers with formatting adjustments and minor logic changes (early returns, function expansion), updated subprocess invocation flags, reorganized option parsing, and pinned dependency versions in Docker configuration. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.shellcheckrc (1)
9-9: Scope ShellCheck suppressions more narrowly.Line 9 disables
SC2059andSC1091repo-wide, which can mask future issues outside installer helpers. Prefer keeping global config minimal and using local# shellcheck disable=...at intentional callsites.Example tightening
-disable=SC2059,SC1091 +disable=SC1091# In files with intentional colorized printf format strings: # shellcheck disable=SC2059 info() { printf "${C_CYAN}[INFO]${C_RESET} %s\n" "$*"; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.shellcheckrc at line 9, Remove the repo‑wide suppression of SC2059 and SC1091 from .shellcheckrc and instead scope those disables to specific call sites that intentionally require them (for example the colorized printf helper like info() and any installer helper that sources generated files), by adding local comments such as "# shellcheck disable=SC2059" or "# shellcheck disable=SC1091" directly above the offending function or source statement; keep the global .shellcheckrc minimal so other files still get checked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.shellcheckrc:
- Line 9: Remove the repo‑wide suppression of SC2059 and SC1091 from
.shellcheckrc and instead scope those disables to specific call sites that
intentionally require them (for example the colorized printf helper like info()
and any installer helper that sources generated files), by adding local comments
such as "# shellcheck disable=SC2059" or "# shellcheck disable=SC1091" directly
above the offending function or source statement; keep the global .shellcheckrc
minimal so other files still get checked.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: dee031f5-e9f3-4ee0-b586-67c22701b172
📒 Files selected for processing (3)
.shellcheckrcinstall.shscripts/install.sh
Passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and test files. Without the argument, pyright respects the configured include paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Auto-formatted by shfmt via pre-commit hooks after merging upstream/main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The test_endpoint_validation.py file imports pytest which is only available as a dev dependency. Pyright in strict mode cannot resolve it, breaking the pre-push hook. Exclude test files from pyright's include paths since they have their own type discipline via pytest. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@install.sh`:
- Around line 572-579: Update the script's usage output (the usage function) to
document the new -h short alias alongside --help and --version/-v; specifically,
modify the displayed options so the help text lists both `-h, --help` (and where
applicable `-v, --version`) to match the case in the option parsing block that
now accepts `-h` in addition to `--help`.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9587cdde-3ef8-4e1b-89f2-dd36b75ac933
📒 Files selected for processing (5)
.pre-commit-config.yamlinstall.shnemoclaw-blueprint/pyproject.tomlscripts/backup-workspace.shscripts/install-openshell.sh
✅ Files skipped from review due to trivial changes (2)
- nemoclaw-blueprint/pyproject.toml
- scripts/backup-workspace.sh
Same issue as the pre-commit hook fix — passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and site-packages (17k+ errors in CI). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses hadolint DL3008, DL3013, DL3042, and DL3059: pin all apt packages to exact versions, pin pyyaml, add --no-cache-dir, and consolidate consecutive RUN instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Dockerfile (1)
16-22: Pinned APT versions may cause build failures when packages are superseded and removed from mirrors.Pinning to exact Debian package versions (e.g.,
curl=7.88.1-10+deb12u14) ensures reproducible builds, but Debian does not retain old package versions in stable mirrors once a newer version is published. When a superseding version is released, the older one can be removed (e.g., whendeb12u15is published,deb12u14may no longer be available), causingapt-get installto fail.Consider one of these alternatives:
- Pin only major/minor versions (e.g.,
curl=7.88.1*) to accept security patches automatically.- Keep exact pins but document a process/schedule for updating them when CI breaks.
- Use
snapshot.debian.orgif strict reproducibility is required; older package versions remain available there even after being removed from the main mirrors.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Dockerfile` around lines 16 - 22, The Dockerfile currently pins exact Debian package versions (e.g., python3, python3-pip, curl, git, ca-certificates, iproute2) which will cause apt installs to fail when upstream mirrors remove superseded versions; change those exact pins to looser pins (for example use major/minor wildcards like curl=7.88.1* or remove the "=version" suffix entirely) so security updates don’t break builds, or alternatively document a process for updating these exact pins or switch to snapshot.debian.org for strict reproducibility—apply the chosen approach to the listed package entries in the Dockerfile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Dockerfile`:
- Around line 16-22: The Dockerfile currently pins exact Debian package versions
(e.g., python3, python3-pip, curl, git, ca-certificates, iproute2) which will
cause apt installs to fail when upstream mirrors remove superseded versions;
change those exact pins to looser pins (for example use major/minor wildcards
like curl=7.88.1* or remove the "=version" suffix entirely) so security updates
don’t break builds, or alternatively document a process for updating these exact
pins or switch to snapshot.debian.org for strict reproducibility—apply the
chosen approach to the listed package entries in the Dockerfile.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ee2cb981-62d4-438f-9a32-5fcd11169685
📒 Files selected for processing (2)
Dockerfilescripts/brev-setup.sh
✅ Files skipped from review due to trivial changes (1)
- scripts/brev-setup.sh
Resolve conflicts in Dockerfile (pyyaml version) and install.sh (keep bash -c over bash -lc to prevent PATH reset in subshells). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove stale DL3008 suppression (versions are pinned) and add quotes around the pyyaml version specifier for consistency with upstream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Thanks for submitting this fix to prevent the login shell from resetting the PATH in subshells, which could help resolve installation issues on macOS and make it easier for users to get started with NemoClaw. |
ericksoa
left a comment
There was a problem hiding this comment.
Shell script fixes look good — the bash -lc → bash -c change and nvm skip are solid.
One thing: the Dockerfile apt version pins conflict with #721 (gateway process isolation) which adds gosu and a gateway user in the same area. Can you rebase onto #721 once it merges and reconcile the Dockerfile? The apt pins may also need loosening (e.g. python3=3.11* instead of exact point release) since they'll break when the base image rolls to a newer Debian build.
NVIDIA#651) * fix(install): prevent nvm/login shell from resetting PATH in subshells Two issues caused install_nemoclaw() subshells to lose the caller's PATH, making install-preflight tests fail on macOS while passing in CI: 1. `bash -lc` sourced /etc/profile which runs path_helper on macOS, resetting PATH to system defaults and hiding the caller's binaries. Fix: replace `bash -lc` with `bash -c` — the parent shell already has the correct PATH, so a login shell is unnecessary. 2. `ensure_nvm_loaded()` unconditionally sourced nvm.sh, which also resets PATH. Fix: skip sourcing when node is already on PATH. Also export `info` and `warn` helpers via `declare -f` so pre_extract_openclaw can use them in the subshell. Additionally: - Fix SC2206 shellcheck warning in version_gte() by using `read -ra` instead of unquoted word splitting into arrays. - Add .shellcheckrc to suppress SC2059 (printf format string with color vars) and SC1091 (dynamically sourced files) across the project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): drop stray '.' arg from pyright pre-push hook Passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and test files. Without the argument, pyright respects the configured include paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: apply shfmt formatting to shell scripts Auto-formatted by shfmt via pre-commit hooks after merging upstream/main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): exclude test files from pyright strict type-checking The test_endpoint_validation.py file imports pytest which is only available as a dev dependency. Pyright in strict mode cannot resolve it, breaking the pre-push hook. Exclude test files from pyright's include paths since they have their own type discipline via pytest. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): drop stray '.' arg from pyright in blueprint Makefile Same issue as the pre-commit hook fix — passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and site-packages (17k+ errors in CI). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: apply shfmt formatting to brev-setup.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(security): pin apt and pip package versions in Dockerfile Addresses hadolint DL3008, DL3013, DL3042, and DL3059: pin all apt packages to exact versions, pin pyyaml, add --no-cache-dir, and consolidate consecutive RUN instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove hadolint ignore and quote pyyaml version pin Remove stale DL3008 suppression (versions are pinned) and add quotes around the pyyaml version specifier for consistency with upstream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: document -h short alias in usage output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NVIDIA#651) * fix(install): prevent nvm/login shell from resetting PATH in subshells Two issues caused install_nemoclaw() subshells to lose the caller's PATH, making install-preflight tests fail on macOS while passing in CI: 1. `bash -lc` sourced /etc/profile which runs path_helper on macOS, resetting PATH to system defaults and hiding the caller's binaries. Fix: replace `bash -lc` with `bash -c` — the parent shell already has the correct PATH, so a login shell is unnecessary. 2. `ensure_nvm_loaded()` unconditionally sourced nvm.sh, which also resets PATH. Fix: skip sourcing when node is already on PATH. Also export `info` and `warn` helpers via `declare -f` so pre_extract_openclaw can use them in the subshell. Additionally: - Fix SC2206 shellcheck warning in version_gte() by using `read -ra` instead of unquoted word splitting into arrays. - Add .shellcheckrc to suppress SC2059 (printf format string with color vars) and SC1091 (dynamically sourced files) across the project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): drop stray '.' arg from pyright pre-push hook Passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and test files. Without the argument, pyright respects the configured include paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: apply shfmt formatting to shell scripts Auto-formatted by shfmt via pre-commit hooks after merging upstream/main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): exclude test files from pyright strict type-checking The test_endpoint_validation.py file imports pytest which is only available as a dev dependency. Pyright in strict mode cannot resolve it, breaking the pre-push hook. Exclude test files from pyright's include paths since they have their own type discipline via pytest. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): drop stray '.' arg from pyright in blueprint Makefile Same issue as the pre-commit hook fix — passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and site-packages (17k+ errors in CI). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: apply shfmt formatting to brev-setup.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(security): pin apt and pip package versions in Dockerfile Addresses hadolint DL3008, DL3013, DL3042, and DL3059: pin all apt packages to exact versions, pin pyyaml, add --no-cache-dir, and consolidate consecutive RUN instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove hadolint ignore and quote pyyaml version pin Remove stale DL3008 suppression (versions are pinned) and add quotes around the pyyaml version specifier for consistency with upstream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: document -h short alias in usage output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NVIDIA#651) * fix(install): prevent nvm/login shell from resetting PATH in subshells Two issues caused install_nemoclaw() subshells to lose the caller's PATH, making install-preflight tests fail on macOS while passing in CI: 1. `bash -lc` sourced /etc/profile which runs path_helper on macOS, resetting PATH to system defaults and hiding the caller's binaries. Fix: replace `bash -lc` with `bash -c` — the parent shell already has the correct PATH, so a login shell is unnecessary. 2. `ensure_nvm_loaded()` unconditionally sourced nvm.sh, which also resets PATH. Fix: skip sourcing when node is already on PATH. Also export `info` and `warn` helpers via `declare -f` so pre_extract_openclaw can use them in the subshell. Additionally: - Fix SC2206 shellcheck warning in version_gte() by using `read -ra` instead of unquoted word splitting into arrays. - Add .shellcheckrc to suppress SC2059 (printf format string with color vars) and SC1091 (dynamically sourced files) across the project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): drop stray '.' arg from pyright pre-push hook Passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and test files. Without the argument, pyright respects the configured include paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: apply shfmt formatting to shell scripts Auto-formatted by shfmt via pre-commit hooks after merging upstream/main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): exclude test files from pyright strict type-checking The test_endpoint_validation.py file imports pytest which is only available as a dev dependency. Pyright in strict mode cannot resolve it, breaking the pre-push hook. Exclude test files from pyright's include paths since they have their own type discipline via pytest. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ci): drop stray '.' arg from pyright in blueprint Makefile Same issue as the pre-commit hook fix — passing '.' to pyright overrides the include/exclude paths in pyproject.toml, causing it to scan .venv and site-packages (17k+ errors in CI). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: apply shfmt formatting to brev-setup.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(security): pin apt and pip package versions in Dockerfile Addresses hadolint DL3008, DL3013, DL3042, and DL3059: pin all apt packages to exact versions, pin pyyaml, add --no-cache-dir, and consolidate consecutive RUN instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove hadolint ignore and quote pyyaml version pin Remove stale DL3008 suppression (versions are pinned) and add quotes around the pyyaml version specifier for consistency with upstream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: document -h short alias in usage output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
bash -lc→bash -cininstall_nemoclaw()subshells. The login shell flag sourced/etc/profilewhich runspath_helperon macOS, resetting PATH to system defaults and hiding the caller's binaries.nvm.shsourcing when node is already on PATH.ensure_nvm_loaded()unconditionally sourcednvm.sh, which also resets PATH — breaking test stubs and unnecessarily mutating the environment.info/warnhelpers viadeclare -fsopre_extract_openclawcan use them in the subshell.version_gte()— useread -rainstead of unquoted word splitting..shellcheckrcto suppress SC2059 (printf format string with color vars) and SC1091 (dynamically sourced files).-hshort alias in the installer usage output to match the option parser.Why these tests failed locally but passed in CI
CI runs on
ubuntu-latestwith a minimal shell profile — no nvm, nopath_helper. On macOS with nvm installed, bothbash -l(via/etc/profile) andensure_nvm_loaded(vianvm.sh) reset PATH, causing the fake node/npm/git stubs ininstall-preflight.test.jsto be overridden by real system binaries.Test plan
npx vitest run— all tests passnpx shellcheck install.sh scripts/install.sh— clean🤖 Generated with Claude Code