Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The batching MSBuild performs here is correct, think about it: you ask it to <code>Message</code> for text <code>%(Server.Identity)</code> so it's going to do that for as many servers as it knows and there's no reason it's gonna wait for oter targets in between. So to get what you want you'll have to make it perform all required tasks once per server. Furthermore your general structure is a bit too complicated. The conditions on the targets are unmanageable: just the fact that you repeat the same condition x times is already a sign something's wrong as it, simply said, violates the DIY principle. Also what if you add another TargetEnv? And then another one? Yep you figured it: won't be nice :] Second possible future pitfall is the use of <code>AfterTargets</code>: it's nice when you only have a couple, but after a while you keep adding targets and you'll have no idea what the order is, you'll basically have to go through the entire file to grasp what's going on. Also what if you add more targets that are common for each TargetEnv? Or if you add another TargetEnv. Again won't be nice as you'll have to fix that in multiple places.</p> <p>Now because you sort of mixed these two complications and threw batching on top of it, things got pretty unclear. Back to the start and think about what you really need: if TargetEnv is A you want to do X and Y and Z, if TargetEnv is B you want to do and Q and Z. That's it. You can consider that as two seperate responsabilities: selecting something based on a condition, and maintaining lists of actions per condition. So let's express this in an msbuild way.</p> <p>Here's the condition part, now in the new Deploy target. The rest of the targets are moved to another file. Deploy will call a target (which one depends on the condition) in the other msbuild file called deploy.targets, in the same directory as the current file. Because the batching is now on a higher level, it will automatically be executed the way you want: once per server. Note the selected server is passed as a property to the other file. There are other ways to do this, but just like with code it's nice to have a couple of smaller files instead of one big do-it-all one.</p> <pre><code>&lt;Target Name="Deploy"&gt; &lt;PropertyGroup&gt; &lt;TargetsFile&gt;$(MsBuildThisFileDirectory)deploy.targets&lt;/TargetsFile&gt; &lt;TargetToCall Condition="$(TargetEnv)=='Production'"&gt;DeployServers&lt;/TargetToCall&gt; &lt;TargetToCall Condition="$(TargetEnv)=='Integration'"&gt;DeployIntegration&lt;/TargetToCall&gt; &lt;/PropertyGroup&gt; &lt;MSBuild Projects="$(TargetsFile)" Targets="$(TargetToCall)" Properties="Server=%(Server.Identity)" /&gt; &lt;/Target&gt; </code></pre> <p>And here's the new file which has all the targets, and two 'master' targets that now specify exactly which other targets they want to have called, no more need for conditions, no more AfterTargets. </p> <pre><code>&lt;Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"&gt; &lt;PropertyGroup&gt; &lt;CommonTargets&gt;CopyFilesAndCreateFolderLinks&lt;/CommonTargets&gt; &lt;/PropertyGroup&gt; &lt;Target Name="DeployIntegration"&gt; &lt;Message Text="= specific int server thing need access to variable $(Server) =" Importance="high" /&gt; &lt;CallTarget Targets="IgnoreRemoveServerFromLoadBalancer;$(CommonTargets)"/&gt; &lt;/Target&gt; &lt;Target Name="DeployServers"&gt; &lt;Message Text="= specific prod thing here need access to variable $(Server) =" Importance="high" /&gt; &lt;CallTarget Targets="RemoveServerFromLoadBalancer;AnotherTargetJustForDeploy;$(CommonTargets)"/&gt; &lt;/Target&gt; &lt;Target Name="RemoveServerFromLoadBalancer"&gt; &lt;Message Text="= removing $(Server) from load balancer =" Importance="high" /&gt; &lt;/Target&gt; &lt;Target Name="AnotherTargetJustForDeploy"&gt; &lt;Message Text="= AnotherTargetJustForDeploy for $(Server) =" Importance="high" /&gt; &lt;/Target&gt; &lt;Target Name="IgnoreRemoveServerFromLoadBalancer"&gt; &lt;Message Text="= ignore removing $(Server) from load balancer =" Importance="high" /&gt; &lt;/Target&gt; &lt;Target Name="CopyFilesAndCreateFolderLinks"&gt; &lt;Message Text=" = creating and copying files $(Server) =" Importance="high" /&gt; &lt;/Target&gt; &lt;/Project&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload