Darthg8r
Darthg8r

Reputation: 12675

MSBUILD batch targets

I want to deploy an application to a list of servers. I have all of the build issues taken care of, but I'm having trouble publishing to a list of servers. I want to read the list of servers from an external file and call a target passing the name of each server in.

<ItemGroup>
    <File Include="$(SolutionFolder)CP\Build\DenormDevServers.txt" />
</ItemGroup>

<Target Name="DeployToServer" Inputs="Servers" Outputs="Nothing">
    <Message Text="Deployment to server done here.  Deploying to server: @(Servers)" />
</Target>

<Target Name="Test">
    <ReadLinesFromFile File="@(File)">
        <Output TaskParameter="Lines" ItemName="Servers" />
    </ReadLinesFromFile>

    <CallTarget Targets="DeployToServer" ContinueOnError="true"></CallTarget>
</Target>

I can't seem to get it to "Deploy" to each server in the list. The output looks like this:

Deployment to server done here.  Deploying to server:

Notice there is no server name, nor is done more than once. There are 2 lines in DenormDevServers.txt

Upvotes: 2

Views: 1317

Answers (3)

Colin Bacon
Colin Bacon

Reputation: 15609

This would be the cleanest approach. Use DependsOnTargets to ensure that Test target is run before DeployToServer.

To get the values of each item in an ItemGroup you must use %(Identity).

The following code will produce the output required.

<ItemGroup>
    <File Include="$(SolutionFolder)CP\Build\DenormDevServers.txt" />
</ItemGroup>

<Target Name="DeployToServer"
        DependsOnTargets="Test">
    <Message Text="Deployment to server done here.  Deploying to server: %(Servers.Identity)" />
</Target>

<Target Name="Test">
    <ReadLinesFromFile File="@(File)">
        <Output TaskParameter="Lines"
                ItemName="Servers" />
    </ReadLinesFromFile>       
</Target>

Upvotes: 0

fsimonazzi
fsimonazzi

Reputation: 3013

You're not using inputs and outputs properly.

Your deploy target should look something like

<Target Name="DeployToServer" Inputs="@(Servers)" Outputs="%(Identity)">
    <Message Text="Deployment to server done here.  Deploying to server: %(Servers.Identity)" />
</Target>

And you should use dependencies rather than explicitly calling targets, e.g.

<Target Name="Test" DependsOn="LoadServers;DeployToServer"/>

And create a new target LoadServers that reads the file into the @(Servers) item.

[edit] The reason for Outputs="%(Identity)" is to get target batching without actually performing up to date checks.

Upvotes: 2

James Woolfenden
James Woolfenden

Reputation: 6651

This achives your result. I think your trying to use tasks a bit too much like methods.

<?xml version="1.0" encoding="utf-8"?>
<Project  xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTarget="Test" >

<ItemGroup>
    <File Include=".\CP\Build\DenormDevServers.txt" />
</ItemGroup>

<Target Name="DeployToServer" DependsOnTargets="Test">
   <Message Text="Deployment to server done here.  Deploying to server: @(Servers)" /> 
</Target>

<Target Name="Test">
    <ReadLinesFromFile File="@(File)">
        <Output TaskParameter="Lines" ItemName="Servers" />
    </ReadLinesFromFile>
</Target>
</Project>

Upvotes: 0

Related Questions