3
votes

Let's say you have multiple build agents configured and you have a folder on the build agents that has some content in it that isn't from TFS (even specifying Output, some intermediate stuff like the obj folder might be generated in a project folder for example) and you deleted the folder in TFS.

Next time you'd build, you'd get an cannot be deleted because it is not empty. error. When triggering the build, you could add the Build.Clean variable as all or source to your next build to fix it. However, since you have multiple agent, only the next agent running will receive that command and clean, and any other builds you make that falls on another agent will fail again because they still have the folder.

Editing the whole build definition so they do a full clean every build would be overkill.

I am of course looking for something else than "Go in the actual folders and delete the folders manually". If it changes anything, the agents aren't hosted, but on premises.

Edit: Logs from the build server, starting with the last cannot be deleted warning:

2017-03-14T20:23:24.2384009Z d:\vso\b1\_work\32\s\[Obfuscated] cannot be deleted because it is not empty.
2017-03-14T20:23:24.4964210Z ##[error]Exit code 1 returned from process: file name 'tf', arguments 'vc get /version:24617 /recursive /overwrite d:\vso\b1\_work\32\s /loginType:OAuth /login:.,******** /noprompt'.
2017-03-14T20:23:24.5124180Z ##[debug]Microsoft.VisualStudio.Services.Agent.ProcessExitCodeException: Exit code 1 returned from process: file name 'tf', arguments 'vc get /version:24617 /recursive /overwrite d:\vso\b1\_work\32\s /loginType:OAuth /login:.,******** /noprompt'.
   at Microsoft.VisualStudio.Services.Agent.ProcessInvoker.<ExecuteAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Worker.Build.TfsVCCommandManager.<RunCommandAsync>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Worker.Build.TFCommandManager.<GetAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Worker.Build.TfsVCSourceProvider.<GetSourceAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Worker.Build.BuildJobExtension.<PrepareAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Worker.JobExtensionRunner.<RunAsync>d__30.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Services.Agent.Worker.StepsRunner.<RunAsync>d__0.MoveNext()
2017-03-14T20:23:24.5174212Z ##[section]Finishing: Get Sources
1
What's the detail scenario that only one of them will receive that command and clean? As far as I know, the files will be clean before build if you set clean to true (source) for repository. On the other hand, you can check Clean option for Visual Studio Build step/task.starian chen-MSFT
@starain-MSFT When you set a variable when triggering a build, that variable is only set for the current build, right? If so, the other agents who aren't processing the next build won't receive it, and clean won't happen on their folders.Tipx
Do you mean set variable value when queue the build? You can Set clean to true in Repository tab of build definition. On the other hand, what's the detail scenario that it throws cannot be deleted because it is not empty? Can you provide the detail steps?starian chen-MSFT
I could set the build definition (in the build tab) to Clean, but that would mean each build would do it, until I'd change it back. The step to reproduce it is to build some solutions/project, and then remove the project from TFS. TFS is not aware of the previously built items (like the obj) and can't delete the folder.Tipx
I made a test with VSTS, I get cannot be deleted because it is not empty warring (yellow color) instead of error. What's the version of your TFS? Are there other errors during your build? Can you share the detail build log here?starian chen-MSFT

1 Answers

1
votes

Ran into this topic through Google. We have the same scenario and i tried to explain it here too.

Basically how we now fixed it is we created a new build definition that we use to queue new builds with the Build.Clean = all parameter.

So we have a PowerShell script that loops over all AgentsNames we want to clean and queue a new clean build and add the Demand "Agent.Name -equals agentName". this way your clean build is queued on all agents you want to clean.