<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tag 'msbuild'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=msbuild&amp;orTags=0</link><description>Search results matching tag 'msbuild'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Editing sqlcmdvariable nodes in SSDT Publish Profile files using msbuild</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2012/12/10/editing-sqlcmdvariable-nodes-in-ssdt-publish-profile-files-using-msbuild.aspx</link><pubDate>Mon, 10 Dec 2012 13:42:51 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:46580</guid><dc:creator>jamiet</dc:creator><description>&lt;p&gt;Publish profile files are a new feature of SSDT database projects that enable you to package up all environment-specific properties into a single file for use at publish time; I have written about them before at &lt;a href="http://sqlblog.com/blogs/jamie_thomson/archive/2012/05/08/publish-profile-files-in-sql-server-data-tools-ssdt.aspx" target="_blank"&gt;Publish Profile Files in SQL Server Data Tools (SSDT)&lt;/a&gt; and if it wasn’t obvious from that blog post, I’m a big fan!&lt;/p&gt;  &lt;p&gt;As I have used Publish Profile files more and more I have realised that there may be times when you need to edit those Publish profile files during your build process, you may think of such an operation as a kind of pre-processor step. In my case I have a sqlcmd variable called DeployTag, it holds a value representing the current build number that later gets inserted into a table using a Post-Deployment script (that’s a technique that I wrote about in &lt;a href="http://sqlblog.com/blogs/jamie_thomson/archive/2012/01/01/implementing-sql-server-solutions-using-visual-studio-2010-database-projects-a-compendium-of-project-experiences.aspx" target="_blank"&gt;Implementing SQL Server solutions using Visual Studio 2010 Database Projects – a compendium of project experiences&lt;/a&gt; – search for “Putting a build number into the DB”).&lt;/p&gt;  &lt;p&gt;Here are the contents of my Publish Profile file (simplified for demo purposes) :&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_79CBFB00.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_38BD7B9C.png" width="669" height="218" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Notice that DeployTag defaults to “UNKNOWN”.&lt;/p&gt;  &lt;p&gt;On my current project we are using msbuild scripts to control what gets built and what I want to do is take the build number from our build engine and edit the Publish profile files accordingly. Here is the pertinent portion of the the msbuild script I came up with to do that:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre style="text-align:left;list-style-type:disc;font-family:;background:white;color:;"&gt;&lt;font face="Consolas"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size:9.8pt;"&gt;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.8pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;ItemGroup&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Namespaces&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;Include&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;myns&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Prefix&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;myns&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Prefix&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Uri&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Uri&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Namespaces&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160; &amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;ItemGroup&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
 
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Target&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;Name&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;UpdateBuildNumber&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;ItemGroup&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;SSDTPublishFiles&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;Include&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;$(DESTINATION)\**\$(CONFIGURATION)\**\*.publish.xml&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt; /&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;ItemGroup&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;MSBuild.ExtensionPack.Xml.XmlFile&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;Condition&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;%(SSDTPublishFiles.Identity) != ''&lt;/font&gt;&lt;/span&gt;&amp;quot;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;TaskAction&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;UpdateElement&lt;/font&gt;&lt;/span&gt;&amp;quot;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;File&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;%(SSDTPublishFiles.Identity)&lt;/font&gt;&lt;/span&gt;&amp;quot;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;Namespaces&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;@(Namespaces)&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;XPath&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;//myns:SqlCmdVariable[@Include='DeployTag']/myns:Value&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#ff0000"&gt;InnerText&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;$(BuildNumber)&lt;/font&gt;&lt;/span&gt;&amp;quot;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;&amp;#160; &amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;Target&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font style="font-size:9.8pt;" color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The important bits here are the definition of the namespace &lt;a href="http://schemas.microsoft.com/developer/msbuild/2003"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_3B83308F.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_2F81405B.png" width="507" height="109" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and the XPath expression &lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;//myns:SqlCmdVariable[@Include='DeployTag']/myns:Value&lt;/font&gt;&lt;/span&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_076E913C.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_4D7F4E4F.png" width="691" height="104" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some extra info:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I use a fantastic tool called XMLPad to discover/test XPath expressions, read more at &lt;a href="http://sqlblog.com/blogs/jamie_thomson/archive/2011/02/11/xmlpad-a-new-tool-in-my-developer-utility-belt.aspx" target="_blank"&gt;XMLPad – a new tool in my developer utility belt&lt;/a&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/li&gt;

  &lt;li&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;MSBuild.ExtensionPack.Xml.XmlFile &lt;/font&gt;&lt;/span&gt;is a msbuild task used to edit XML files and is available from &lt;a href="https://twitter.com/MikeFourie" target="_blank"&gt;Mike Fourie&lt;/a&gt;’s &lt;a href="http://msbuildextensionpack.codeplex.com/" target="_blank"&gt;MSBuild Extension Pack&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;I’m using a property called &lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;$(BuildNumber)&lt;/font&gt;&lt;/span&gt; to hold the value to substitute into the file and also &lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;$(DESTINATION)\**\$(CONFIGURATION)\**\*.publish.xml&lt;/font&gt;&lt;/span&gt; to define an ItemGroup all of my Publish Profile files. Populating those properties is basic msbuild stuff and is therefore outside the scope of this blog post however if you want to learn more check out &lt;a href="http://msdn.microsoft.com/en-us/library/ms171458(v=vs.80).aspx" target="_blank"&gt;MSBuild properties&lt;/a&gt; &amp;amp; &lt;a href="http://msdn.microsoft.com/en-us/library/ms171454(v=vs.80).aspx" target="_blank"&gt;How To: Use Wildcards to Build All Files in a Directory&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope this is useful!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/jamiet" target="_blank"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SSIS MSBuild task now included in MSBuild Extension Pack</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2010/09/14/ssis-msbuild-task-now-included-in-msbuild-extension-pack.aspx</link><pubDate>Tue, 14 Sep 2010 21:11:55 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:28772</guid><dc:creator>jamiet</dc:creator><description>&lt;p&gt;The information in this blog post may be of interest to anyone out there that is using Continuous Integration with msbuild in order to build/deploy a project that includes SSIS packages.&lt;/p&gt;  &lt;p&gt;The MSBuild Extension Pack at &lt;a href="http://msbuildextensionpack.codeplex.com/"&gt;http://msbuildextensionpack.codeplex.com/&lt;/a&gt; now includes an MSBuild task that will build an SSIS project, the output from which is a .deploymentmanifest file that can be used in concert with the SSIS deployment utility.&lt;/p&gt;  &lt;p&gt;Building a SSIS project using the SSIS MSBuild Task essentially has the same effect as right-clicking on a SSIS project and selecting Build with CreateDeploymentUtility=True (i.e. produces a .deploymentmanifest file):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_7FED67F0.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="build ssis project" border="0" alt="build ssis project" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_48C3D9F7.png" width="304" height="367" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_7B473769.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="SSIS Deployemnt Utility" border="0" alt="SSIS Deployemnt Utility" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_03E78FF6.png" width="653" height="339" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The advantage of using the MSBuild task is of course that you can now do it in an MSBuild script, none of this manual mouse-clicking required thank you very much!&lt;/p&gt;  &lt;p&gt;The SSIS MSBuild task was previously available in the SSIS community samples project at &lt;a href="http://sqlsrvintegrationsrv.codeplex.com"&gt;http://sqlsrvintegrationsrv.codeplex.com&lt;/a&gt; but having it as part of the MSBuild Extension Pack is definitely advantageous as this is a very widely used set of utilities. The source code has been available in the MSBuild Extension pack since &lt;a href="http://msbuildextensionpack.codeplex.com/SourceControl/changeset/changes/54481" target="_blank"&gt;changeset 54481&lt;/a&gt; which was checked-in on 26th August 2010 and was included in the &lt;a href="http://msbuildextensionpack.codeplex.com/releases/view/46020" target="_blank"&gt;August 2010 Release&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Note that in order to deploy your packages after using the SSIS MSBuild task you will need to call the SSIS deployment utility and pass in the outputted .deploymentmanifest file. Information on doing that is decidedly thin on the ground so I’ll try and elucidate. The SSIS Deployment Utility is an executable that gets installed with SQL Server Integration Services workstation tools and is called dtsinstall.exe. You can call it on the command-line and pass in the path to a .deploymentmanifest file but as far as I can determine there is no way to do an unattended install (i.e. there is no way to tell dtsinstall.exe where to install the packages to, it simply opens up a GUI and prompts you for this information). This is a horribly antiquated method of deployment and I’m hunting around to see if there’s anything I’ve missed here – if you know any better please let me know.&lt;/p&gt;  &lt;p&gt;Hope this helps!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Setting up database unit testing as part of a Continuous Integration build process [VS2010 DB Tools - Datadude]</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2010/08/20/setting-up-database-unit-testing-as-part-of-a-continuous-integration-build-process-vs2010-db-tools-datadude.aspx</link><pubDate>Fri, 20 Aug 2010 18:41:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:28103</guid><dc:creator>jamiet</dc:creator><description>&lt;P&gt;&lt;I&gt;&lt;FONT face=Consolas&gt;[This blog post assumes a familiarity with the terms Continuous Integration (CI), MSBuild &amp;amp; MSTest. If you don’t have a good appreciation of those terms then this blog post probably isn’t for you anyway so don’t worry about it!]&lt;/FONT&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Over the past few days I have been working to get database unit tests executing as part of our Continuous Integration (CI) build and in this blog post I’ll explain how I went about it because it is decidedly &lt;I&gt;not&lt;/I&gt; straightforward.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;We are using the &lt;STRONG&gt;DB Tools in Visual Studio 2010&lt;/STRONG&gt; (aka &lt;STRONG&gt;DBPro&lt;/STRONG&gt; or &lt;STRONG&gt;Datadude&lt;/STRONG&gt; - I will refer to it as Datadude from here on in) which includes unit testing functionality. The rest of this blog post also assumes a familiarity with database unit testing in Datadude although if you want to do some background reading an excellent place to start is Jamie Laflen’s whitepaper &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/magazine/cc164243.aspx"&gt;&lt;FONT face=Consolas&gt;Apply Test-Driven Development to your Database Projects&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Consolas&gt; on MSDN.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Consolas&gt;
