"npm" should use the version of Node that it belongs to

Issue #29 resolved
Michael Knight created an issue

We have multiple versions of Node.js on our build agents:

  • /opt/nodejs/current (a symlink pointing to /opt/nodejs/v0.12)
  • /opt/nodejs/v0.12
  • /opt/nodejs/v0.10
  • /opt/nodejs/v0.8

We also have /opt/nodejs/current/bin in our agent users' $PATH by default.

We've found that even if someone configures an npm task with the Node.js 0.10 executable, /opt/nodejs/v0.10/bin/npm will actually invoke /opt/nodejs/current/bin/node to run itself.

Consequently dependencies are being built using 0.12 instead of 0.10 (which is causing build failures for some native modules).

A workaround is to explicitly set the environment variable PATH=/opt/nodejs/v0.10/bin for the task, but this is not ideal and hard to communicate to our users. It feels like the task should take care of this automatically.

Comments (21)

  1. m

    I have similar problems when using this inside of a multi-version NVM environment.

    It seems to me that we should use the same "hack" as used in convertNodePathToNpmPath to explicitly add the directory to the node executable to the beginning of PATH just before (or after) setting the extra environment variables in execute, unless you have a brighter idea?

  2. Marcin Oles

    @isaacg there is actually a simpler way of doing this - instead of calling <pathToNpm> <arguments> we can call <pathToNode> <pathToNpm> <arguments>, like it's done for other tasks, e.g. Grunt. I've checked it, it then executes with the correct version of node - see the log below:

    $ /opt/node-v0.10.26-linux-x64/bin/node /opt/node-v0.12.5-linux-x64/bin/npm -dd info grunt
    
    npm info it worked if it ends with ok
    npm verb cli [ '/opt/node-v0.10.26-linux-x64/bin/node',
    npm verb cli   '/opt/node-v0.12.5-linux-x64/bin/npm',
    npm verb cli   '-dd',
    npm verb cli   'info',
    npm verb cli   'grunt' ]
    npm info using npm@2.11.2
    npm info using node@v0.10.26
    
    $ /opt/node-v0.12.5-linux-x64/bin/node /opt/node-v0.10.26-linux-x64/bin/npm -dd info grunt 
    
    npm info it worked if it ends with ok
    npm verb cli [ '/opt/node-v0.12.5-linux-x64/bin/node',
    npm verb cli   '/opt/node-v0.10.26-linux-x64/bin/npm',
    npm verb cli   '-dd',
    npm verb cli   'info',
    npm verb cli   'grunt' ]
    npm info using npm@1.4.3
    npm info using node@v0.12.5
    
  3. m

    It doesn't work by me. I'm doing a compiled module (hashring, required by memcached) and it's still going to $PATH to try to find a "default" node to run node-gyp with...

    bash-4.1$ /home/bamboo-agent/.nvm/versions/node/v0.12.4/bin/node /home/bamboo-agent/.nvm/versions/node/v0.12.4/bin/npm install
    -
    > hashring@3.1.1 install /home/bamboo-agent/test/node_modules/memcached/node_modules/hashring
    > node-gyp rebuild
    
    /home/bamboo-agent/.nvm/versions/node/v0.12.4/lib/node_modules/npm/bin/node-gyp-bin/node-gyp: line 3: node: command not found
    npm ERR! Linux 2.6.32-504.12.2.el6.x86_64
    npm ERR! argv "/home/bamboo-agent/.nvm/versions/node/v0.12.4/bin/node" "/home/bamboo-agent/.nvm/versions/node/v0.12.4/bin/npm" "install"
    npm ERR! node v0.12.4
    npm ERR! npm  v2.10.1
    npm ERR! file sh
    npm ERR! code ELIFECYCLE
    npm ERR! errno ENOENT
    npm ERR! syscall spawn
    
    npm ERR! hashring@3.1.1 install: `node-gyp rebuild`
    npm ERR! spawn ENOENT
    npm ERR!
    npm ERR! Failed at the hashring@3.1.1 install script 'node-gyp rebuild'.
    npm ERR! This is most likely a problem with the hashring package,
    npm ERR! not with npm itself.
    npm ERR! Tell the author that this fails on your system:
    npm ERR!     node-gyp rebuild
    npm ERR! You can get their info via:
    npm ERR!     npm owner ls hashring
    npm ERR! There is likely additional logging output above.
    
    npm ERR! Please include the following file with any support request:
    npm ERR!     /home/bamboo-agent/test/npm-debug.log
    
  4. Marcin Oles

    @isaacg - but do you think this is an issue with npm task?

    If I understand correctly, your npm did detect the correct node version:

    npm ERR! node v0.12.4
    npm ERR! npm  v2.10.1
    

    so the problem seems to be related to node-gyp tool (which I'm not familiar with). I'll discuss this with other Bamboo team members, but I think we will probably still decide to avoid setting the PATH variable within the build task.

  5. m

    That depends on whether the way node/npm/node-gyp play together is a bug or feature on the Node.js team's side :)

    If node-gyp is looking for node on the PATH, and that's considered correct behavior, then what I described above is an issue with the NPM task IMHO

  6. Martin Sander

    Will this bugfix be released to the marketplace for older Versions of Bamboo?

    Or do we have to upgrade to 5.9.2?

    If we build 1.7.5 ourselves, would it work with bamboo 5.8?

  7. Marcin Oles

    Hi @martinsander,

    since the test API of Bamboo has changed in 5.9, the integration tests will fail for older Bamboo versions than 5.9 (see commits 9653cfd, 7d97bb7, c4ac332). This doesn't mean that the plugin is broken for older Bamboo versions, but just automated tests.

    Most likely the soon-to-be-released version on Marketplace will say it does not support older Bamboo versions, as it would require manual testing of every change...

    But I'm almost sure that this plugin will work properly with older versions of Bamboo, especially 5.8 which is quite recent. Though this is just an opinion, I give no guarantees and it's done at own risk. Building it manually by doing mvn clean package -DskipTests and then uploading into Bamboo should be alright. Or just downloading via the Marketplace - each version has a "Download" button with the .jar file.

    But upgrading to most recent Bamboo version is always recommended.

  8. Martin Sander

    Hey @marcin-oles,

    We have verified that version 1.7.5 basically works with our bamboo.

    However, we run into the same problem as @issacg :

    The npm script itself executes okay. But when running npm install with e.g. the phantomjs package, the installation assumes a node binary in the path:

    build   17-Jul-2015 11:14:31    > phantomjs@1.9.17 install /opt/bamboo-agent/xml-data/build-dir/SUSHI-DSQA-JOB1/node_modules/phantomjs
    build   17-Jul-2015 11:14:31    > node install.js
    build   17-Jul-2015 11:14:31    
    error   17-Jul-2015 11:14:31    sh: 1: node: not found
    

    So there are at least two projects who assume node to be on PATH: node-gyp and phantomjs.

    Adding node to the PATH properly solves this problem and is even simpler than the solution from 6577bbaba:

    diff --git a/src/main/java/com/atlassian/bamboo/plugins/nodejs/tasks/npm/NpmTaskType.java b/src/main/java/com/atlassian/bamboo/plugins/nodejs/tasks/npm/NpmTaskType.java
    index d3a0c8e..16c706b 100644
    --- a/src/main/java/com/atlassian/bamboo/plugins/nodejs/tasks/npm/NpmTaskType.java
    +++ b/src/main/java/com/atlassian/bamboo/plugins/nodejs/tasks/npm/NpmTaskType.java
    @@ -97,6 +97,7 @@ public class NpmTaskType implements CommonTaskType
                 taskResultBuilder.checkReturnCode(processService.executeExternalProcess(taskContext, new ExternalProcessBuilder()
                         .command(commandListBuilder.build())
                         .env(extraEnvironmentVariables)
    +                    .path(FilenameUtils.getFullPath(nodePath))
                         .workingDirectory(taskContext.getWorkingDirectory())));
    
                 return taskResultBuilder.build();
    

    Is there any chance to get this into the plugin or do we need to patch it ourselves?

  9. Marcin Oles

    Well if it is that simple and - as I now see it - necessary for many tools to work, I think we can have it. I'll add it to the next release.

    Correct me if I'm wrong, but this feature should probably be added to all tasks that use node (including Node.js task, and helper tasks like Grunt, Gulp etc), as this problem might occur to them as well...?

  10. Martin Sander

    Well if it is that simple and - as I now see it - necessary for many tools to work, I think we can have it. I'll add it to the next release.

    Thanks!

    Correct me if I'm wrong, but this feature should probably be added to all tasks that use node (including Node.js task, and helper tasks like Grunt, Gulp etc), as this problem might occur to them as well...?

    Sounds reasonable to me, although we only ran into this problem with npm - yet.

  11. m

    I've only actually seen it with npm.

    I use Node.js tasks, and grunt tasks in the same environment and (so far) have not run into this.

  12. Former user Account Deleted

    Sorry if this is a stupid question, but we're experiencing this exact problem and I can't figure out how to download the newer version. The version available on the marketplace is still 1.7 and when I download the zip from the bitbucket download page it is the source and not the compiled jar file.

  13. Marcin Oles

    @coryclaflin I've released 1.7.8 on Atlassian Marketplace, and added the last 3 Maven-released versions as JARs to 'Downloads' section.

    Please note that this is now a plugin bundled with Bamboo. To obtain the most up-to-date releases please use the newest version of Bamboo available. Marketplace releases are done as 'best effort' work and may not be present for each Maven version released.

    I'll try to add each Maven released version to Downloads section from now on, however there won't be any guarantees about supported Bamboo versions. I suggest always using the newest Bamboo.

  14. Log in to comment