Excluding Sitecore Assemblies from Deployment using Publish Settings

During another recent conversation on Sitecore Slack chat we discussing solutions with a large number of projects, and the fact that it is recommended to set CopyLocal=false for references (see here and here) since it optimizes Visual Studio builds and can reduce build times. The problem however is that setting this value causes you to lose Intellisense from your Razor Views/Webform controls, although everything should continue to build and work as expected though.

intellisense-vs-razor

That’s a fairly big price to pay! Another advantage of setting CopyLocal=false is that those DLLs are not included in the output directory of your build. More than likely you have a process to deploy a vanilla instance of Sitecore to the server or it is installed on the server, so there is no need to re-deploy the basic DLLs like Sitecore.Kernel.dll or Sitecore.Mvc.dll for example. More recently, we had an issue where the local version of our Coveo install was a slightly different version to the ones on the server, which meant that these assemblies should not be deployed either.

Team Development For Sitecore

If you are using Team Development for Sitecore (TDS) then it is possible to exclude these assemblies through the general project settings but in our case we do not use TDS for deploying code, only for packaging up our Sitecore items.

Exclude From Publish using Project settings

A suggestion by Steve McGill was to exclude the files from publish instead an leave CopyLocal=true

A quick Google revealed the following suggestion.

To apply this, unload your project, edit the .csproj and add the following:

<PropertyGroup>
  …
  <ExcludeFilesFromDeployment>bin\Sitecore.*.dll;bin\Coveo.*.dll;bin\Newtonsoft.*.dll</ExcludeFilesFromDeployment>
  <ExcludeFoldersFromDeployment>sourcefiles;raw-images;</ExcludeFoldersFromDeployment>
</PropertyGroup>

If you set it for the PropertyGroup node with no Condition attribute set then it seems to take effect with all Publish profiles.

Exclude From Publish using Publish Profile settings

The alternate seems to be setting it on the profile.pubxml file, but there is one of those per publish profile and I was under the impression that meant the need to edit/update multiple files with those setting.

Instead, Steve suggested using a reference file in the Publish Profiles and updating those, kind of like a global settings.

Create a new xml file and add it to your solution:

publishsettings.targets

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <publishUrl>http://hostname</publishUrl>
    <LaunchSiteAfterPublish>False</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <DeleteExistingFiles>False</DeleteExistingFiles>
    <ExcludeFilesFromDeployment>bin\Sitecore.*.dll;bin\Coveo.*.dll;bin\Newtonsoft.*.dll</ExcludeFilesFromDeployment>
    <ExcludeFoldersFromDeployment>sourcefiles;raw-images;</ExcludeFoldersFromDeployment>
    <!--<IncludeSetACLProviderOnDestination>False</IncludeSetACLProviderOnDestination>-->
  </PropertyGroup>
</Project>

And then in each publish profile add a reference to the above file like so:

.pubxml

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\..\..\..\publishsettings.targets" />
  <PropertyGroup>
  </PropertyGroup>
</Project>

You have to add this reference to every publish profile you have, but logically this is in the correct file since the file exclusion is directly related to publishing and not the project itself. You can then override the settings in each publish target, so this helps keep things consistent across all profiles.

It’s possible to use Wildcards to mass exclude certain files, e.g. Sitecore.*.dll. A word of warning if you do set this though: If you have used any Sitecore SharedSource modules or Support files, and the assemblies are named Sitecore.SharedSource.*.dll or Sitecore.Support.*.dll, then the above will mean they will be excluded. That might be a problem if it needs to be deployed via publish, i.e. it is not a module installed through the package installer but instead added as a project to your solution.


EDIT:

The better alternative is to use a MyProject.wpp.targets file located next to the csproj which is automatically applied to all publish targets. See the comment from Ben Golden below.


Include Files on Publish

This seems a little counter productive, excluding files then including things back in. But this gets around the problem above and allows us to add back in Support and SharedSource modules, and also allows us to push out any files which are not included in our project, such as generated CSS or Javascript files.

.wpp.targets

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

  <PropertyGroup>
    <ExcludeFilesFromDeployment>bin\Sitecore.*.dll</ExcludeFilesFromDeployment>
  </PropertyGroup>

  <!-- Copy Sitecore Support and Shared Source module files to output directory -->
  <Target Name="CustomCollectFiles">
    <Message Text="Collecting custom files..."/>
    <ItemGroup>
      <CustomFiles Include="bin\Sitecore.Support.*" />
      <CustomFiles Include="bin\Sitecore.SharedSource.*" />
      <CustomFiles Include="bin\Sitecore.Ship.*" />
      <CustomFiles Include="bin\Sitecore.SmartCommands.*" />
      <FilesForPackagingFromProject Include="%(CustomFiles.Identity)">
        <DestinationRelativePath>%(CustomFiles.Identity)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
    <Message Text="Add custom file to package %(FilesForPackagingFromProject.Identity)"/>
  </Target>

  <!-- Copy assets from Submodule projects -->
  <Target Name="CustomCollectSubmoduleFiles">
    <Message Text="Collecting custom submodule files..."/>
    <ItemGroup>
      <!-- custom project files -->
      <CustomFiles Include="shared\project\css\*" />
      <CustomFiles Include="shared\project\img\**\*" />
      <CustomFiles Include="shared\project\js\*" />

      <FilesForPackagingFromProject Include="%(CustomFiles.Identity)">
        <DestinationRelativePath>%(CustomFiles.Identity)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
    <Message Text="Add custom submodule file to package %(FilesForPackagingFromProject.Identity)"/>
  </Target>

  <PropertyGroup>
    <CopyAllFilesToSingleFolderForMsdeployDependsOn>
      CustomCollectFiles;
      CustomCollectSubmoduleFiles;
      $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
    </CopyAllFilesToSingleFolderForMsdeployDependsOn>
  </PropertyGroup>

</Project>

The above example will exclude all Sitecore DLLs from deployment, but crucially include the Support, SharedSource and others that we have specifically included. We have also specified as secondary group of generated files to include (separated for cleanliness). Note the CopyAllFilesToSingleFolderForMsdeployDependsOn calls (several) targets, which matches the Name attribute of the Target node that specifies the files to include.

If you are using OctoPack to create Nuget packages for deployment, then you need to create a Nuspec file to include the additional files into the package. The list of files to include will essentially be a copy from above so be sure to keep them in sync. Be sure to read the documentation and include the /p:OctoPackEnforceAddingFiles=true build parameter “which will instruct OctoPack to package a combination of files using its conventions, and those defined by your section”.

Links

4 comments

  1. Ben Golden · January 21, 2016

    Nice post! You can also add those properties to a myproject.wpp.targets file and it will be automatically included.

  2. Pingback: DLL Smell – How To Break Sitecore
  3. Pingback: Stop web.config on publish – How To Break Sitecore

Leave a comment