nvm-sh / nvm

Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
MIT License
79.76k stars 7.99k forks source link

Unable to install global npm packages via ansible #3061

Closed Clumsy-Coder closed 1 year ago

Clumsy-Coder commented 1 year ago

Operating system and version:

MacOS Catalina (10.15.7)

nvm debug output:

```sh nvm --version: v0.39.1 $TERM_PROGRAM: tmux $SHELL: /bin/zsh $SHLVL: 2 whoami: 'umar' ${HOME}: /Users/umar ${NVM_DIR}: '${HOME}/.local/share/nvm' ${PATH}: /usr/local/opt/openssl@3/bin:/usr/local/sbin:${HOME}/.local/share/gem/bin:${HOME}/.local/share/cargo/bin:${NVM_DIR}/versions/node/v19.7.0/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Wireshark.app/Contents/MacOS:${HOME}/.local/share/go/bin:${HOME}/.local/share/npm/bin:/usr/local/bin/python3:/usr/bin/python $PREFIX: '' ${NPM_CONFIG_PREFIX}: '' $NVM_NODEJS_ORG_MIRROR: '' $NVM_IOJS_ORG_MIRROR: '' shell version: 'zsh 5.7.1 (x86_64-apple-darwin19.0)' uname -a: 'Darwin 19.6.0 Darwin Kernel Version 19.6.0: Tue Jun 21 21:18:39 PDT 2022; root:xnu-6153.141.66~1/RELEASE_X86_64 x86_64' checksum binary: 'sha256sum' OS version: Mac 10.15.7 19H2026 curl: /usr/bin/curl, curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2 wget: /usr/local/bin/wget, GNU Wget 1.21.3 built on darwin19.6.0. sed: /usr/bin/sed cut: /usr/bin/cut basename: /usr/bin/basename rm: /bin/rm mkdir: /bin/mkdir xargs: /usr/bin/xargs git: /usr/local/bin/git, git version 2.39.2 ls: grep:: No such file or directory grep: grep: aliased to grep --color (grep --color), grep (BSD grep) 2.5.1-FreeBSD awk: /usr/bin/awk, awk version 20070501 nvm current: v19.7.0 which node: ${NVM_DIR}/versions/node/v19.7.0/bin/node which iojs: iojs not found which npm: ${NVM_DIR}/versions/node/v19.7.0/bin/npm npm config get prefix: ${HOME}/.local/share/npm npm root -g: ${HOME}/.local/share/npm/lib/node_modules ```

nvm ls output:

```sh -> v19.7.0 default -> node (-> v19.7.0) iojs -> N/A (default) unstable -> N/A (default) node -> stable (-> v19.7.0) (default) stable -> 19.7 (-> v19.7.0) (default) lts/* -> lts/hydrogen (-> N/A) lts/argon -> v4.9.1 (-> N/A) lts/boron -> v6.17.1 (-> N/A) lts/carbon -> v8.17.0 (-> N/A) lts/dubnium -> v10.24.1 (-> N/A) lts/erbium -> v12.22.12 (-> N/A) lts/fermium -> v14.21.3 (-> N/A) lts/gallium -> v16.19.1 (-> N/A) lts/hydrogen -> v18.15.0 (-> N/A) ```

Ansible is unable to find node when installing npm packages.

roles/nvm/tasks/main.yaml

---

### Install Node Version Manager

- name: "Create directory for Node Version Manager on {{ ansible_env.NVM_DIR }}"
  file:
    path: "{{ ansible_env.NVM_DIR }}"
    state: directory
  tags:
    - terminal
    - nvm

- name: "Create directory for NPM  on {{ ansible_env.NPM_DIR }}"
  file:
    path: "{{ ansible_env.NPM_DIR }}"
    state: directory
  tags:
    - terminal
    - nvm

- name: "link NPM config file"
  file:
    src: "{{ ansible_env.DOTDIR}}/tools/npm/.npmrc"
    dest: "{{ ansible_env.NPM_CONFIG_USERCONFIG }}"
  tags:
    - terminal
    - nvm

- name: "Install Node Version Manager"
  shell:
    cmd: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | PROFILE=/dev/null zsh
  tags:
    - terminal
    - nvm

- name: "Install latest NodeJS version"
  shell:
    cmd: "source {{ ansible_env.NVM_DIR }}/nvm.sh && nvm install node --default --latest-npm"
  tags:
    - terminal
    - nvm

roles/npm/tasks/main.yaml

- name: "Store current nodejs version being used by nvm"
  shell: "source {{ ansible_env.NVM_DIR}}/nvm.sh && nvm current"
  register: node_version

- name: "Install global npm packages"
  npm:
    name: "{{ item }}"
    global: true
    executable: "{{ ansible_env.NVM_DIR}}/versions/node/{{ node_version.stdout }}/bin/npm"
  loop:
    - commitizen
    - typescript

playbooks/macos.yaml

---
- hosts: "local"
  roles:
    - role: nvm
    - role: npm

ansible.cfg

[defaults]
inventory = ./hosts
roles_path = ./roles/
stdout_callback = debug

roles.yaml

[local]
localhost ansible_connection=local

command to run

ANSIBLE_CONFIG=./ansible.cfg ansible-playbook "./playbooks/macos.yaml" --ask-become-pass --verbose

output

image

Clumsy-Coder commented 1 year ago

Figured out a solution

roles/npm/tasks/main.yaml

- name: "Store current nodejs version being used by nvm"
  shell: "source {{ ansible_env.NVM_DIR}}/nvm.sh && nvm current"
  register: node_version
  changed_when: false

- name: "Install global npm packages"
  npm:
    name: "{{ item }}"
    global: true
    # executable: "{{ ansible_env.NVM_DIR}}/versions/node/{{ node_version.stdout }}/bin/npm"
  loop:
    - commitizen
    - typescript
  environment:
    # obtained from https://truongtx.me/2015/11/02/ansible-install-and-work-with-nodejs-using-nvm#install-npm-tools-with-node-in-nvm
    PATH: "{{ ansible_env.NVM_DIR }}/versions/node/{{ node_version.stdout }}/bin:{{ ansible_env.PATH }}"

Credit

https://truongtx.me/2015/11/02/ansible-install-and-work-with-nodejs-using-nvm#install-npm-tools-with-node-in-nvm

ljharb commented 1 year ago

You should never need to hardcode paths to node; the issue is that whatever sources nvm and uses a version needs to export the PATH for future steps to use.