MSDeploy skip rules when using MSBuild PublishProfile with Visual Studio 2012 - visual-studio

I'm trying to use WebDeploy to publish a website using custom MSDeploy skip rules and a publish profile saved in Visual Studio 2012.
I have the publish profile working from the command line, but the skip rule to skip deleting a folder isn't working.
I have an ErrorLog subfolder in my web app with a web.config file inside it to set the proper folder permissions. Without any skip rules, the ErrorLog folder and web.config file are published normally, but all existing error log files in the folder on the server are deleted on publish.
Error with <SkipAction>Delete</SkipAction>
When I add a custom skip rule to my wpp.targets file, the skip rule is no longer accepting a value for the <SkipAction> element. If I set <SkipAction>Delete</SkipAction>, I get the following error:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets(4377,5): error : Web deployment task failed. (Unrecognized skip directive 'skipaction'. Must be one of the following: "objectName," "keyAttribute," "absolutePath," "xPath," "attributes.<name>.") [C:\inetpub\wwwroot\My.Website\My.Website\My.Website.csproj]
If I simply omit the <SkipAction> element, the ErrorLog folder is deleted when it would normally be published.
If I set <SkipAction></SkipAction>, again, the ErrorLog folder is deleted on publish.
If I set <KeyAttribute>Delete</KeyAttribute>, then ErrorLog and the web.config file are published normally.
My understanding is that in order to use custom skip rules, you need to call MSBuild from the command line instead of publishing from within VS 2012. I'd still like to use my saved publishing profiles, however, and I understand that's now possible as of VS 2012.
My MSBuild command line:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe My.Website.sln /p:Configuration=Release;DeployOnBuild=true;PublishProfile="Test Server - Web Deploy"
My.Website.wpp.targets:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipErrorLogFolder1">
<SkipAction></SkipAction>
<KeyAttribute>Delete</KeyAttribute>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_Escaped_WPPAllFilesInSingleFolder)\\ErrorLog$</AbsolutePath>
<XPath></XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
</Project>
My MSBuild output showing the custom skip rule, but still deleting the files:
GenerateMsdeployManifestFiles:
Generate source manifest file for Web Deploy package/publish ...
AddCustomSkipRules:
Adding Custom Skip Rules
MSDeployPublish:
Start Web Deploy Publish the Application/package to http://testserver.domain.com/MSDEPLOYAGENTSERVICE ...
Starting Web deployment task from source: manifest(C:\inetpub\wwwroot\My.Website\My.Website\obj\Release\Package\My.Website.SourceManifest.xml) to Destination: auto().
Deleting filePath (MyWeb/ErrorLog\test.txt).
Updating setAcl (MyWeb/).
Updating setAcl (MyWeb/).
Updating filePath (MyWeb/ErrorLog\Web.config).
Updating filePath (MyWeb/Web.config).
Updating setAcl (MyWeb/).
Updating setAcl (MyWeb/).
Successfully executed Web deployment task.
Publish is successfully deployed.

Edit: It turns out you are right: the skip directive is ignored when executed from Visual Studio.
Fortunately, there's a workaround.
What you want is this:
<!-- Skip the deletion of any file within the ErrorLog directory -->
<MsDeploySkipRules Include="SkipErrorLogFolder1">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>ErrorLog</AbsolutePath>
</MsDeploySkipRules>
In addition, you need to prevent VS from using the UI-task (which appears to contain a bug regarding the skip rules). You can do this by declaring the following in your wpp.targets or pubxml:
<PropertyGroup>
<UseMsDeployExe>true</UseMsDeployExe>
</PropertyGroup>
I've tested this locally and I can confirm that it works as desired: the additional file is updated but no files in the directory are deleted.

