Nodejs npm step downloads packages on every build in TeamCity

The best way i found to fix this was to backup/restore the node modules folder, i've done a blog post about it here

https://beerandserversdontmix.com/2016/06/04/teamcity-and-avoiding-redownloading-of-npm-packages/


I don't know about Node.js, but here are a couple TeamCity-specific suggestions:

  1. Does NPM perhaps download the files into %TEMP%? If so, they won't be reusable between subsequent TeamCity builds because a TeamCity agent hijacks the %TEMP% directory (redirects it to <TeamCity Home>/buildAgent/temp/buildTmp) and always completely wipes this directory before every new build. (See buildTmp here.)
    • In that sense, it would be preferable if you could instruct NPM to store the downloaded files in the workspace (the directory where you checkout your build) instead.
  2. If NPM is downloading into the workspace (the checkout dir), have you perhaps requested to do a clean checkout on every run? (See Edit Configuration Settings | Version Control Settings | Show advanced options | Clean all files in the checkout directory before the build checkbox.)
    • In that case, uncheck the checkbox.
  3. Is perhaps TeamCity cleaning up the checkout directory due to low disk space? This clean-up kicks in automatically when TeamCity notices it's running out of space. (The clean-up can be made even more aggressive with the Free disk space build feature.)
    • In that case, stop using the build feature. If it's not used and the automatic clean-up is to blame, it's hard to control. It's best if you simply clean-up that part of your file-system which is not managed by TeamCity (your own %TEMP% and other places) and thus give some leeway to TeamCity.
  4. Is your build running on a different agent every time? (Consult the build history.) If so, it cannot reuse the downloaded artifacts (even if they are downloaded into the checkout dir), since they are downloaded to a different machine's filesystem every time. I doubt this is the case though, since TeamCity gravitates towards agent-workspace reuse (sticking to the same agent).
    • In that case, you can force agent reuse by setting an agent requirement, specifying that you want your builds to run on one specific agent all the time. You can also single that agent out into its own pool, so that no other builds can run on it.