I have a web application project:
As you can see, there are 3 robots.txt files - one for each environment. There're also 3 publish profiles.
Now, for each pubxml I want to pick the correct "robots.xxx.txt" file and rename it to "robots.txt". Ideally I would like to leverage MSBuild and keep the configuration within each pubxml file.
Each of the 3 publish profiles is using <WebPublishMethod>MSDeploy</WebPublishMethod>
.
EDIT:
Just tried Richard Szalay answer, however to no avail. All 3 files are still copied to the output directory. This is what my publish profile looks like now
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<PrecompileBeforePublish>True</PrecompileBeforePublish>
<EnableUpdateable>True</EnableUpdateable>
<DebugSymbols>False</DebugSymbols>
<WDPMergeOption>DonotMerge</WDPMergeOption>
<ExcludeApp_Data>True</ExcludeApp_Data>
<publishUrl>C:\Temp\myproject</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
<ItemGroup>
<MsDeployReplaceRules Include="robots">
<ObjectName>filePath</ObjectName>
<Match>robots\.debug\.txt</Match>
<Replace>robots.txt</Replace>
</MsDeployReplaceRules>
</ItemGroup>
</Project>
I have no idea if this is technically the right way, but it works for me.
In your pubxml
file, under the PropertyGroup node add this node:
<Target Name="MoveRobotsTxt" AfterTargets="GatherAllFilesToPublish">
<Move Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " SourceFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.release.txt" DestinationFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.txt" />
<Delete Files="obj\$(ConfigurationName)\Package\PackageTmp\robots.release.txt" />
</Target>
If you use more than just Release
, you'll need to copy the Move
command and change the Release|AnyCPU
to your build name or use the special variable $(ConfigurationName).
As you don't have an existing robots.txt you want to replace only if it's the release version, you'll probably want:
<Target Name="MoveRobotsTxt" AfterTargets="GatherAllFilesToPublish">
<Move SourceFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.$(ConfigurationName).txt" DestinationFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.txt" />
</Target>
The big ah-ha for me was realising the pubxml
is just like a project file and you can use all the same commands that you use for msbuild.
While trying to solve this I saw there are a few changes between 2010 and 2012 which might explain why Richard's answer isn't working.
EDIT:
My original answer didn't work with MSBuild for some reason, the pipeline seems different between MSBuild and Visual Studio.
Also targets in the publish profile didn't get run. So I edited my project file adding this at the end after the commented out BeforeBuild/AfterBuild:
<Target Name="move_robots_in_msbuild" AfterTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Move Condition=" '$(Configuration)' == 'Live' " SourceFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.live.txt" DestinationFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.txt" />
<Delete Files="obj\$(ConfigurationName)\Package\PackageTmp\robots.live.txt" />
</Target>
<Target Name="move_robots_in_visual_studio" AfterTargets="GatherAllFilesToPublish">
<Move Condition=" '$(Configuration)' == 'Live' " SourceFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.live.txt" DestinationFiles="obj\$(ConfigurationName)\Package\PackageTmp\robots.txt" />
<Delete Files="obj\$(ConfigurationName)\Package\PackageTmp\robots.live.txt" />
</Target>
What you need is a replace rule. Just add the following to your publish profile:
<ItemGroup>
<MsDeployReplaceRules Include="robots">
<ObjectName>filePath</ObjectName>
<Match>robots\.debug\.txt</Match>
<Replace>robots.txt</Replace>
</MsDeployReplaceRules>
</ItemGroup>
If the file naming convention matches your publish profiles, you can alternatively create a single Robots.wpp.targets
file in the root of your web application and use the following:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<MsDeployReplaceRules Include="robots">
<ObjectName>filePath</ObjectName>
<Match>robots\.$(PublishProfileName)\.txt</Match>
<Replace>robots.txt</Replace>
</MsDeployReplaceRules>
</ItemGroup>
</Project>
I had the same problem this morning but the two answers supplied above didn't work for me either.
Eventually I followed this article - http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/deploying-extra-files
Then added this markup just before the </Project>
tag in my debug, release and staging .pubxml files, renaming robots.release.txt appropriately:
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="robots.release.txt" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>%(RecursiveDir)robots.txt</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With