Mixing web.config transforms and Parameters.xml, or something to that effect - webdeploy

I've been using web.config transforms for a while now, for deployment on a few of our projects. What I'm now trying to achieve, is to have Web Deploy's 'Import Package' screen to prompt to check & update several of the variables in , adjusted for each environment.
I know I can use Parameters.xml to introduce these editable variables, but I haven't yet found how to have the defaults updated for different environment targets.
Consider the following neat, but non-overlapping example of wanting to have the user edit the 'specialServer' AppSetting, and have it present a different default when compiled for the NewEnv target:
Sample entry in Parameters.xml:
<parameter name="Special server" description="" tags="" defaultValue="server1-dev.domain">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='specialServer']/#value" />
</parameter>
Sample transform for Web.NewEnv.config, setting a different value for
<appSettings>
<add key="specialServer"
value="other-server.domain2"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
Sample of the prompt in Web Deploy:
Any suggestions as to how to update the default value for different build targets?
Thanks.

You would have to generate and new parameters definition file and embed it in your WebDeploy package for each environment.
This would give you different deploy packages per environment and would allow you to specify different default values for those parameters. Obviously doing so undermines the point if parameter transforms and you essentially end up baking in your config, but it's the only way to achieve what you want.
I don't recommend the approach but it may fit your needs.

We use a batch script to call msdeploy. It allows for a parm to specify the Parameters.xml file. Then with multiple Parameters.xml files (one per environment), you can just call msdeploy like:
"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package='D:\mysite.zip' -dest:auto,computerName="testcomp1",includeAcls="False" -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"D:\mysite.test.SetParameters.xml"

Related

How to ignore the connection string parameter in SetParameter.xml

I am using msDeploy (3.0) to deploy my MVC applicaiton. I have a build pipeline that generates build artifacts for msdeploy and my deploy pipeline applies appropriate web.config transforms on the Web.config before deploying it to the production instances. One of the transforms includes changes to connection string. However, looking at the deployed instances, it seems like my web.config transforms are being overriden by the parameters in setParameters.xml in my build artifacts.
Ideal behavior would be that I would be to avoid adding any Connection string to the SetParameter.xml so that all my connection string overrides will be controlled by my deployment pipeline only. How do I achieve that?
Below is a sample of SetParameters.xml file
<parameters>
<setParameter name="IIS Web Application Name" value="Default/Foo"/>
<setParameter name="Foo-Web.config Connection String" value="Server=Foo,1433;Database=Bar;Integrated Security=SSPI;MultiSubnetFailover=True;App=Something;Connection Timeout=25"/>
</parameters>
Ideally it would look something like
<parameters>
<setParameter name="IIS Web Application Name" value="Default/Foo"/>
</parameters>
I have already tried passing a parameters.xml file to the msbuild step that does not contain the connectsion string parameter but that did not work
After bang my head against the wall for several hours, I finally figured out the solution. MsBuild takes in a parameter - p:AutoParameterizationWebConfigConnectionStrings=false that prevents the connection strings from being parameterized. Unfortunately, there is little or no documentation on this parameter.
You can also set this on a per project basis adding
<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
to the PropertyGroup of your build configuration.

Set Web Deploy parameter values in MSBuild

I use MSBuild to build and deploy a web application.
MSBuild.exe MySite.csproj /p:DeployOnBuild=True /p:WebPublishMethod=MSDeploy /p:MSDeployServiceURL=mysite.example.com
My site connects to a SQL Server database.
<connectionStrings>
<add name="dbconnection"
connectionString ="Data Source=(local);Initial Catalog=MySite;Integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
</connectionStrings>
I develop against a local database, but the connection string needs to be changed when the site is deployed to test or production servers.
I have declared a deployment parameter named dbconnection in a file named parameters.xml
<parameter name="dbconnection"
defaultValue="Data Source={server};Initial Catalog={database};Integrated Security=SSPI;"
tags="DBConnectionString">
<parameterEntry type="XmlFile"
scope="\\Web.config$"
match="/configuration/connectionStrings/add[#name='dbconnection']/#connectionString"/>
</parameter>
I could easily create a parameterized web deploy package and deploy it with msdeploy.
msdeploy -verb:sync
-source:package:MySite.zip
-dest:iisApp="Site1/MySite"
-setParam:name=dbconnection,value="Data Source=.\SQLEXPRESS;Initial Catalog=MySiteTest;Integrated Security=SSPI"
However, I'd really like to be able to do everything in MSBuild. What is the MSBuild equivalent of -setParam?
Parameterization is not used when debugging locally. So all you should have to do is set the defaultValue in your parameters.xml file to your desired connection string.
We create a SetParameters file for each environment (DEV, QA, MOCK, PROD) and call MSDeploy after MSBuild creates a WebDeploy package with the appropriate setParam file. I don't believe there is way to use a custom SetParameters file when deploying directly from MSBuild.
Here is a post that further describes parameterization:
http://dotnetcatch.com/2014/09/08/parameterizationpreview-visual-studio-extension/
UPDATE:
Steven and I worked further outside of SO to understand his use cases better. We confirmed again the MSDeployPublish target does not support setting parameter value overrides. To solve his use case I wrote some MSBuild script to provide the functionality he was looking for and wrote a blog post about it -
http://dotnetcatch.com/2016/04/27/setparameters-via-msbuild-commandline/
It basically works by passing a SetParameters file or list of key/value pairs via MSBuild Properties on the MSBuild.exe commandline. The MSBuild script parses that out and overrides the parameters by setting the MsDeployDeclareParameters ItemGroup.
msdeploy.exe ... /p:MSDeployPublishSetParametersFile=SetParameters.Test.xml
msdeploy.exe ... /p:MSDeployPublishSetParameters=testSetting='changed_fromSetParam';IIS Web Application Name='Default Web Site/app13'

