We have an NAnt script to update our "pre-built" assemblies in TFS as one of our TeamCity build projects. The build is triggered by other builds. It does a TF checkout, moves some files, then does a TF checkin.
The relevant target (tf resolves to the path of TF.exe):
<target name="checkin.assemblies">
<exec program="${tf}">
<arg value="checkin" />
<arg value="${dir.assemblies}" />
<arg value="/comment:${message}." />
<arg value="/noprompt" />
<arg value="/recursive" />
</exec>
</target>
Regularly we get:
Checking in edit: ... The following changes were not checked in because the items were not modified. Undoing edit: ... There are no remaining changes to check in. External Program Failed: E:\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe (return code was 1) Process exited with code 1 BUILD FAILED - 0 non-fatal error(s), 1 warning(s)
What I think is happening is the build gets triggered once too many times (there are several builds that can trigger it). If the files we want to update didn't change, TFS skips the check-in and "helpfully" returns an error code. Unfortunately it will also return 1 for "locked for check-out" errors, which are severe.
For reference: TF Command-Line Exit Codes
The workaround is simple but annoying - fire off one of the builds that will bump an assembly's version number and then trigger this build.
How can we make this work reliably?
Update: We ended up revising the build triggering configurations for TeamCity to create build “chains,” insuring that checkin only gets triggered once.