Here’s a way to use the standalone Web Configuration Transformation Tool to use the same modifications that Visual Studio’s Configuration Manager uses to implement multiple deployment environments. In this example, I'm doing the transform of the connection string for deployment to a cloud platform. (The excellent UhuruCloud, for this example.)
My need was that I was trying to perform a VS Config Transform, but didn't need One-Click deployment support. My cloud host supplies a plugin for managing deployment, so I couldn't use Visual Studio's One-Click deployer which runs it for you, without showing exactly how it is executed. But VS is handy creating the transform files, so I wanted to take advantage of that.
Use Visual Studio to create your transform template.
1. In VS, choose Build - Configuration Manager - New... and name it UhuruCloud, for example.
2. In Solution Explorer, right-click on your Web.Config file and choose 'Add Config Transforms'
3. Edit the resulting Web.UhuruCloud.config for the transform.
Use the standalone Config Transform standalone Tool.
Get the tool from http://ctt.codeplex.com/Wikipage?ProjectName=ctt
The syntax of the tool is like so:
ctt.exe s:source.config t:transform.config d:destination.config
Use the standalone Config Transform standalone Tool.
Get the tool from http://ctt.codeplex.com/Wikipage?ProjectName=ctt
The syntax of the tool is like so:
ctt.exe s:source.config t:transform.config d:destination.config
That’s just the most basic usage. Other good Examples are provided in the distribution. For me, it was handy to have a quick batch script to make that call easier. Especially while trying to get the paths just right.
File: ctt_run.bat
#ECHO off
rem ... Use the Config Transform standalone Tool (CTT),
rem ... from http://ctt.codeplex.com/Wikipage?ProjectName=ctt
rem ... Basic CTT syntax is "ctt.exe s:source.config t:transf.config d:dest.config"
rem ... Set the (S)ource, (T)ransformTemplate, and (D)estination files here.
SET S=C:\tfs-hill\MvcITunes1\MvcITunes1\Web.config
SET T=C:\tfs-hill\MvcITunes1\MvcITunes1\Web.UhuruCloud.config
SET D=Web.New.config
#ECHO on
C:\Common\ctt.exe s:%S% t:%T% d:%D%
That’s it. (My example writes the transformed file Web.New.config.)
I hope this is helpful to someone trying to perform a VS Config Transformation but doesn't need One-Click deployment support.
Related
We are in the process of trying to automate our build/deploy processes with the Release Management tool for Visual Studio (formerly InCycle).
The Release Management tool includes a facility to modify settings in a web.config (or app.config). However, there are situations where I'd like to be able to do more than this.
For example, we have URL rewriter rules to automatically redirect HTTP requests to HTTPS. But this won't work (at present) on our dev workstations. So, the "base" version of the web.config doesn't include the rewriter rules -- they are inserted at build/publish time via a web.config transform.
But the Release Management "configuration variable" mechanism won't let me specify more than a single line as a replacement value.
I realize I can remove line breaks, and condense an XML fragment to a single line of text. But I'd rather not have a web.config with lines that are several thousand characters long. And I suspect our IT folks -- who after all may also need to view/edit the file -- would feel rather more strongly about this than I do ;)
In general, the web.config transform mechanism had several modes: you could change a setting but also insert or replace (or delete) an entire section / XML element. While it's nice to no longer be restricted to web.config files (out of the box), the new functionality seems to be much more limited.
Am I missing something? Has anyone else found this to be an issue? What did you do to work around it?
You can still use xml transform to achieve what you want. Make sure that your transform are applied during your build, and the resulting web.config file available in your build output folder will be containing your URL rewriter rules. RM will pick it up from there and apply any other normal token replacement.
Here is a post that help in this regards: http://incyclesoftware.zendesk.com/entries/21487316-InRelease-with-Web-Deploy
If you have multiple stages in your release path, and for example the first stage should not have your URL rewriter section, than it may be a bit harder. You will need to apply your transform as part of your deployment. Multiple components/actions will need to be used for that (xcopy component, xml transform action/component).
I can't find it now, but I know there is some command line tool you can invoke to achieve your xml transformation as part of your deployment.
Apologies for my lack of knowledge about rewriter rules but can they exist in the base version of web.config and be set up so that they don't effectively do anything and 'rewrite' to HTTP?
If that's possible then the way I would do this is to configure a web.config.release file that will create a tokenised web.config via the transformation process. However, rather than use Web One Click Publish I use the /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false arguments in the TFS build definition to apply the transformation. This then results in a build in the drops folder that is completely unaware about any environment it will be deployed to. You then simply use an XCopy Deployer-based component in RM to deploy the website and replace all the tokenised values for that environment. See my blog post here for more details of the technique.
I am a Visual Studio noob. My background is more Unix-related and mostly used to building things via scons or make. I don't even have much Eclipse experience.
Anyway, I am frustrated how it seems very difficult to move files between projects in VS. (I am running Visual Studio 2013). For example, suppose I have a ProjectXRel (release) and I want a ProjectXDev (development). I want them both to be runnable, and the dev version might have just a few editing changes that differ it from the rel version.
The intuitive thought is to just copy the files from ProjectXRel to create ProjectXDev, but VS seems to fight me on that (it wants to rename all the namespaces to the title of the project).
Also, some of the files, like .cs files derived from .dbml via OR designer, seem uncopyable, and rely on one replicating the process of using the utility to having valid files. I'm used to a project being defined by its files, but that's not really the case in VS. Instead it seems defined by process steps used to create and organize the files.
Also, do serious developers just use command line calls and powershell? That's seems harder, but at least you know what the %#$$# is going on.....
So, the basic question is, how does one replicate an existing project to produce a similar one for development purposes? (I know source control such as git could help with that, but that's not an option for this situation.)
Thanks!
You should be using the same project for both Development and Release.
The things that are different between Development and Release should be stored in a config file (web.config or app.config, depending on what type of project).
You should then be using Configuration Transformations to transform that .config file into Development or Release.
In Visual Studio, right click on the project and click Add New Item, select "Application Configuration File".
In this file you can put connection strings or key/value pair settings in the AppSettings element (MSDN Link).
Once you have your basic settings defined, you can then right click on the config file and click Add Transformation. This will add transformations for each of the Project Configurations you have. (by default Debug and Release).
It will look like this:
Now you can build deployment packages.
Or install Slowchetah and then when you press F5 to debug it will run the selected project configuration with the configuration transformation applied.
I've got a web deployment package I've built using Visual Studio 2010. I've defined a Parameters.xml file, which includes all of the parameters, descriptions, and default values.
When deploying a web application in IIS 7, it will automatically look at the parameters and build a GUI for the user, as seen here.
Does anyone know of any equivalent in IIS 6? We need to run the deployment locally, so Web Deploy isn't an option. Right now, I'm planning on using the generated ProductName.deploy.cmd file to install the package. But (as far as I can tell) the only way to set parameters with this method is to populate the ProductName.SetParameters.xml file. This file doesn't contain any of the descriptions from the original Parameters.xml file. It's just a set of key/value pairs.
Is there any way to prompt users for parameters - including the parameter descriptions - when running msdeploy? Or am I out of luck until I can use IIS 7?
I don't think that there is a UI like what you are looking for targeting IIS 6.
With that being said I have just released a Nuget package which I think would be helpful to you, read more at http://sedodream.com/2011/12/24/PackageOncePublishAnywhere.aspx. To give you a summary of why I think that it will help you is that after installing the Nuget package when you create a package from the web project in VS there will be a .ps1 file generated. When you execute that .ps1 file it will walk you through a publish, and one aspect of that is prompting for the parameter values. It prompts for two types of values:
MSDeploy endpoint info
MSDeploy parameter values
Based on #2 if you had any parameters declared when you invoked a publish you would be prompted for them, and it will show you the default value. For example take a look at the image below (green text is the param name, cyan text is the default value).
Based on this thread I just realized that I'm not showing the description for the parameters, but I'm wondering if that would be too much info. Let me know if you have any thoughts in this area.
Note in order for this to work for you at this time you'll need the following installed on the machine running the publish:
Powershell v2
MSDeploy v2
To give some info how this is implemented in case you want to do something similar w/o using my extension here is the info.
MSDeploy has a verb, getParameters, which can be used to determine all the parameters which exist for a package. For example we can execute the command
%msdeploy% -verb:getParameters -source:package=WebApplication1.zip
And the result would be what's shown below.
After you have that XML you can create whatever prompts/processes you want.
I have an Asp.NET MVC site that I manage multiple instances of. Each instance uses it's own database but the code base is all the same. To facilitate this I have several build configurations with matching web.config transforms, so that when I publish it doesn't use my development database but instead uses the specific database for that site instance.
The problem with this came today when I went to publish an update to one of the sites. I forgot to change the build configuration, so my publish to site A was using a web.config transform that was meant for site B, and mayhem and confusion ensued.
Is there any way to to specify that a specific publish target will ONLY be used with a specific build configuration?
Or is there a better way to handle this situation than juggling build configurations?
One way to deal with this sort of thing, and I'm not certain it's the best, but it is a way, is to set certain configuration values in a higher level web.config or machine.config file that always resides on the machine in question.
Then just make sure that your project files don't override those configuration values.
Here are some considerations if you do this.
If you want to source control these values, it can be more difficult
this way (this could be a pro or a con depending on your
environment).
If other virtual sites are on the same machine and use the same
configuration values, this could affect them all, and if multiple
sites do use that same configuration value, changing it at the
source will change them all (again, could be a pro or a con
depending).
If something is wrong with the value, it can be harder to
determine where the problem is or what is causing it.
Getting to machine.config may be difficult in your organization
or with your hosting provider depending on your access/security
privileges, and it's not always possible to put a web.config at a
higher level than your application.
Obviously the good thing here is that you can have a different value configured on each machine and as long as these values are not also set in your web.config (which would probably result in an error), you won't have to worry about compiling different versions.
I believe that Visual Studio 2010 has a way for setting different config files for different build types, but that sounds pretty much like what you are already doing, so forgetting to build the right way can still end up with similar results.
You could attempt to set up continuous integration with something like TFS Build if that is available to you, in which case what gets built for prod could be set up to always work a certain way and always pull from the correct build type.
Hope something here helps.
Maybe you could go a solution where you don't rely on the 'Publish' dialog of the web application that requires you to make the right setting every time, but instead use a automated command-line like solution (batch file, your own msbuild target, or a build server like CStroliaDavis suggested [cruisecontrol, tfs, teamcity]).
You can just call the 'package' target from command line which creates a package:
msbuild MyWebProject.csproj /t:Package /P:Configuration=Release;DeployIisAppPath="Default Web Site/Main/MyWebProject";PackageLocation="F:\MyWebProjectDeploy.zip"
This also creates a *.cmd file so you can deploy it like this:
F:\MyWebProjectDeploy.deploy.cmd /Y -allowUntrusted /M:http://webserver/MSDeployAgentService /U:Administrator /P:"Secret"
You can add a custom *.msbuild file to your solution that performs these actions, or maybe it's easiest to just add a command to Tools -> External tools.
With kwateeSDCM you can not just deploy apps and web applications but you can also manage instance-by-instance parameters or file overrides. I've only used it with tomcat wars but it's not tied to a language or a platform so I suppose it should be straightforward to configure it to work with ASP.NET as well.
Greetings,
I'm trying to figure out how to pull off the following scenario with MSBuild and Visual Studio 2010.
I have a set of three services that I would like to install. The default installation directory should vary with the build (qa, uat, and production).
To add another fun wrinkle to this whole thing, sometimes the uat environment can be pressed into service when we are at peak load, so each build of the service will need to have a different name. It doesn't happen frequently, but it is on the list. How can I configure the service installers to alter the service name dynamically?
I want to be able to create MSI installers for the services (for whatever the current build is). I have an existing and extensive MSBuild script for the various websites I'm working with already, but I'm a little unsure how to proceed with making the services work.
Obviously, the configuration files for each service build will be different.
I've added installer classes for each of the services.
I guess I'm a little confused with how to start this, so any help I can get would be awesome. I had considered simply hardcoding the different service names and using conditional compilation statements to set them, but I don't think doing so is a particularly clear way to go about it all. Any thoughts?
It might be simpler to just zip up the service bits during the build and deploy with MSBuild using or MSBuild Extension tasks. You would put your environment specific configuration data in an msbuild .properties file (mylocal.service.properites, qp.service.properties, uat.service.properties, etc.). This is the way I deploy services.
note: the property file would contain things like your db connection string, TargetDir, ServiceName, etc.
Service names are specified at install time see 'sc', 'installutil' or the WindowsService msbuild extensions pack task snippet below. This means you can copy the same service bits everal directories and install each with a unique name (e.g. QAService, UATService, PRODService).
note: I want to reinforce that the service name is a deploy-time consideration, not a build-time consideration.
<WindowsService TaskAction="Install"
ServiceName="$(ServiceName)"
MachineName="$(TargetServer)"
ServicePath="$(FullServicePath)"
User="$(User)" />
The approach is similar for MSI installers. I assume your installers prompt for all necessary environment specific configuration data... All [decent] installers have a way to provide answers from a file versus using the installer interactively. So, as above, you create one answer file per environment and feed it to the installer on the command-line.
You do not want to do this at build time... and thereby have a separate installer per platform. Was forced to do this with an ancient version of the wyse installer. Made me sad. You want a single MSI installer that can be run in every environment (given the environment specific answer file).
Details of the MSI command-line and answer file format will vary by product. What installer package are you using?
Cheers,
/jhd