logo

Premium Support
24/7/365

Premium support customers may submit help-desk tickets using the form below.
Alternatively, the help-desk system can be accessed directly at support.maxiomtech.com. support@maxiomtech.com
info@maxiomtech.com
+1 (703) 942-9420
 

MSBuild Script for Automated DotNetNuke Module Packages

MSBuild Script for Automated DotNetNuke Module Packages

MSBuild Script for Automated DotNetNuke Module Packages

An automated packager will save you an enormous amount of time when you’re ready to release an initial or new release of your module. The following guide on how to MSBuild script will show you how I do it and feel free to add in any customization you would like.

The tasks I like to have in my build automation are:

  • Generic. No hard coded locations or names.
  • Release Mode only packing
  • Version Tracking – Assembly and DNN manifest
  • Inclusion of DLLs contained in DNN manifest
  • Compression
  • Resources zip
  • Install Package & Source Package

In order to complete these tasks I use MS Build with Community Tasks extension pack. I use a variation of Chris Hammond’s build script from the Module Development Template with some additional features.  Feel free to extend this script to suit your individual needs.

How To Install Build Scripts

Create a BuildScripts folder in your project and add in the ModulePackage.targets file along with the MSBuild.Community.Tasks.targets

Now modify your projects .csproj if you’re using C# and add the following line to the end of your project file (inside of </project>)

<Import Project=”BuildScriptsModulePackage.Targets” />

<Target Name=”AfterBuild” DependsOnTargets=”PackageModule” />

View the ModulePackage.targets file configuration

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
<?xml version="1.0" encoding="windows-1252"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Variable used to fine DNN Manifest File -->
<DNNFileName>$(AssemblyName)</DNNFileName>
<!--Variable used to create the install and source zip file-->
<PackageName>$(AssemblyName)</PackageName>
<!-- Variable used to find the location of the DotNetNuke installation bin folder. Used to get the projects binary DLL.
Assumes your your project will be stored in a company/module folder.
Ex: DesktopModules/CompanyName/ModuleName/-->
<MSBuildDnnBinPath Condition="'$(MSBuildDnnBinPath)' == ''">$(MSBuildProjectDirectory)......bin</MSBuildDnnBinPath>
</PropertyGroup>
 
<!-- Imports the community tasks for later use.
Used for: versioning, xml reading and writing. Compression. -->
<Import Project="MSBuild.Community.Tasks.Targets" />
 
<!-- Begins the main packaging of the project. This is called from the csproj -->
<Target Name="PackageModule" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 
<!--
Versioning of the module. Uses the version.txt file to store it's value. Every day from the StartDate that you build
the package in release mode it will add a new build version number. This allows you to create several builds in the same
day as the same version.
-->
<Version BuildType="Automatic" RevisionType="None" VersionFile="version.txt" StartDate="12/6/2012">
<Output TaskParameter="Major" PropertyName="Major" />
<Output TaskParameter="Minor" PropertyName="Minor" />
<Output TaskParameter="Build" PropertyName="Build" />
<Output TaskParameter="Revision" PropertyName="Revision" />
</Version>
<!--
Write new version to assemblyinfo.cs. This will make sure that the DLL file is the same version as the manifest.
Keeping everything in sync
-->
<FileUpdate Files="PropertiesAssemblyInfo.cs" Encoding="ASCII" Regex="AssemblyVersion(&quot;.+&quot;)" ReplacementText="AssemblyVersion(&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" />
<FileUpdate Files="PropertiesAssemblyInfo.cs" Encoding="ASCII" Regex="AssemblyFileVersion(&quot;.+&quot;)" ReplacementText="AssemblyFileVersion(&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" />
 
<!--Adds the verion to the DNN manifest -->
<XmlUpdate Prefix="n"
Namespace="http://schemas.microsoft.com/developer/msbuild/2003"
XPath="dotnetnuke/packages/package[1]/@version"
XmlFileName="$(DNNFileName).dnn" Value="$(Major).$(Minor).$(Build).$(Revision)" />
 