&lt;HR&gt;
&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;We got to the point where we had a C# test project containing database unit tests that executed successfully inside Visual Studio. For demonstration purposes I have put together a solution that contains a simple database project and a test project containing a database unit test:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image001_png01CB4075_1B0AD4EE.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="Solution Explorer screenshot" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=433 alt="solution explorer" src="http://sqlblog.com/blogs/jamie_thomson/cid_image001_png01CB4075_thumb_7DC4E149.png" width=506 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;And just to prove that the test executes successfully in Visual Studio:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image002_png01CB4075_10D5E829.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="Visual Studio Test Results screenshot" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=249 alt="Visual Studio Test Results screenshot" src="http://sqlblog.com/blogs/jamie_thomson/cid_image002_png01CB4075_thumb_1DCFC83A.png" width=856 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;N.B. The code for the database object(s) and the unit test itself are not important, that is outside the scope of this blog post.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;At this point we have some tests that run in our development sandbox, the configuration for which is done using the Database Test Configuration dialog:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image003_png01CB4076_14938CF9.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="database test configuration choice" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=382 alt="database test configuration choice" src="http://sqlblog.com/blogs/jamie_thomson/cid_image003_png01CB4076_thumb_057CAE1F.png" width=786 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image004_png01CB4076_70AAB59E.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="database test configuration dialog" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=638 alt="database test configuration dialog" src="http://sqlblog.com/blogs/jamie_thomson/cid_image004_png01CB4076_thumb_4FB742F7.png" width=508 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Those config settings are stored in the app.config file which exists as part of our test project (screenshot of which is at the top of this blog post). If we take a look inside that file we can see the&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;ConnectionString&lt;/FONT&gt; &lt;FONT face=Consolas&gt;that we defined in the Database Test Configuration dialog:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image005_png01CB4076_5F76D7FB.png"&gt;&lt;IMG title="app config connectionString DatabaseUnitTesting" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=271 alt="app config connectionString DatabaseUnitTesting" src="http://sqlblog.com/blogs/jamie_thomson/cid_image005_png01CB4076_thumb_17491C1F.png" width=959 border=0&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Note the&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#c0504d&gt;DatabaseUnitTesting&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt; &lt;/FONT&gt;&lt;FONT face=Consolas&gt;element, we’re going to be coming back to that a little later!!&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Consolas&gt;
&lt;HR&gt;
&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Once we have the tests running in Visual Studio the next step is to get them running inside a CI build and for that we call out to MSTest.exe from inside an MSBuild script:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image006_png01CB407D_54F603DB.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="msbuild script mstest" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=155 alt="msbuild script mstest" src="http://sqlblog.com/blogs/jamie_thomson/cid_image006_png01CB407D_thumb_733FF92A.png" width=1069 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;When we execute that script we get some positive results and all looks peachy:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image007_png01CB407D_380C1D5F.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="msbuild mstest output" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=534 alt="msbuild mstest output" src="http://sqlblog.com/blogs/jamie_thomson/cid_image007_png01CB407D_thumb_4837E558.png" width=650 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;FONT face=Consolas&gt;
&lt;HR&gt;
&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;OK, we now have a test that runs successfully both in Visual Studio and by calling MSTest.exe directly from MSBuild. The problem I have to solve now though (and this is the real crux of this blog post) is that the test is still running against the server I specified in app.config; I don’t want this, I want the test to run against a server of my choosing, namely my build server. For this I had to call on the help of the aforementioned Jamie Laflen (who, luckily, I have met in the past) and he gave me guidance on how to achieve it. Below are the steps that you need to take.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Firstly you need to tell Datadude that you want to specify some different credentials and that is done by adding an attribute&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;&lt;FONT color=#ff0000&gt;AllowConfigurationOverride&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;=&lt;/FONT&gt;"&lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;"&lt;/FONT&gt;&lt;FONT face=Consolas&gt; to the&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#c0504d&gt;DatabaseUnitTesting&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt; &lt;/FONT&gt;&lt;FONT face=Consolas&gt;element of app.config like so:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image008_png01CB407E_32F9B9E3.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="app config DatabaseUnitTesting AllowConfigurationOverride" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=345 alt="app config DatabaseUnitTesting AllowConfigurationOverride" src="http://sqlblog.com/blogs/jamie_thomson/cid_image008_png01CB407E_thumb_23E2DB09.png" width=643 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;I&gt;&lt;FONT face=Consolas&gt;Don’t forget to build your test project after changing the app.config file!!!&lt;/FONT&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;This will cause datadude unit testing framework to go and search for a file called&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;*.dbunittest.config&lt;/FONT&gt; &lt;FONT face=Consolas&gt;where the * indicates either:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Consolas&gt;The name of machine upon which the tests are being run or&lt;/FONT&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Consolas&gt;The name of the user running the tests&lt;/FONT&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;According to Jamie L datadude runs the following precedence checks:&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;FONT face=Consolas&gt;Is an override specified in app.config? If not, use app.config&lt;/FONT&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Consolas&gt;Does an override file exist called &amp;lt;machinename&amp;gt;.dbunittest.config? If so, use it, if not…&lt;/FONT&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Consolas&gt;Does an override file exist called &amp;lt;username&amp;gt;.dbunittest.config? If so, use it, if not…&lt;/FONT&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Consolas&gt;Fail!&lt;/FONT&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;“So”, you may be asking, “what goes in this &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;*.dbunittest.config&lt;/FONT&gt; file then?”. &lt;FONT face=Consolas&gt;Fair question, that’s where the&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#c0504d&gt;DatabaseUnitTesting&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt; &lt;/FONT&gt;&lt;FONT face=Consolas&gt;element that I mentioned earlier comes in. Copy that element from the app.config file into your &lt;FONT face="Courier New"&gt;*.dbunittest.config&lt;/FONT&gt; file, remove the&lt;/FONT&gt;&amp;nbsp;&lt;FONT face="Courier New"&gt;&lt;FONT color=#ff0000&gt;AllowConfigurationOverride&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;=&lt;/FONT&gt;"&lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;"&lt;/FONT&gt;&lt;FONT face=Consolas&gt; attribute and change the&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;ConnectionString&lt;/FONT&gt; &lt;FONT face=Consolas&gt;property accordingly:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image009_png01CB4081_20ED7656.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="dbunittest.config ConnectionString" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=236 alt="dbunittest.config ConnectionString" src="http://sqlblog.com/blogs/jamie_thomson/cid_image009_png01CB4081_thumb_7464466F.png" width=847 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;The next step is to tell MSTest.exe that there is another file that it needs to be aware of when it runs the tests and to do that we need to create a custom testsettings file that will be used instead of the default Local.testsettings. To create a new testsettings file use the Add New Item dialog:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image010_png01CB4083_7D049EFB.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="add new test settings" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=466 alt="add new test settings" src="http://sqlblog.com/blogs/jamie_thomson/cid_image010_png01CB4083_thumb_1BDB12DA.png" width=825 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;In the Test Settings dialog go to ‘Deployment’, click ‘Enable deployment’, then ‘Add File…’. Browse to your&lt;/FONT&gt;&lt;FONT face="Courier New"&gt; *.dbunittest.config &lt;/FONT&gt;&lt;FONT face=Consolas&gt;file and add it to the project:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image011_png01CB4083_39D920CE.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="test settings dialog" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=655 alt="test settings dialog" src="http://sqlblog.com/blogs/jamie_thomson/cid_image011_png01CB4083_thumb_3FB3C467.png" width=892 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;At this point you’re good to go and all you need to do edit your call to MSTest.exe and tell it to use your new testsettings file:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image012_png01CB4084_5CD96C71.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="msbuild script mstest testsettings" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=163 alt="msbuild script mstest testsettings" src="http://sqlblog.com/blogs/jamie_thomson/cid_image012_png01CB4084_thumb_70865605.png" width=1011 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Notice the extra information in the output:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image013_png01CB4084_2F0BA3AC.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="msbuild script output" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=577 alt="msbuild script output" src="http://sqlblog.com/blogs/jamie_thomson/cid_image013_png01CB4084_thumb_4DE2178A.png" width=702 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;You’ll have to trust me that it used the new config file and therefore the new &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;ConnectionString&lt;/FONT&gt;&lt;FONT face=Consolas&gt;, although having said that you do get some useful information in the test results file (*.trx) that MSTest.exe creates:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/jamie_thomson/cid_image014_png01CB4085_248ACF8C.png"&gt;&lt;FONT face=Consolas&gt;&lt;IMG title="mstest test results trx output" style="BORDER-TOP-WIDTH:0px;PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;BORDER-LEFT-WIDTH:0px;BACKGROUND-IMAGE:none;BORDER-BOTTOM-WIDTH:0px;PADDING-TOP:0px;BORDER-RIGHT-WIDTH:0px;" height=255 alt="mstest test results trx output" src="http://sqlblog.com/blogs/jamie_thomson/cid_image014_png01CB4085_thumb_2A657325.png" width=991 border=0&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;FONT face=Consolas&gt;
&lt;HR&gt;
&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;I think its fair to say that this process is a little fiddly to say the least so I’m hoping that Microsoft come up with a better solution in the future, one that integrates better into the whole testing infrastructure. Meanwhile you can download the demo that I put together for this blog post from my &lt;/FONT&gt;&lt;A href="http://bit.ly/cYYIdq" target=_blank&gt;&lt;FONT face=Consolas&gt;SkyDrive&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Consolas&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;Hope that helps! Comments are welcome.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://twitter.com/jamiet" target=_blank&gt;&lt;FONT face=Consolas&gt;Jamiet&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;SPAN class=Apple-style-span style="WORD-SPACING:0px;FONT:medium 'Times New Roman';TEXT-TRANSFORM:none;TEXT-INDENT:0px;WHITE-SPACE:normal;LETTER-SPACING:normal;BORDER-COLLAPSE:separate;orphans:2;widows:2;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;"&gt;&lt;SPAN class=Apple-style-span style="FONT-SIZE:13px;FONT-FAMILY:Arial, Helvetica, sans-serif;"&gt;
&lt;P&gt;UPDATE: Atul Verma has written a 3-part blog series on how to write your database unit tests so if Jamie Laflen's whitepaper (linked to above) doesn't tickle your fancy try reading Atul's series instead:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="" href="http://blogs.msdn.com/b/atverma/archive/2010/07/28/how-to-unit-test-sql-server-2008-database-using-visual-studio-2010.aspx"&gt;How to unit test SQL Server 2008 database using Visual Studio 2010&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="" href="http://blogs.msdn.com/b/atverma/archive/2010/08/22/how-to-unit-test-sql-server-2008-database-using-visual-studio-2010-part-2.aspx"&gt;How to unit test SQL Server 2008 database using Visual Studio 2010 – Part 2&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="" href="http://blogs.msdn.com/b/atverma/archive/2010/08/22/how-to-unit-test-sql-server-2008-database-using-visual-studio-2010-part-3.aspx"&gt;How to unit test SQL Server 2008 database using Visual Studio 2010 – Part 3&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;</description></item><item><title>A strategy for managing security for different environments using the Database Development Tools in Visual Studio 2010</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2010/07/21/a-strategy-for-managing-security-for-different-environments-using-the-database-development-tools-in-visual-studio-2010.aspx</link><pubDate>Wed, 21 Jul 2010 20:59:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:27217</guid><dc:creator>jamiet</dc:creator><description>&lt;h3&gt;Intro&lt;/h3&gt;
&lt;p&gt;Of late I have been getting down and dirty with the Database Development tools in Visual Studio 2010. You may know this feature set by one of the plethora of other names it has had over recent years such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visual Studio Team System for Database Professionals &lt;/li&gt;
&lt;li&gt;DBPro &lt;/li&gt;
&lt;li&gt;Datadude &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;For the rest of this post I’ll stick with the colloquial name that most people seem to recognise – datadude.&lt;/p&gt;
&lt;p&gt;Regardless of which moniker you prefer I’m hoping you recognise the feature set that I am referring to here which includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Schema Compare &lt;/li&gt;
&lt;li&gt;Data Compare &lt;/li&gt;
&lt;li&gt;Offline database development &lt;/li&gt;
&lt;li&gt;T-SQL refactoring &lt;/li&gt;
&lt;li&gt;Database unit testing/Data generation &lt;/li&gt;
&lt;li&gt;MSBuild integration &lt;/li&gt;
&lt;li&gt;various other things… &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I plan to write a detailed blog post in the coming weeks talking about my overall experiences with datadude but in the meantime I’m writing this blog post to focus on how I have chosen to manage security; by which I mean:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;logins &lt;/li&gt;
&lt;li&gt;users &lt;/li&gt;
&lt;li&gt;role membership &lt;/li&gt;
&lt;li&gt;user and role permissions &lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;

