Team City is cleaning directory when I don't want it to

My issues is similar to the old post here: https://teamcity-support.jetbrains.com/hc/en-us/community/posts/206912195-TeamCity-cleaning-out-checkout-directory-even-when-clean-files-disabled but my scenario is different and the cause is not the same.

I have a single .Net solution which has several projects in it which have dependencies on each other. To make it simple to understand, assume there are two: Common and Models with Models => Common. I am trying to get the nuget version dependencies to work.

They run as separate build configurations but use the same VCS root with no checkout rules so they all checkout into the same directory and they all build fine.

I build Common, it correctly injects the build version into the csproj as PackageVersion. I then run the Models build.

Expected:

No files are modified since they are all up to date (except the locally modified Common csproj) so models correctly packs the dependency version with dotnet pack.

Actual:

Running the Models build cleans the directory, replacing the csproj for Common, which resets its version back to 1.0.0, which breaks the nuget versioning.

None of the clean options are checked in the VCS root settings (although Clean policy is set to On Branch Change) or in the Version Control Settings of the specific build configurations.

Can you tell me what I've missed?

0
5 comments

Hi Luke,

 

the build log registers the reason as to why it decides to run a clean checkout. Without it, it's hard to say, but it's likely that your modification of the file tells TeamCity that the folder isn't clean.

 

If you are modifying the versioning with the FileContentReplacer or AssemblyInfo Patcher, you should take into account that this features only affect the running build and will be reversed when it finishes.

0

Hi Denis,

Thanks for the reply

Whether or not TeamCity thinks the folder clean should not matter. There are a list of reasons why an automatic clean is performed at https://confluence.jetbrains.com/display/TCD18/Clean+Checkout and modified files is not one of them. The only thing I can see in the build log is below. Note the "git reset --hard". I can't see why it is cleaning it, it just is. (I've shortened some of the paths below to make it more readable)

I am also not completely clear what the option in the Agents tab does since it is a hyperlink which opens a list and doesn't add anything you select into a list. The docs make it sound like an automatic clean every time but the software looks more like it only does it once for the selected build.

[VCS Root: SharedLibraries_VSTS] Update checkout directory (C:\buildAgent\work\2357397f21417b8a)
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" config lfs.storage C:\buildAgent\system\git\git-D5CF150B.git\lfs
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" config core.sparseCheckout true
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" config http.sslCAInfo
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" config --unset http.sslCAInfo
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" show-ref
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" show-ref refs/remotes/origin/master
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" log -n1 --pretty=format:%H%x20%s d9838782d2b83a05f7450ef1d75ee127afe4f518 --
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" branch
 [Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" -c core.askpass=C:\buildAgent\temp\buildTmp\pass7758368607134247885.bat -c credential.helper= -c credential.helper=C:/buildAgent/temp/buildTmp/credHelper4722241083680486082.bat reset --hard d9838782d2b83a05f7450ef1d75ee127afe4f518
[Update checkout directory (C:\buildAgent\work\2357397f21417b8a)] "C:\git.exe" branch --set-upstream-to=refs/remotes/origin/master

0

Hi Luke,

 

sorry for the delay, went out of office for a few weeks and couldn't answer any sooner

 

A Clean checkout in TeamCity is a very specific concept, and when TeamCity performs a clean checkout it registers a message in the build log, as already mentioned, indicating why it's happening. The log you copied only shows the reset --hard from git, but the decision to perform a clean checkout should be performed quite a bit earlier, normally a few lines above the "Update checkout directory" message.

0

Hi Denis, I have modified the way the projects build to work around this issue (using artifacts and snapshot dependencies) but the log above "Update checkout directory" is this (with some content removed to make it easier to read):

There is no mention of clean in the build log at all so I wonder what causes it to go a git reset hard?

Updating sources: auto checkout (on agent) (1s)
[Updating sources] Will use agent side checkout
[Updating sources] VCS Root: SharedLibraries_VSTS (1s)
[VCS Root: SharedLibraries_VSTS] revision: 7a6f2ec9cde979c14a4af31d655594a35b38a161
[VCS Root: SharedLibraries_VSTS] Git version: 2.15.0.0
[VCS Root: SharedLibraries_VSTS] Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" config http.sslCAInfo
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" config --unset http.sslCAInfo
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" show-ref
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" -c core.askpass=C:\buildAgent\temp\buildTmp\pass5197808906544297765.bat -c credential.helper= ls-remote origin
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" show-ref refs/remotes/origin/master
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" show-ref refs/heads/master
[Update git mirror (C:\buildAgent\system\git\git-D5CF150B.git)] "C:\git.exe" pack-refs --all

 

0

Hi Luke,

 

When teamcity performs checkout, yes, it does update the files locally to make sure they match the revision that was requested for the build itself. I was getting quite confused because a reset --hard does not clean untracked files, and thus any changes to untracked files or any kind of untracked files created by previous builds would stay there.

 

I'd like to mention that your scenario seems a bit strange. If you separate the build into two different build configurations, the checkout step happens and this behavior would be expected, but also, if you have multiple agents, unless you have configured the builds not to do so, the builds might be distributed to different agents, rendering your initial changes useless.

 

For a 2-build chain, this has a pretty simple solution: Run all sequentially as a single build instead of multiples. Your scenario seems to be quite more complex, so I would recommend different approaches, from easier and more flexible, to usually worse but still covering some niche scenario:

  • Set up the modified files as build artifacts of the builds which modify them, then pull those files via artifact dependencies. This gives you the flexibility of being able to use multiple agents without caring whether the previous builds were run on the same place or not.
  • Push the libraries to a dedicated dependency system (nuget, even the integrated one would do) and pull the dependencies from it.
  • Set up the generated libraries as build artifacts and pull those entirely instead.
  • Make the builds that change working files create a commit with the modified files, then on the builds that need to reuse those files, run a manual step that pulls the newer commit (TeamCity will run the full build chain under the same commit otherwise)
  • Join the multiple build configurations as a single build with multiple build steps. Checkout is not performed between steps so all changes you do will stick.

Would that help?

0

Please sign in to leave a comment.