<!-- Pulls the version back out from the DNN Manifest and stores it in a variable to be used later to attach to the package zips -->
<XmlRead Prefix="n"
Namespace="http://schemas.microsoft.com/developer/msbuild/2003"
XPath="dotnetnuke/packages/package[1]/@version"
XmlFileName="$(DNNFileName).dnn">
<Output TaskParameter="Value" PropertyName="Version" />
</XmlRead>
 
<!-- Search DNN Manifest for other Assemblies that need to be added to the package -->
<XmlRead Prefix="n"
Namespace="http://schemas.microsoft.com/developer/msbuild/2003"
XPath="dotnetnuke/packages/package/components/component/assemblies/assembly/name"
XmlFileName="$(DNNFileName).dnn">
<Output TaskParameter="Value" PropertyName="DLLS" />
</XmlRead>
 
<!--Assemblies above come out as a string. The need to be split in order loop through each DLL to add it to the zip. -->
<ItemGroup>
<SplitDLLs Include="$(DLLS.Split(';'))" />
</ItemGroup>
 
 
<!-- Files that will be added to the root of the package zips. These files are linked to in the DNN Manifest in order
to show during the Module installation. .HTM files are used to get the most features in the installation. -->
<ItemGroup>
<RootFiles Include="**DocumentationLicense.htm" />
<RootFiles Include="**DocumentationReleaseNotes.htm" />
<RootFiles Include="***.sqldataprovider" />
<RootFiles Include="$(DNNFileName).dnn" />
</ItemGroup>
 
<!-- Files and folders that will be excluded from both packages. -->
<ItemGroup>
<DefaultExclude Include="**.svn**" />
<DefaultExclude Include="**bin**" />
<DefaultExclude Include="**obj**" />
<DefaultExclude Include="**Release**" />
<DefaultExclude Include="**Debug**" />
<DefaultExclude Include="**Test**" />
<DefaultExclude Include="**TestResults**" />
<DefaultExclude Include="**doc**" />
<DefaultExclude Include="**www**" />
<DefaultExclude Include="***.user" />
<DefaultExclude Include="***.suo" />
<DefaultExclude Include="***.zip" />
<DefaultExclude Include="***ReSharper.***" />
<DefaultExclude Include="**Tests***" />
<DefaultExclude Include="***.dnn" />
</ItemGroup>
 
<!-- Files that will be added to the install package. Note the default exclude collection on each item.
NOTE: If any file is missing from the install package simply add the extension here -->
<ItemGroup>
<InstallInclude Include="***.ascx" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.asmx" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.css" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.html" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.htm" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.resx" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.aspx" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.js" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.xsl" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.xslt" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.xml" Exclude="@(DefaultExclude)" />
<InstallInclude Include="**images*.*" Exclude="@(DefaultExclude)" />
<InstallInclude Include="***.txt" Exclude="@(DefaultExclude);**version.txt;" />
</ItemGroup>
 
<!-- FIles that will be added to the source package. Essentially everything but primary exclusion list. -->
<ItemGroup>
<SourceInclude Include="***.*" Exclude="@(DefaultExclude)" />
</ItemGroup>
<!-- Copy the files to be used for the INSTALL RESOURCES.ZIP file into a temp folder -->
<Copy SourceFiles="@(InstallInclude)" DestinationFolder="$(MSBuildProjectDirectory)ResourcesZip%(RecursiveDir)" />
 
<!-- Creates a variable of all the files found in the Resources.zip temp folder. -->
<CreateItem Include="$(MSBuildProjectDirectory)ResourcesZip***.*">
<Output TaskParameter="Include" ItemName="ResourcesContent" />
</CreateItem>
 
<!-- Creates the Resources.zip file -->
<Zip Files="@(ResourcesContent)" WorkingDirectory="$(MSBuildProjectDirectory)ResourcesZip" ZipFileName="Resources.zip" />
 
<!-- Moves that Resources.zip to a package folder. -->
<Copy SourceFiles="$(MSBuildProjectDirectory)Resources.zip" DestinationFolder="package/" />
 