For reference, here is my complete .wpp.targets file with working skip rule to skip deleting the ErrorLog folder and custom ACLs to make the ErrorLog folder writable on the server.
As of VS 2012 Update 3, this only works when publishing with MSBuild from the command line with the DeployOnBuild=true;PublishProfile="Test Server - Web Deploy" options passed to MSBuild. This will not work when publishing from within VS.
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UseMsdeployExe>true</UseMsdeployExe> <!-- Required for the MSDeploySkipRules to work -->
<DeployManagedPipelineMode>Integrated</DeployManagedPipelineMode>
</PropertyGroup>
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>
$(AfterAddIisSettingAndFileContentsToSourceManifest);
AddCustomSkipRules;
</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipErrorLogFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>ErrorLog</AbsolutePath>
<XPath></XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>
$(AfterAddIisSettingAndFileContentsToSourceManifest);
SetCustomACLs;
</AfterAddIisSettingAndFileContentsToSourceManifest>
<AfterAddDeclareParametersItemsForContentPath>
$(AfterAddDeclareParametersItemsForContentPath);
SetCustomAclParameters;
</AfterAddDeclareParametersItemsForContentPath>
</PropertyGroup>
<Target Name="SetCustomACLs">
<Message Text="Setting Custom ACLs" />
<ItemGroup>
<!--Make sure the application pool identity has write permission to the download folder-->
<MsDeploySourceManifest Include="setAcl"
Condition="$(IncludeSetAclProviderOnDestination) And Exists('$(_MSDeployDirPath_FullPath)\ErrorLog')">
<Path>$(_MSDeployDirPath_FullPath)\ErrorLog</Path>
<setAclAccess>Write</setAclAccess>
<setAclResourceType>Directory</setAclResourceType>
<AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="SetCustomAclParameters">
<Message Text="Setting Custom ACL Parameters" />
<EscapeTextForRegularExpressions Text="$(_MSDeployDirPath_FullPath)">
<Output TaskParameter="Result" PropertyName="_EscapeRegEx_MSDeployDirPath" />
</EscapeTextForRegularExpressions>
<ItemGroup>
<MsDeployDeclareParameters Include="Add write permission to ErrorLog folder"
Condition="$(IncludeSetAclProviderOnDestination) and Exists('$(_MSDeployDirPath_FullPath)\ErrorLog')">
<Kind>ProviderPath</Kind>
<Scope>setAcl</Scope>
<Match>^$(_EscapeRegEx_MSDeployDirPath)\\ErrorLog$</Match>
<Description>Add write permission to ErrorLog folder</Description>
<DefaultValue>Default Web Site/ErrorLog</DefaultValue>
<Value>$(DeployIisAppPath)/ErrorLog</Value>
<Tags>Hidden</Tags>
<Priority>$(VsSetAclPriority)</Priority>
<ExcludeFromSetParameter>True</ExcludeFromSetParameter>
</MsDeployDeclareParameters>
</ItemGroup>
</Target>
</Project>

Another approach is to avoid the SkipAction tag, I've successfully used this setup directly from VS 2013:
<Target Name="AddCustomSkipRules"
AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipMedia">
<objectName>dirPath</objectName>
<absolutePath>media</absolutePath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipUpload">
<objectName>dirPath</objectName>
<absolutePath>upload</absolutePath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
Only caveat as far as I can tell is that, it will ignore both update, delete and add operations.

After many hours looking through the net. i created this file as {myprojectname}.wpp.targets under the site root folder. it works when publishing with visual studio. the media folder is ignored. i am using VS 2010.
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<UseMsdeployExe>true</UseMsdeployExe>
<!-- Required for the MSDeploySkipRules to work -->
<DeployManagedPipelineMode>Integrated</DeployManagedPipelineMode>
</PropertyGroup>
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>
$(AfterAddIisSettingAndFileContentsToSourceManifest);
AddCustomSkipRules;
</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules - WPP Targets 2" />
<ItemGroup>
<MsDeploySkipRules Include="SkipErrorLogFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>media</AbsolutePath>
<XPath></XPath>
<Apply>Destination</Apply>
</MsDeploySkipRules>
</ItemGroup>
</Target>
</Project>

I think the problem is in incorrect AbsolutePath. It should be a regular expression to match file or folder. so it should be properly escaped. Below is the sample which worked for me (I wanted to skip removal of app_offline.htm to make delivery part of larger deployment)
<PropertyGroup>
<PackageUsingManifestDependsOn>$(PackageUsingManifestDependsOn);AddCustomSkipRules</PackageUsingManifestDependsOn>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<ItemGroup>
<MsDeploySkipRules Include="SkipAppOfflineOnDeploy">
<SkipAction></SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>app_offline\.htm</AbsolutePath>
<Apply>Destination</Apply>
<XPath></XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>

