23
votes

I'm trying to run a simple gruntfile.js as part of my build in TeamCity. However, even after installing grunt and grunt-cli as global node packages, TeamCity still won't recognize them. I can type grunt in the command line and it works, but when I run it in TeamCity either through a command line runner or an executable with parameters, it still gives

'grunt' is not recognized as an internal or external command

I also tried installing TeamCity.Node, which is a plugin for running grunt scripts, but it can't find grunt either. Any ideas?

8

8 Answers

33
votes

I couldn't get the accepted solution to work. The problem for me was that TeamCity services (server and agent) were running under system accounts. AFAIK, there is no concept of "globally install npm package for all users of the OS". So I:

  1. created a TeamCity windows user
  2. changed the TeamCity services to run as that user
  3. logged into the OS as the TeamCity user
  4. ran npm install -g grunt-cli
  5. restarted the services.

From there, the NodeJS, NPM and Grunt tasks just started working.

14
votes

Here is a complement to Christopher's answer (I don't have enough reputation to make a comment).

In case you don't want to create a user on build server, you can write full path to execute a npm package. Here is a command line runner to run Weyland without creating dedicated user on build server:

  • Command executable: "C:\Program Files\nodejs\node.exe"
  • Command parameters: c:\users\Administrator\AppData\Roaming\npm\node_modules\weyland\bin\cli.js build

BTW, it seems that the installer of Node.js has another solution. Unfortunately, it's trimmed!

Here is the screenshot of Node.js installer:

5
votes

I ran into the same problem when trying to get grunt to work with TFS where it would be ran by the tfsservice user. Running our builds as a different user as Christopher's answer suggests wasn't an option for us. After I added C:\Users\tfsservice\AppData\Roaming\npm to the tfsservice user's Path it was able to find the grunt-cli when I manually logged in as tfsservice, but not when the TFS Build agent performed the build. At first I just changed my build process to use the full path to the grunt.cmd file.

So I changed from using this:

grunt deploy

to using this:

"C:\Users\tfsservice\AppData\Roaming\npm\grunt.cmd" deploy

I imagine doing the same for your Team City user would also fix the problem. Of course if you do this you have to make sure that the grunt-cli is installed in the same location on all of your build servers.

Turns out though that I had just missed the final step of restarting my PC (so that the tfsservice would get restarted) and then the builds were able to find grunt without specifying the full path.

I assume that the trimmed node.js installer description shown by Zeke Lu's answer was going to say that other users need to update their Path environment variable.

4
votes

make sure %AppData%\Roaming\npm path is on you windows GLOBAL path variable, restart team agent service and will work

2
votes

You should restart the TeamCity Build Agents after installing NPM.

1
votes

I know this question is kind of old. But I struggled with the same problem nowadays and couldn't find a solution... but finally I did. Here you are.

TeamCity build steps should include:

1) Installation grunt-cli Command Line Command: npm install grunt-cli

2) Running grunt build task Command Line Command: node "node_modules/grunt-cli/bin/grunt" build

Working directory for both cases should be where your grountfile.js is located.

0
votes

This was a weird and very annoying bug, but I finally found a workaround. In the %AppData%\Roaming\npm directory, there are two files: "grunt" and "grunt.cmd". "grunt" is a unix file, and "grunt.cmd" is supposed to run the grunt-cli application using node, but it doesn't. I had to create a new file called "grunt.bat" (which takes precedence over "grunt.cmd") that contains

node "%~dp0\node_modules\grunt-cli\bin\grunt" %*

Now it works. Not sure why.

0
votes

You don't need to change TeamCity account from system to local like Christoper wrote. It's simpler way:

1.[build agent machine] Make sure you have node directory and local npm packages directory in your PATH, example:

 C:\Users\'yourUserName'\AppData\Roaming\npm;C:\Program Files\nodejs 
  1. [build agent machine] Install grunt globally: npm install grunt-cli
  2. [build step] Run cmd in your project dirctory: npm install -g grunt-cli. You can do this step only once (on your local machine) and commit file changes to repo
  3. [build step] Run cmd in your project dirctory: npm install
  4. [build step] Run grunt build as powershell script: powershell -Command "grunt build"

In some reason build agent running on system account cant get access to C:\Users\'yourUserName'\AppData\Roaming\npm via cmd, but via powershell can.