&lt;h3&gt;Security in Post-Deployment scripts&lt;/h3&gt;
&lt;p&gt;Datadude has built-in support for managing all of this stuff as we can see from this screenshot:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_4F758EED.png"&gt;&lt;img style="border-width:0px;display:inline;" class="wlDisabledImage" title="users roles logins in datadude" border="0" alt="users roles logins in datadude" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_0D8EA99F.png" width="676" height="433"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice that we have created a &lt;strong&gt;user&lt;/strong&gt;, a &lt;strong&gt;login &lt;/strong&gt;for that user and a &lt;strong&gt;role &lt;/strong&gt;into which we later want to add the user. They exist as explicit objects within our project which means that datadude “knows” about them and that has a number of advantages including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Datadude can include these objects in a schema compare &lt;/li&gt;
&lt;li&gt;Datadude can do dependency tracking thus enabling offline development (e.g. If the login that is referenced in the CREATE USER statement does not exist then a design-time error will be raised) &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;That should be enough to justify using datadude to manage users and roles however I have come across a limitation that prohibits us from doing so; we do not deploy the same security model to each of our environments. The reasons for this are very familiar to you I’m sure, we have people that require different permissions on different environments (e.g. our developers will want to be able to issue DDL and UPDATE/INSERT/DELETE on our development environment but we definitely don’t want them to have the same on production).&lt;/p&gt;
&lt;p&gt;As far as I can discern datadude does not have a good solution for dealing with this situation. I have not found a way of conditionally deploying objects depending on which environment we are deploying to. Actually that is not altogether true, we could have a Visual Studio configuration for each environment and include/exclude objects as we choose but that doesn’t play well with the build and deploy model of msbuild which requires that you build each one of those configurations; each of our builds takes about 10 minutes which, when multiplied by the number of environments, results in a total build time that takes too long for our continuous integration (CI) usage.&lt;/p&gt;
&lt;p&gt;Hence we needed a better way to deploy our security model – we chose to use PostDeployment scripts. PostDeployment scripts do exactly what they say on the tin – they are scripts that get run after datadude has deployed the objects that it knows about. They get called (using SQLCMD syntax) from the &lt;font face="Courier New"&gt;Script.PostDeployment.sql &lt;/font&gt;file that exists in every datadude project:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/cid_image002_png01CB274D_4ACF5E66.png"&gt;&lt;img style="border-width:0px;display:inline;" class="wlDisabledImage" title="post deployment script solution explorer" border="0" alt="post deployment script solution explorer" src="http://sqlblog.com/blogs/jamie_thomson/cid_image002_png01CB274D_thumb_6A120539.png" width="303" height="221"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My chosen approach is to have a script called &lt;font face="Courier New"&gt;SecurityAdditionsWrapper.sql&lt;/font&gt; that gets called from &lt;font face="Courier New"&gt;Script.PostDeployment.sql&lt;/font&gt;. &lt;font face="Courier New"&gt;SecurityAdditionsWrapper.sql &lt;/font&gt;checks a SQLCMD variable to determine which environment is being deployed to and then calls the appropriate &lt;font face="Courier New"&gt;SecurityAdditionsXXX.sql &lt;/font&gt;script that is responsible for deploying the security model for that environment (where XXX is the environment).&lt;/p&gt;
&lt;p&gt;I then have 3 subfolders that contain all the individual CREATE USER, role membership and permissions scripts that get called from &lt;font face="Courier New"&gt;SecurityAdditionsXXX.sql&lt;/font&gt; as and when required.&lt;/p&gt;
&lt;p&gt;The screenshot below shows the contents of &lt;font face="Courier New"&gt;Script.PostDeployment.sql &lt;/font&gt;&amp;amp; &lt;font face="Courier New"&gt;SecurityAdditionsWrapper.sql&lt;/font&gt; and also the files as they exist in Solution Explorer:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/cid_image003_png01CB274F_7DBEEECD.png"&gt;&lt;img style="border-width:0px;display:inline;" class="wlDisabledImage" title="!cid_image003_png@01CB274F" border="0" alt="!cid_image003_png@01CB274F" src="http://sqlblog.com/blogs/jamie_thomson/cid_image003_png01CB274F_thumb_5969E47E.png" width="778" height="614"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some things to notice:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I have a SQLCMD variable called $(DeployType) that will contain the value “DEV”, “UAT” or “PRD” &lt;/li&gt;
&lt;li&gt;All of my security scripts exist in Post-Deployment&amp;nbsp; -&amp;gt; SecurityAdditions &lt;/li&gt;
&lt;li&gt;In the commented-out code you can see that I was trying to be clever and dynamically build the name of the file to be executed using the $(DeployType) variable – the thinking being that if we later added a new environment type I wouldn’t need to change this script. Unfortunately even though this is valid SQLCMD syntax it does not work in datadude; I have reported that issue on Connect as a bug (with repro) at &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/575383/datadude-valid-sqlcmd-syntax-throws-error-at-build-time"&gt;[Datadude] Valid SQLCMD syntax throws error at build time&lt;/a&gt;. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;You may be wondering how we get a value into that $(DeployType) variable when using msbuild. Well, its pretty simple when you know how. First you need to include the variable in the sqlcmdvars file for your datadude project:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/cid_image004_png01CB2755_5A129AA8.png"&gt;&lt;img style="border-width:0px;display:inline;" class="wlDisabledImage" title="!cid_image004_png@01CB2755" border="0" alt="!cid_image004_png@01CB2755" src="http://sqlblog.com/blogs/jamie_thomson/cid_image004_png01CB2755_thumb_0E46C3EF.png" width="430" height="272"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You then need to pass in the appropriate value to that variable at deploy-time. We are using &lt;a href="http://msdn.microsoft.com/en-us/library/dd193258.aspx"&gt;VSDBCMD.exe&lt;/a&gt; to run our deployments and the &lt;a href="http://msdn.microsoft.com/en-us/library/dd193283.aspx"&gt;syntax to pass in a value for a variable&lt;/a&gt; is /p:PropertyName=PropertyValue. We are calling VSDBCMD.exe from inside an msbuild script which therefore looks like this:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;Exec&lt;/font&gt; &lt;font color="#ff0000"&gt;Command&lt;/font&gt;&lt;font color="#9b00d3"&gt;="..\Tools\VSDBCMD\vsdbcmd.exe /Action:Deploy /ConnectionString:'Data Source=$(DatabaseServer);Integrated Security=True;Pooling=False' /DeployToDatabase:+ /ManifestFile:.\MyDB.deploymanifest &lt;strong&gt;/p:DeployType=&amp;amp;quot;$(DeployType)&amp;amp;quot&lt;/strong&gt;; "&lt;/font&gt; &lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;$(DeployType) is of course also a property within our msbuild file, which I am drawing attention to in the bold section above.&lt;/p&gt;
&lt;h3&gt;Wrap-Up&lt;/h3&gt;
&lt;p&gt;In conclusion, I am not saying that this is the &lt;i&gt;correct&lt;/i&gt; way to deploy a SQL Server security model using datadude, it just happens to be the method that I have chosen. I would really like to how people have solved this using datadude so if you have any anecdotes to share please put them in the comments.&lt;/p&gt;
&lt;hr&gt;