Works for me: My Full prepprod.pubxml file in my App_Data/PublishProfiles folder in my web solution. Web Deploy no longer deletes files out of the cachefiles folder on webdeploy from VS 2015. The first PropertyGroup was auto-generated by using the web publishing gui in Visual Studio. I added the second PropertyGroup, and the Target section from previous comments.
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Production</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>{masked}</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>{masked}</MSDeployServiceURL>
<DeployIisAppPath>{masked}</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<MSDeployUseChecksum>true</MSDeployUseChecksum>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>{masked}</UserName>
<_SavePWD>True</_SavePWD>
<PublishDatabaseSettings>
<Objects xmlns="">
</Objects>
</PublishDatabaseSettings>
<ExcludeFilesFromDeployment>packages.config;*.bat;*.sln;*.suo,*.p4ignore</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>packages;cachefiles;.ebextensions</ExcludeFoldersFromDeployment>
</PropertyGroup>
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>
$(AfterAddIisSettingAndFileContentsToSourceManifest);
AddCustomSkipRules;
</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipcachefilesFolder">
<objectName>dirPath</objectName>
<absolutePath>cachefiles</absolutePath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
</Project>

This worked for me in vs 2015, website project type:
<!--Added inside existing <ProjectGroup> tag-->
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
<!--Added new ProjectGroup tag inside <Project></Project>-->
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
</PropertyGroup>
<!--Added inside existing <Project> tag at the bottom-->
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipConfigFolder">
<SkipAction></SkipAction>
<!--<KeyAttribute>Delete</KeyAttribute>-->
<ObjectName>dirPath</ObjectName>
<AbsolutePath>App_Data\\Composite\\Logfiles</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>

Related

Azure: Include unreferenced DLLs when publish

I was struggling to publish my project because some DLLs were missing. After some investigations, I found what I was looking for:
http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx
Here my code:
<Target Name="CustomCollectFiles">
<Message Text="Publishing unreferenced DLLs" Importance="High" />
<ItemGroup>
<_CustomFiles Include="$(UnreferencedDlls)" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
It is working fine now but only when I publish on local. When I try to publish on Azure, these same DLLs are missing. So I tried to add the following line:
<DestinationRelativePath>obj\Release\Package\PackageTmp\bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
Because when I publish on azure, the Output says:
Copying all files to temporary location below for package/publish:
obj\Release\Package\PackageTmp.
But still, the DLLs are missing and I have no idea how to add them when I'm publishing on Azure.
I find a solution. The first one add the DLLs when I deploy on my local machine and the second do the same thing but when I deploy the app on Azure.
<PropertyGroup>
<!-- Publish on the FILE SYSTEM -->
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<!-- Publish on AZURE: Web Deploy -->
<CopyAllFilesToSingleFolderForMSDeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForMSDeployDependsOn);
</CopyAllFilesToSingleFolderForMSDeployDependsOn>
</PropertyGroup>

Exclude `.js` files but not '.min.js' files from MSBuild publish

