6
votes

I have installed npm and grunt on our TFS build server. I installed the grunt-cli using npm install -g grunt-cli and was then able to run grunt deploy from the command line when logged in as myself.

Out TFS builds run as the tfsservice user though, and when it attempts to do grunt deploy it gets an error message that:

'grunt' is not recognized as an internal or external command, operable program or batch file.

So, while logged in as myself on the build server, if I run the command prompt as tfsservice I get the same error. So I tried doing npm install -g grunt-cli from that command prompt, and it looked to have installed properly and created the grunt files in C:\Users\tfsservice\AppData\Roaming\npm, but then I still get the same error when running grunt deploy.

So it looks like grunt-cli is not getting installed for tfsservice? When I get the tfsservice %homepath% I see that it is set to \Windows\system32, rather than the expected \Users\tfsservice; maybe it being a service account has something to do with it?

I see that a similar questions has been asked for using grunt-cli with Team City, but it recommends using a Team City specific plugin.

There's also this post which says they changed Team City run as a different user and then everything just started working properly. Changing our builds to run as a different user than tfsservice isn't really an option for me though.

Any suggestions are appreciated. Thanks.

3
What I did by the way is create a NEW user that was running the BuildAgent, not just logging in as tfsservice and then instaling grunt.m90
Yeah, I read that in the linked posts, but we didn't want to create another user; we wanted all of our builds to run as tfsservice as it already had all of the permissions for the various other tasks that the builds needed to perform and servers it needs to interact with.deadlydog

3 Answers

7
votes

After logging in as tfsservice and running npm install -g grunt-cli it placed all of the grunt files in C:\Users\tfsservice\AppData\Roaming\npm, but it couldn't find the C:\Users\tfsservice\AppData\Roaming\npm\grunt.cmd file until I added C:\Users\tfsservice\AppData\Roaming\npm to the System Path; you might be able to get away with creating a new Path variable for just the tfsservice user's variables, but I wanted it to work when logged in as other users too.

enter image description here

Once I did that grunt deploy worked when I was manually logged in as tfsservice and opened a new command prompt, but still wouldn't work when the actual TFS Build performed the build as tfsservice. At first I just modified my build process to call grunt.cmd from the command line by using its full path, like so:

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

and made sure that I ran npm install -g grunt-cli as tfsservice on all of my build machines to make sure grunt exists in the tfsservice user's AppData directory on each build server. This worked, but was more of a workaround than a fix.

Turns out the final step was I just had to reboot the TFS Build server. Once I did that grunt deploy worked as expected for the builds, so I didn't need to specify the full path anymore :) Simply restarting the tfsservice might have been enough, but I just rebooted the PC to be safe.

1
votes

I also experienced this failure. Adding the npm folder to the global path and rebooting the server did fix this.

1
votes

We faced the same issue and we did the following:

First of all we installed every software on the our system user that is also used for the build.

To find out which user will be used we added a batch file with echo %username% and added the "Batch Script" task to the build process and let this task execute our script.

So we could install all needed Software on the TFS with the same user the TFS is using if it is building an artefact.

We tried if npm is working, grunt is installed globally and also ruby got its sass gem. And everything works fine after some configurations and adding of missed path variables.

So we knew that the build user is understanding all given batch commands, because we also tried it with this user looged in. right?

wrong =( ... every build always showed us:

'grunt' is not recognized as an internal or external command, operable program or batch file.

as well as npm and ruby sass.

So we executed a batch script in the same described way with just echo %path% as its content.

After a lot of failed builds and calling all tools via batch script and absolute path we found this article and simply restarted the TFS and everything woks like a charm.

So it seems the TFS is caching the given path vars and did not looks for them on every build. Some other explanation, or tips how to avoid this behavior of the TFS?

I found a way for the same behavior oft the windows cli, and could imagine it is still the same problem so we could run this script before every build. But that looks a bit hacky for my opinion.

Thx guys for the nice posts.