&lt;h3&gt;One more thing…&lt;/h3&gt;
&lt;p&gt;Cranking all of those files out by hand is a laborious undertaking, especially if you have lots of users with lots of permissions. In our case we introduced datadude to be used with an existing system hence we already had all our security setup on existing servers but we had no good way of getting it into the structure that I explained above. Powershell and SQLCMD to the rescue!&lt;/p&gt;
&lt;p&gt;I have produced a series of scripts that interrogate a named instance and produce all of the files that I explain above. Namely:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A file for each user which gets dropped into %SolutionRoot%\%ProjectName%\Scripts\Post-Deployment\Users\ &lt;/li&gt;
&lt;li&gt;A file for each principle that issues all the GRANT/DENY EXECUTE/SELECT/INSERT/UPDATE/DELETE for that principle, it gets dropped into %SolutionRoot%\%ProjectName%\Scripts\Post-Deployment\PermissionsSets\ &lt;/li&gt;
&lt;li&gt;A file that specifies all of the role memberships, for all database principles. &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Creating the CREATE USER file and the file containing the permissions for each principle is&amp;nbsp;quite involved. For that we need some nested loops that loop over (a) all the databases for which you want to scripts users and (b) all the principles in each database. It then dumps the appropriate files into the appropriate folders and then you have the simple task of adding them to your project and calling them from your Post Deployment script.&lt;/p&gt;
&lt;p&gt;The files are stored in a zip folder on my SkyDrive at &lt;a title="http://cid-550f681dad532637.office.live.com/self.aspx/Public/BlogShare/20100721/GeneratePermissions.zip" href="http://cid-550f681dad532637.office.live.com/self.aspx/Public/BlogShare/20100721/GeneratePermissions.zip"&gt;http://cid-550f681dad532637.office.live.com/self.aspx/Public/BlogShare/20100721/GeneratePermissions.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To run the Powershell script simply unzip all the files into the root folder of your solution and issue:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;gt;GeneratePermissions.ps1 -SQLInstance instanceName -Environment XXX&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;changing SQLInstance &amp;amp; XXX accordingly (the &lt;font face="Courier New"&gt;$Environment&lt;/font&gt; variable is simply a suffix that is added to the names of some of the generated files). The Powershell script contains more detailed notes within it in the comments section at the top.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_0A78F952.png"&gt;&lt;img style="border-width:0px;display:inline;" class="wlDisabledImage" title="powershell script comments" border="0" alt="powershell script comments" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_62664A32.png" width="739" height="273"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hope this helps!&lt;/p&gt;
&lt;p&gt;Disclaimer: I’m giving this away for free and I won’t be supporting it so use at your own peril (in other words, don’t come here complaining that it doesn’t work on your environment). On the other hand if you find a problem and are able to fix it – please let me know &lt;img class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://sqlblog.com/blogs/jamie_thomson/wlEmoticonsmile_19CC5B61.png"&gt;&lt;/p&gt;
&lt;p&gt;UPDATE: I did actually find some problems with the scripts and have now uploaded a new set. I'm confident that they'll work this time.&lt;/p&gt;
&lt;p&gt;UPDATE 2: I've updated the scripts again. They now create the SecurityAdditionsXXX.sql file as well as the individual CREATE USER &amp;amp; permissions files;&amp;nbsp;SecurityAdditionsXXX.sql contains all of the calls to the relevant scripts for environment XXX.&lt;/p&gt;
&lt;p&gt;SecurityAdditionsXXX.sql also issues all of the role membership statements as well. So just to clarify - you now no longer have a need to run the script that generates the role memberships - GeneratePermissions.ps1 takes care of everything.&lt;/p&gt;&lt;p&gt;UPDATE 3: Peter Schott has taken this, adapted it for hiw own needs, and sent it back to me so that I can share it here. His modified version of the scripts is at &lt;a href="http://cid-550f681dad532637.office.live.com/self.aspx/Public/BlogShare/20100721/GeneratePermissions%5E_PeterSchott.zip"&gt;http://cid-550f681dad532637.office.live.com/self.aspx/Public/BlogShare/20100721/GeneratePermissions%5E_PeterSchott.zip&lt;/a&gt;&amp;nbsp;and includes these changes (mainly to deal with roles):&lt;/p&gt;&lt;p&gt;1. Changed the Powershell script:&lt;br&gt;&amp;nbsp; * Added a section to handle role permissions. (really don't care for the way VS does it)&lt;br&gt;&amp;nbsp; * Tweaked the Database Principle section - for some reason, the variable in the PS script I extracted wasn't set properly so I just changed the names around&lt;br&gt;&amp;nbsp; * Added a bunch of lines of code to add to the Array. My Powershell's not too strong so wasn't sure about the best way to add new DBs/Projects to the DB Array. I ended up doing a bunch of sets. I know it's not ideal, but I just wanted to get it done one time.&lt;br&gt;&amp;nbsp; * Tweaked the section that creates the Users. If one of those logins doesn't exist, the grant permissions script would stop. Now I check to make sure that the login exists before the script runs.&amp;nbsp;I sometimes get empty (Login = [])&amp;nbsp; sections. No ideas on that yet. I fix or delete that file as appropriate.&lt;br&gt;&lt;br&gt;2. Added a "GetDatabaseRoleList.sql" file.&amp;nbsp; Gets the roles for the DB so we can run it through the Permissions file&lt;br&gt;&lt;br&gt;3. Permissions SQL file. I tweaked this with a query that UNIONs the object permissions with the Schema permissions. I didn't break it down further &lt;br&gt;like you did, but our permissions are so messed up right now that it doesn't matter much to me. (we have &lt;i&gt;far&lt;/i&gt; too many permissions granted to &lt;br&gt;individual users instead of roles because the prior DBA didn't understand the point of DB Roles for permissions and even then far too many permissions because we had a job that nightly granted all permissions on all objects to certain usernames :-P&amp;nbsp; )&lt;br&gt;&lt;/p&gt;&lt;p&gt;And one more change that needs to be made which Peter informed me of later: &lt;/p&gt;&lt;p&gt;Ended up changing the GeneratePermissions.ps1 file to change all of the Out-File &lt;br&gt;to "Out-File -width 500 ".&lt;br&gt;&lt;br&gt;After doing that, the permissions weren't truncated at 80 characters.&amp;nbsp; Also tweaked the Invoke-SQLCmd functions to use -MaxCharLength 500 so the output line would be long enough. That may have been overkill or there may be a better way to handle, but some of my permission lines were definitely longer than the allowed line lengths.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;P.S. I have used Powershell in the past but this is the first time I have really got into the inner workings of it and I’ve got to tell you – its just fantastic. The productivity you get is just incredible – if you don’t believe me have a look at the script herein and see how easy it is to generate a dataset from SQL Server and then loop over it inside your script. Its two lines of code - really fantastic stuff – I recommend any SQL Server pro go out and spend some time getting to know Powershell. </description></item></channel></rss>