Search code examples
msbuildmsbuild-4.0msbuildcommunitytasksmsbuildextensionpackmsbuild-propertygroup

FTP Credentials for MSBuild.ExtensionPack.Communication.Ftp


In my AfterBuild script I use the following method to upload the files to the deployment server:

<MSBuild.ExtensionPack.Communication.Ftp
TaskAction="UploadFiles"
Host="localhost"
FileNames="$(SomeFolder)\$(FileToUpload)"
UserName="myUserName"
UserPassword="myPassword"
RemoteDirectoryName="/" />

How can I load these credentials from a text file or an external source? What are the alternatives? I don't want to hard-code ftp credentials into my cproj files.

I used GranadaCoders method to answer my own question:

<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="ReadAttribute" File="$(FTP_Credentials_File)" XPath="/parameters/setParameter[@name='host']/@value">
  <Output PropertyName="FtpHost" TaskParameter="Value"/>
</MSBuild.ExtensionPack.Xml.XmlFile>

<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="ReadAttribute" File="$(FTP_Credentials_File)" XPath="/parameters/setParameter[@name='username']/@value">
  <Output PropertyName="FtpUserName" TaskParameter="Value"/>
</MSBuild.ExtensionPack.Xml.XmlFile>

<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="ReadAttribute" File="$(FTP_Credentials_File)" XPath="/parameters/setParameter[@name='password']/@value">
  <Output PropertyName="FtpPassword" TaskParameter="Value"/>
</MSBuild.ExtensionPack.Xml.XmlFile>

<Message Text="Attempting to uploade $(GeneratedZipFile) to $(FtpHost) as read from $(FTP_Credentials_File) ..." Importance="high" />
<MSBuild.ExtensionPack.Communication.Ftp TaskAction="UploadFiles" Condition="Exists('$(FTP_Credentials_File)')"  Host="$(FtpHost)" FileNames="$(PublicFolderToDropZip)\$(GeneratedZipFile)" UserName="$(FtpUserName)" UserPassword="$(FtpPassword)" RemoteDirectoryName="/" />

Solution

  • Put the values in an external xml file. Read the values from the xml file into a variable.

    Parameters.xml

    <?xml version="1.0" encoding="utf-8"?>
    <parameters>
      <setParameter name="LineNumber1" value="PeanutsAreCool" />
      <setParameter name="LineNumber2" value="" />
    </parameters>
    

    MyMsbuild_MsBuildExtensions.proj

    <?xml version="1.0" encoding="utf-8"?>
    <Project  ToolsVersion="4.0"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapped">
    
     <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
    
        <PropertyGroup>
            <!-- Always declare some kind of "base directory" and then work off of that in the majority of cases  -->
            <WorkingCheckout>.</WorkingCheckout>
        </PropertyGroup>
    
        <Target Name="AllTargetsWrapped">
            <CallTarget Targets="ReadXmlPeekValue" />
        </Target>   
    
    
        <Target Name="ReadXmlPeekValue">
    
            <!--  ReadAttribute  -->
            <MSBuild.ExtensionPack.Xml.XmlFile TaskAction="ReadAttribute" File="$(WorkingCheckout)\Parameters.xml" XPath="/parameters/setParameter[@name='LineNumber1']/@value">
                <Output PropertyName="MyValue1" TaskParameter="Value"/>
            </MSBuild.ExtensionPack.Xml.XmlFile>
            <Message Text="MyValue1 = $(MyValue1)"/>        
    
        </Target>   
    
    </Project>
    

    OR

    MyMsbuild_WithCommunityTasks.proj

    <?xml version="1.0" encoding="utf-8"?>
    <Project  ToolsVersion="4.0"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapped">
    
        <!--
      <UsingTask AssemblyFile="$(ProgramFiles)\MSBuild\MSBuild.Community.Tasks.dll" TaskName="Version"/>
      -->
    
    
    
        <Import Project="$(MSBuildExtensionsPath32)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
    
    
    
        <PropertyGroup>
            <!-- Always declare some kind of "base directory" and then work off of that in the majority of cases  -->
            <WorkingCheckout>.</WorkingCheckout>
        </PropertyGroup>
    
        <Target Name="AllTargetsWrapped">
            <CallTarget Targets="ReadXmlPeekValue" />
    
        </Target>   
    
    
        <Target Name="ReadXmlPeekValue">
            <!-- you do not need a namespace for this example, but I left it in for future reference -->
            <XmlPeek Namespaces="&lt;Namespace Prefix='peanutNamespace' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;"
                 XmlInputPath=".\Parameters.xml" 
                 Query="/parameters/setParameter[@name='LineNumber1']/@value">
                <Output TaskParameter="Result" ItemName="Peeked" />
            </XmlPeek>
    
            <Message Text="@(Peeked)"/>
    
            <XmlPeek Namespaces="&lt;Namespace Prefix='peanutNamespace' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;"
                 XmlInputPath=".\Parameters.xml" 
                 Query="/parameters/setParameter[@name='LineNumber1']/@value">
                <Output TaskParameter="Result" PropertyName="PeekedSingle" />
            </XmlPeek>      
    
            <Message Text="PeekedSingle = $(PeekedSingle)   "/>
        </Target>   
    
    
    
    
    
    
    </Project>
    

    EDIT:

    You can add some basic error checking for the values.

    See URL here:

    http://tutorials.csharp-online.net/MSBuild:_By_Example%E2%80%94Dealing_with_MSBuild_Errors

    Short example.. note the condition..and how it checks for an empty string.

        <Error Text="Unable to connect to webserver" Code="Deploy" Condition=" '$(WebURL)' == '' "/>