Using Visual Studio and MSBuild I would like to be able to exclude all .js files and include all .min.js files in my deployments.
I know this can be achieved using the file properties in visual studio, but this is not an option as there are far too many files.
I have the following PublishProfile in my Visual Studio project. Everything works just fine apart from the <ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Delpoy-Static</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>True</ExcludeApp_Data>
<publishUrl>\\***\wwwroot\***.com\static</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
<!--This does not work, but gives the idea of what I want to achieve-->
<ItemGroup>
<Deploy Exclude="**\*.js" Include="**\*.min.js" />
</ItemGroup>
</Project>
Can this be achieved using the PublishProfile? If so, how?
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<!-- ... -->
</PropertyGroup>
<Target Name="BeforeBuild">
<ItemGroup>
<Minified Include="**\*.min.js" />
<Maxified Include="**\*.js" Exclude="#(Minified)" />
<Content Remove="#(Maxified)" />
</ItemGroup>
</Target>
</Project>
Edit:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<!-- ... -->
</PropertyGroup>
<ItemGroup>
<Minified Include="**\*.min.js" />
<Maxified Include="**\*.js" Exclude="#(Minified)" />
</ItemGroup>
<PropertyGroup>
<ExcludeFoldersFromDeployment>bin</ExcludeFoldersFromDeployment>
<ExcludeFilesFromDeployment>#(Maxified);Web.config</ExcludeFilesFromDeployment>
</PropertyGroup>
</Project>
If you want to exclude files you can place the files to be excluded in the the ExcludeFromPackageFiles item group. In your case you want to take all .js files and exclude all but those that are *.min.js. To do that in your .pubxml file add the following in your .pubxml file .
<ItemGroup>
<ExcludeFromPackageFiles Include="js\**\*.js" Exclude="js\**\*min*.js">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFiles>
</ItemGroup>
Note: this snippet assumes that your .js files are in a folder named js.
work to me:
Edit .csproj file
Find section MinifyJavaScriptAndCSS
Edit property Exclude in JS tag
Add directory or files to ignore during publish
<Target Name="MinifyJavaScriptAndCSS" AfterTargets="CopyAllFilesToSingleFolderForPackage" Condition="'$(Configuration)'=='Release'">
<ItemGroup>
<!-- Every .js file (exclude *.min.js and *.vsdoc.js files) -->
<JS Include="$(_PackageTempDir)\**\*.js" Exclude="$(_PackageTempDir)\**\*.min.js;$(_PackageTempDir)\**\*vsdoc.js;" />
<CSS Include="$(_PackageTempDir)\**\*.css" Exclude="$(_PackageTempDir)\**\*.min.css" />
</ItemGroup>
<AjaxMin JsKnownGlobalNames="jQuery,$" JsSourceFiles="#(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".js" CssSourceFiles="#(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".css" />
<Message Text="[pcv] $(MSBuildProjectName) -> Minified: #(JS)" Importance="high" />
<Message Text="[pcv] $(MSBuildProjectName) -> Minified: #(CSS)" Importance="high" />

Get static content to copy to TFS Build Drop location

I'm using TFS 2013 / VS 2013.
For various reasons, I need some static content copied to a TFS build drop location. I've created a custom project type that simply copies a directory structure/files to an output path.
I would expect that TFS would then take everything in the output path and copy it to the drop location, but it's not. No files from my project show up in the drop location.
Here is my proj file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputPath>db\</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Target Name="Build">
<Copy SourceFiles="#(Content)" DestinationFiles="#(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Exec Command="rd /s /q $(OutputPath)" Condition="Exists($(OutputPath))" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<ItemGroup>
<Content Include="**\*.*" Exclude="db\**\*.*;*.csproj;*.rgdbproj;*.vspscc" />
</ItemGroup>
</Project>
When I build this in Visual Studio, I get the desired directory structure to appear in the /db folder.
In TFS 2013 you can specify a pre-build and post-build script. You can run PowerShell scripts to copy the files. See below question on how to do it. You will have to use TfvcTemplate.12.xaml for that.
Where can we open the `Post-build script` box of a build process template?
I was able to resolve this issue by changing all my references from OutputPath to OutDir. Apparently, OutputPath is deprecated and OutDir is what TFS Build pays attention to. Here is my final build script:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputPath>db\</OutputPath>
<OutDir>db\</OutDir>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Target Name="Build">
<Copy SourceFiles="#(Content)" DestinationFiles="#(Content->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Exec Command="rd /s /q $(OutDir)" Condition="Exists($(OutDir))" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<ItemGroup>
<Content Include="**\*.*" Exclude="db\**\*.*;*.csproj;*.rgdbproj;*.vspscc" />
</ItemGroup>
</Project>
In your build file, you can define a target for copying files:
<Target Name="CopySomeFiles">
<ItemGroup>
<SomeFiles Include="$(SourceFolder)\*.*"></SomeFiles>
</ItemGroup>
<Copy SourceFiles="#(SomeFiles)" DestinationFolder="$(DestFolder)" SkipUnchangedFiles="false"/>
</Target>
You can then add this target where you want, e.g. after compile:
<Target Name="AfterCompile"
DependsOnTargets="CopySomeFiles">
</Target>

