I have searched the interwebs far and wide and the documentation on customising the pubxml file is ridiculously limited. Even in this day and age of automation.
What is the pubxml file?
The pubxml file is what Visual Studio/MSBuild uses to publish a project. This may include as a basic description, the location of where the files will go, what build configuration (Debug, Release etc.) to use, what method to use (FileSystem, MSDeploy etc) etc.
Example of a basic template
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">The UI that is provided in Visual Studio does not expose what can be created in the PubXml file. In this post I just want to focus on creating a file during the publish process.
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:\Deployments\SomeName\</publishUrl>
<DeleteExistingFiles>false</DeleteExistingFiles>
</PropertyGroup>
</Project>
Scenario
For an example I want to create two files one will be a nuspec file and another a powershell script. Contents are not important for now.
To create the file(s) you need to use a custom Target node. Example below,
<Target Name="CreateFiles" AfterTargets="GatherAllFilesToPublish">
<Message Text="Creating Powershell script" Importance="high"></Message>
<WriteLinesToFile File="$(PublishUrl)CustomCreatedNuspecFile.nuspec" Overwrite="true" Lines="[Contents to go into this file]">
</WriteLinesToFile>
<WriteLinesToFile File="$(PublishUrl)AGoodPowerShellScript.ps1" Overwrite="true" Lines="[Content to go into this file]">
</WriteLinesToFile>
</Target>
That's it. As you can see its pretty straightforward. The AfterTargets is the crucial part as this tells the publish process when to execute the Target node. I have tried to find a definitive list of what can go in here, except for AfterBuild, BeforeBuld, CopyAllFilesToSingleFolderForMsdeploy, GatherAllFilesToPublish and custom Target names (like CreateFiles) I cannot find one.
However I have found out that if you look in your own system there is a file which contains some information. For the case if you have Visual Studio 2015 installed go to
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.targetsWhich supposedly contains it all but you have to work out what each one does, its over 4500 lines long, so good luck with that.
Ok, more clarity of what Target can do.
So say you want to get the version of the assembly your publishing from and spit that out in a text file. You can put the below xml into the pubxml file.
<Target Name="AfterCompile">
<GetAssemblyIdentity AssemblyFiles="$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)">
<Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
</GetAssemblyIdentity>
<PropertyGroup>
<ApplicationVersion>%(AssemblyInfo.Version)</ApplicationVersion>
</PropertyGroup>
</Target>
<Target Name="CreateVersionFile" DependsOnTargets="AfterCompile" AfterTargets="GatherAllFilesToPublish">
<Message Text="Creating text file" Importance="high"></Message>
<WriteLinesToFile File="$(PublishUrl)ProjectVersion.txt" Overwrite="true" Lines="Version : $(ApplicationVersion)">
</WriteLinesToFile>
</Target>
Again I have tried to find a list of all the $(..) parameters that there are and again I can not find one. Its one of those things that if you search for specifically what you want and hopefully someone out there has written/answered a question about it.
Finally you can take this a little further and create a file using the below example.
<Target Name="CreateFile" AfterTargets="GatherAllFilesToPublish ">
<ItemGroup>
<Line Include="line01">
<Text>
First Line
</Text>
</Line>
<Line Include="line02">
<Text>
Second Line
</Text>
</Line>
<Line Include="line03">
<Text>
Third Line
</Text>
</Line>
<LineText Include="%(Line.Text)" />
</ItemGroup>
<WriteLinesToFile File="$(PublishUrl)ProjectVersion.txt" Lines="@(LineText)" Overwrite="true"/>
</Target>
With this method you can control each line, if you want to, or just have one Line node that has all your text in there like below
<Target Name="CreateFile" AfterTargets="GatherAllFilesToPublish ">Either method of creating a file is fine just pick one that suits you. Just make sure that if someone else picks it up its clear and makes sense.
<ItemGroup>
<Line Include="line01">
<Text>
First Line
Second Line
Third Line
</Text>
</Line>
<LineText Include="%(Line.Text)" />
</ItemGroup>
<WriteLinesToFile File="$(PublishUrl)ProjectVersion.txt" Lines="@(LineText)" Overwrite="true"/>
</Target>
Also, I have seen a lot of Stackoverflow answers say that AfterPublish is a target that is available, which will fire after the publish has completed. I don't think that is true and has resulted in a lot of copy and paste of a supposedly correct answer. What you can do is create a target called AfterPublish and then you can set that in another Target's AfterTargets or DependsOnTargets attribute.
No comments:
Post a Comment