How to configure Application Pool with MSDeploy

I'm currently using MSBuild to create an MSDeploy package by passing in arguments:
/p:DeployOnBuild=true;DeployTarget=Package
I'm using a parameters.xml file (placed at the root of my website). Another SO question I found tries to set up the application pool.
My parameters.xml file:
<parameters>
<parameter name="Application Pool Name" description="Application Pool for this site" tags="" defaultValue="ASP.NET v4.0">
<parameterEntry kind="DeploymentObjectAttribute"
scope="application"
match="/application/#applicationPool" />
</parameter>
...
</parameters>
but it seems that the archive.xml file inside the msdeploy package generated by the msbuild doesn't have an section with an applicationPool element
How can I get the archive.xml to be generated with this section so that I can set the application pool?
The app pool I want to set will exist already, so I'm not concerned with MSDeploy synching or creating app pools here.
Edit:
I have found this question How do I control the AppPool used for deploy through VS & MSDeploy settings which hints at using wpp.targets to generate a custom provider. I'm exploring how to use this approach to modify the archive.xml file
Assuming you have the correct IIS settings on your project and are running as Administrator, you should be able to specify IncludeIisSettings=true to have the settings included in the zip.
If you need the actual AppPool definition included (so it can be created), you should also set IncludeAppPool=true.

MSBuild or StyleCop task to verify key in App.config file?

In several projects’ App.config file, there is a line
<add key="url" value="http://www.example.com/"/>
Upon each build, I want to have a task to verify that the "url" key does not have the text "http://localhost". Is there a way to do this?
I'm assuming you have a team, and some of your team members inadvertently checkin those configs, changing that value to localhost.
If this is the case, why not have transform files for each environment, where your debug configuration can set the key to localhost, and your production/test/stage/qa/whatever configuration can set it to example.com or something else.
You might not have been aware that msbuild can transform your config files. Essentially you have your main config file, and then a config file containing just the things changed, for each environment. Upon doing a build, msbuild will modify the main one with whatever the changes are in the other "transform" files.
App.Config Transformation for projects which are not Web Projects in Visual Studio 2010?
Your transform file would look like:
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="url" value="http://www.example.com/" xdt:Locator="Match(key)" xdt:Transform="SetAttributes"/>
</appSettings>
</configuration>
The microsoft link is to http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx
They can easily be used on web.configs, as well as app.configs, with a little tweaking to your project file.
An alternative solution would be to integrate unit tests as part of your build, and have the test verify the key in your web.config.
Go to your builds:
Right click on your build and click on edit build definition:
Choose process:
Now we can set fail on build here:

Pass parameters via the command line to NUnit

Is it somehow possible to pass values to NUnit tests via the command line?
My tests use a certain URL. I have different instances of my code at different URLs and would like to specify the URL via the command line. File App.config is not an option, because I want to run the tests for different URLs via a batch file.
Use an environment variable to pass the information.
Use set from the command-line or <setenv> from NAnt. Then read the value using Environment.GetEnvironmentVariable().
NUnit 3 now allows passing parameters. Here is the usage
nunit3-console [inputfiles] --params:Key=Value
From the documentation
--params|p=PARAMETER
A test PARAMETER specified in the form NAME=VALUE for consumption by tests. Multiple parameters may be
specified, separated by semicolons or by repeating the --params option
multiple times. Case-sensitive.
Here's how you can access the parameter through code:
var value= TestContext.Parameters.Get("Key", "DefaultValue");
There seems to be no solution at the moment. The best option is to use NUnit project files, modify settings there and pass the solution file to the runner.
I had a similar issue. The answer of Achim put me on the right track, and for other readers:
Create a file, like example.nunit, like this:
<NUnitProject>
<Settings activeconfig="local"/>
<Config name="local" configfile="App.config">
<assembly path="bin\Debug\example.dll"/>
</Config>
<Config name="dev" configfile="App.Dev.config">
<assembly path="bin\Debug\\example.dll"/>
</Config>
<Config name="test" configfile="App.Test.config">
<assembly path="bin\Debug\\example.dll"/>
</Config>
</NUnitProject>
All the file / paths (of the configuration and assembly files) are relative to the location of the NUnit file. Also the App.config, App.Dev.config, etc. file are just .NET configuration files.
Next when you want to run it for a certain configuration you execute it like this:
nunit3-console.exe example.nunit /config:test
More information about the format of the NUnit file is in NUnit Project XML Format.
More information about command-line arguments is in
http://www.nunit.org/index.php?p=consoleCommandLine&r=2.2.5