Web deployment: Exclude directories depending on Project Configuration name

I want to delete some image resources depending on what build I'm releasing using MsDeploy.
I have three builds for different clients which are basicly another theme and a lot of configuration transforms to setup their environments correctly.
I donĀ“t want to include the image resources for client1 when deploying to client2.
Been using this as a reference for making my first stumbling steps into customizing msdeploy and it works good but I have no idea what variable to get the configuration name.
In pseudo code:
if $configurationName == "client1"
exclude dirs gfx/client2 and gfx/client3
if $configurationName == "client2"
exclude dirs gfx/client1, gfx/client3
and so on...
May be its even possible to exclude all and then include just the one which is needed?
I have posted an entry on my blog about this at http://sedodream.com/2010/08/15/WebDeploymentToolMSDeployHowToExcludeFilesFromPackageBasedOnConfiguration.aspx. Here is the summary:
You use the same approach as in my previous answer, ExcludeFromPackageFiles but you just put a condition on it. So if you have files under scripts folder with 'debug' in the file name that you want to exclude from any package which not built under debug configuration the way you do it is
<ItemGroup Condition=" '$(Configuration)'!='Debug' ">
<ExcludeFromPackageFiles Include="scripts\**\*debug*" />
</ItemGroup>
More details on my blog, but its a simple mod to the previous approach.
Thanks for both your answers. I fixed everything now, struggled alot with including a build and migration for my database (migrator.net) but I cheated and did it through the runcommand instead.
I thought I post my whole deployment process here so people who read this post might learn from all my misstakes.
The basic steps are:
Web.config transforms to make sure all settings are correct for each of the clients
Backup of webserver files and database at the production server
Exclude all gfx directories for all clients
Include the gfx dir which is wanted by this client
Include extra binares and license-files which are not referenced by the project correclty
Migrate the database to the current revision
Webdeploy all the new files
Deploy.proj, imported by <Import Project="Deploy.csproj" /> at the last line of the webproject project file:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
ExcludeAllGfx;
Client1Backup;
Client1Include;
Client1Migrate;
CollectBinFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="ExcludeAllGfx" BeforeTargets="ExcludeFilesFromPackage">
<ItemGroup>
<ExcludeFromPackageFiles Include="gfx\client1\**\*.*">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFiles>
<ExcludeFromPackageFiles Include="gfx\client2\**\*.*">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFiles>
<ExcludeFromPackageFiles Include="gfx\client3\**\*.*">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFiles>
</ItemGroup>
<Message Text="ExcludeFromPackageFiles: #(ExcludeFromPackageFiles)" Importance="high" />
</Target>
<Target Name="CollectBinFiles">
<ItemGroup>
<_CustomFiles Include="..\IncludeBin\Telerik\Telerik.ReportViewer.WebForms.dll" />
<_CustomFiles Include="..\IncludeBin\Telerik\Telerik.Reporting.dll" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Bin\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Target Name="Client1Migrate" Condition="'$(Configuration)|$(Platform)' == 'Release Client1|AnyCPU'">
<Exec Command=""..\MigratorProject\Bats\Client1.bat"" ContinueOnError="false" />
</Target>
<Target Name="Client1Include" Condition="'$(Configuration)|$(Platform)' == 'Release Client1|AnyCPU'">
<ItemGroup>
<_CustomFilesClient1 Include="gfx\Client1\**\*.*" Exclude="gfx\Client1\**\.svn\**\*.*">
<FromTarget>Project</FromTarget>
</_CustomFilesClient1>
<FilesForPackagingFromProject Include="%(_CustomFilesClient1.Identity)">
<DestinationRelativePath>gfx\client1\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Target Name="Client1Backup" Condition="'$(Configuration)|$(Platform)' == 'Release Client1|AnyCPU'">
<Exec Command=""C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:contentPath="page of client1",computerName=http://10.8.1.1/MsDeployAgentService2,encryptPassword=pass -dest:package=c:\Backups\deployments\client1.zip,computerName=http://10.8.1.1/MsDeployAgentService2,encryptPassword=pass" ContinueOnError="false" />
<Exec Command=""C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:runCommand='C:\Backups\deployments\scripts\backup.cmd client1',waitInterval=20000 -dest:auto,computerName=http://10.8.1.1/MsDeployAgentService2,encryptPassword=pass" ContinueOnError="false" />
</Target>
</Project>
Backup.cmd:
#echo off
sqlcmd -v name=%1 -S . -i "C:\Backups\deployments\scripts\backupdb.sql"
C:\Backups\deployments\scripts\stampme "C:\Backups\deployments\%1.zip"
backupdb.sql:
DECLARE #name NVARCHAR(50) -- database name
DECLARE #path NVARCHAR(256) -- path for backup files
DECLARE #fileName NVARCHAR(256) -- filename for backup
DECLARE #fileDate NVARCHAR(20) -- used for file name
SET #name = '$(name)'
SET #path = 'C:\Backups\deployments\'
SELECT #fileDate = REPLACE(REPLACE(CONVERT(VARCHAR(50),GETDATE(),120),':','-'), ' ', '#')
SET #fileName = #path + #name + '_' + #fileDate + '.BAK'
BACKUP DATABASE #name TO DISK = #fileName;
stampme.bat: http://ss64.com/nt/syntax-stampme.html
Hope anyone gets some help and examples from this entry.
You can extend Sayed's examples using the Condition attribute on your ItemGroup, and the $(Configuration) property.
e.g.:
<ItemGroup>
<Content Include="a.jpeg" Condition=" '$(Configuration)' == 'Client1' " />
</ItemGroup>