<!-- Copies the DLLS needed for the package into the root directory. -->
<Copy SourceFiles="$(MSBuildDnnBinPath)%(SplitDLLs.Filename)%(SplitDLLs.Extension)" DestinationFolder="$(MSBuildProjectDirectory)Packagebin"/>
<!-- Copies the files that will be shown in the root of the zip package -->
<Copy SourceFiles="@(RootFiles)" DestinationFolder="$(MSBuildProjectDirectory)Package" />
 
<!--Creates a variable of all the files in the package folder. This will be used to create the install package.-->
<CreateItem Include="$(MSBuildProjectDirectory)Package***.*">
<Output TaskParameter="Include" ItemName="OutputContent" />
</CreateItem>
<!-- Zipps all the files in the package folder and saves it as the INSTALL package. Appends the version number to the end of the file name.-->
<Zip Files="@(OutputContent)" WorkingDirectory="$(MSBuildProjectDirectory)Package" ZipFileName="$(PackageName)_$(Version)_Install.zip" />
<!--Moves the INSTALL package zip to the packages folder. Install package is now complete. -->
<Copy SourceFiles="$(MSBuildProjectDirectory)$(PackageName)_$(Version)_Install.zip" DestinationFolder="packages/" />
 
<!-- Clean up Files. Remove the ResourcesZip and Package folder. Folders will be reused again for source package. -->
<RemoveDir Directories ="$(MSBuildProjectDirectory)Package" />
<RemoveDir Directories ="$(MSBuildProjectDirectory)ResourcesZip" />
 
 
<!-- create the SOURCE RESOURCES.ZIP file -->
<Copy SourceFiles="@(SourceInclude)" DestinationFolder="$(MSBuildProjectDirectory)ResourcesZip%(RecursiveDir)" />
<CreateItem Include="$(MSBuildProjectDirectory)ResourcesZip***.*">
<Output TaskParameter="Include" ItemName="SourceContent" />
</CreateItem>
<Zip Files="@(SourceContent)" WorkingDirectory="$(MSBuildProjectDirectory)ResourcesZip" ZipFileName="Resources.zip" />
<Copy SourceFiles="$(MSBuildProjectDirectory)Resources.zip" DestinationFolder="package/" />
 
<!-- Create the Source package -->
<Copy SourceFiles="$(MSBuildDnnBinPath)%(SplitDLLs.Filename)%(SplitDLLs.Extension)" DestinationFolder="$(MSBuildProjectDirectory)Packagebin"/>
<Copy SourceFiles="@(RootFiles)" DestinationFolder="$(MSBuildProjectDirectory)Package" />
 
<CreateItem Include="$(MSBuildProjectDirectory)Package***.*">
<Output TaskParameter="Include" ItemName="OutputSource" />
</CreateItem>
 
<Zip Files="@(OutputSource)" WorkingDirectory="$(MSBuildProjectDirectory)Package" ZipFileName="$(PackageName)_$(Version)_Source.zip" />
<Copy SourceFiles="$(MSBuildProjectDirectory)$(PackageName)_$(Version)_Source.zip" DestinationFolder="packages/" />
 
<!-- Clean up Files -->
<RemoveDir Directories ="$(MSBuildProjectDirectory)Package" />
<RemoveDir Directories ="$(MSBuildProjectDirectory)ResourcesZip" />
 
<!-- General Clean Up-->
<Delete Files="$(MSBuildProjectDirectory)$(PackageName)_$(Version)_Install.zip" />
<Delete Files="$(MSBuildProjectDirectory)$(PackageName)_$(Version)_Source.zip" />
<Delete Files="$(MSBuildProjectDirectory)Resources.Zip" />
</Target>
</Project>
view raw gistfile1.xml This Gist brought to you by GitHub.
Jonathan Sheely

Sr Software Engineer at InspectorIT. Jonathan is an out of the box thinker who has over 10 years experience building and supporting web application software and infrastructure. Jon specializes in ASP.NET C#, Javascript and CSS but is willing to learn anything that gets the job done.

No Comments

Sorry, the comment form is closed at this time.