Automatic tracking of build number in VS 2005?

In Visual Studio 2005, is there an easy way to automatically increment the assembly/file build numbers after a successful build?
Emphasis on easy. I would like to track my build version, without having to set up CruiseControl or some similar tool.
You can use this project and include it your .proj file
This url might be of use Updating Porj build number
This didn't fit my needs and I took to adding this as a build.proj which works a treat
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> <PropertyGroup>
<Major>1</Major>
<Minor>0</Minor>
<Build>0</Build>
<Revision>0</Revision> </PropertyGroup> <PropertyGroup>
<BuildDir>C:\svn\Infrastructure</BuildDir> </PropertyGroup>
<ItemGroup>
<SolutionsToBuild Include="Infrastructure.sln"/> </ItemGroup>
<Target Name="Build" DependsOnTargets="ChangeDataAccessAssemblyInfo">
<RemoveDir Directories="$(BuildDir)\Builds" Condition="Exists('$(BuildDir)\Builds')" />
<MSBuild Projects="#(SolutionsToBuild)" Properties="Configuration=Debug" Targets="Rebuild" /> </Target>
<ItemGroup>
<TestAssemblies Include="Build\Logging\Logging.UnitTests.dll" /> </ItemGroup>
<Target Name="ChangeDataAccessAssemblyInfo" >
<Message Text="Writing ChangeDataAccessAssemblyInfo file for 1"/>
<Message Text="Will update $(BuildDir)\DataAccess\My Project\AssemblyInfo.vb" />
<AssemblyInfo CodeLanguage="VB"
OutputFile="$(BuildDir)\DataAccess\My Project\AssemblyInfo_new.vb"
AssemblyTitle="Data Access Layer"
AssemblyDescription="Message1"
AssemblyCompany="http://somewebiste"
AssemblyProduct="the project"
AssemblyCopyright="Copyright notice"
ComVisible="true"
CLSCompliant="true"
Guid="hjhjhkoi-9898989"
AssemblyVersion="$(Major).$(Minor).1.1"
AssemblyFileVersion="$(Major).$(Minor).5.7"
Condition="$(Revision) != '0' "
ContinueOnError="false" />
<Message Text="Updated Assembly File Info"
ContinueOnError="false"/> </Target> </Project>
The Publish options might be what you want... (def. available for C#, not sure abuut C++).
In studio, right click on the project file, and go to Properties, then select the "Publish" tab. There is an option there for auto-incrementing revision number.
What about writing a little macro, which increments the version?
Or what about this VS AddIn ?

Resources