Automatic change of web.config under source control during CI build - asp.net

I am working with couple of friends on an ASP.NET MVC website. The project is maintained in SVN and I have CC.Net set up to checkout latest version and do automated build and deploy to a pre-production server. The default build configuration is set to Debug, but the automated build is set to build Retail. Everything works just fine, except for the <compilation debug=""> in web.config which currently is set always to true. I'd like to be able to specify true or false for <compilation debug=""> based on the build flavor.
I've thought about two separate solutions to this problem.
I could have a pre/post-build step that modifies the value. However, the web.config file is under source control, so modifying it in the automated build will leave it checked out on the build machine. I could also have additional step that would revert it as well.
I could also instead of having web.config under source control, have a web.config.base file that is used as a source during the build to generate the web.config file. The problem with this approach is that most of the tools modify web.config directly and we have to manually merge such changes back in the base file. And since there's no indication when any tool changed web.config, we have to look for changes at any checkin. Not only this becomes a tedious manual step, but it's also error prone.
Both of these approaches would work, but have some shortcomings. I was hoping there's a more elegant way of doing this. Thus the question - how do you guys deal with modifying web.config that is under source control during the CI builds?

You can take a look at the Web Deployment Projects VS add-in. Scott Guthrie does a great job explaining it in this post.

Why not modify web.config as part of a build-step using a command line utility that can edit XML?
e.g. Obtain a command line utility that works like:
xml_mod.exe web.config [xpath-of-value-to-change] [new-value]
Then have different value per debug/release(retail)..

Why don't you just make the web.config read/write without checking it out from source control, make your changes you need during the build process and then discard them?
AFAIK SVN has the files read/write anyway.

we have a
web.config for development
web.config.cert which is deployed by hudson to our cert environment
web.config.prod which is used for production
This allows us to put comments in there and values in there specific to the environments when that would normally have to go in some documentation somewhere, and it would surely be ignored.
Like I said, we have Hudson deploy to our cert environment on each build, so it just copies the directory over, deletes the web.config and renames web.config.cert to web.config
You may want to check out Hudson, I dont think I've ever heard of anyone choosing CC.net over Hudson if they had the ability to choose :)

Related

How can I use a different web.config file for each Azure deployment slot?

I have several Azure deployment slots: dev, staging, production, etc.
I want to create a set of web.config files, one for each deployment slot. So web-dev.config, web-staging.config, etc.
I do not want to use the slot-specific settings in Azure because if you have more than one or two settings it seems vastly easier to just have all your settings in a text file.
I do not want to write XML transforms on a single web.config file because that is insane. Config files already have enough complexity without an extra layer of indirection. And even if I didn't think that, web.config transforms seem to be tied to build configuration and not to a deployment destination. I don't want to contort my build process for the benefit of my deploy process.
I know copying and pasting config settings across files is gross but here we are. Until someone at MS fixes configuration in ASP.net, I just want to have one file for each deployment destination and call it a day.
How do I do it?
You have a few options.
The most obvious is the transformations. I don't know why you're so quick to discount it: only a few settings should be changing between environments, right?
Or you can have multiple .config files and then make it part of your deployment script (I hope you're not just using VS to deploy). Your scripts can select the correct file and rename it to web.config.
And of course, you can move all the app settings and connection string stuff, and probably more, out of the web.config file and use alternative configuration systems. Perhaps a giant XML or JSON file with all the settings for each environment in it. Or perhaps use environment variables.
Really, it's up to you to write your deployment scripts and set your configuration up how you want it. It's not "up to Microsoft", it's up to you, though they have made it even easier to use a common configuration system across multiple sources in ASP.NET 5.

Visual Studio 2008 XDT (Config Transform) on build

I'm maintaining a webforms application for several different clients in Visual Studio 2008. Each client has their own separate web.config file. We are using config transformation when deploying which works great.
There are many developers currently working on this project, and while developing each developer needs to have the configuration values for a specific client. Right now, what we are doing is that each one of us, has their own version of web.config locally, and we just try to be careful not to check in the web.config file.
This approach of course has several drawbacks. We need to do this manually, which is annoying, we need to be really careful not to check in the config files since it could cause trouble for the rest of the developers, it's cumbersome to add a new value to the config, etc.
I'd like to transform the config files when building from visual studio, so we can chose which file to take the configuration values from, without having to manually edit web.config.
I've been looking in the web for a while, but the best thing i found so far is this:
http://www.codeproject.com/Articles/399002/Project-Build-Web-config-transformation
Which is not working for me, it gives me a build error saying it can't copy Web.config_output because the file is missing.
By default tools like SlowCheetah and other config transform technologies use the $(Configuration) to figure out the name of the transformation to apply. You could take the slowcheetah.targets file and edit it to take $(username) which will pick up the standard windows logged on user name if you're building inside visual studio. You could use a condition to apply the change specifically when '$(BuildingInsideVisualStudio)'='true'.
This will require you to do some work with MsBuild target files, but the end result would be that your developers can check in a web.jesse.houwing.config (in my case) and that of that file is there, their transformation will be applied instead of the standard release or debug transformation.
As for a good starting point, look at SlowCheetah.

Don't publish particular folder in ASP.NET

Is it possible to exclude a folder in a web project from being published? We've got some documentation and scripts that included in a particular project folder, and are added to the project, but when I do a VS publish, I don't want them to go up to the production server.
I know they shouldn't be in the project, but I thought I'd find a workaround before I try to convince the owner to modify the way he's doing things.
Old question, but I found if I mark the folder as hidden in Windows Explorer, it doesn't show/publish in your solution.
This is good for example to stop original photoshop images being included in uploads which aren't used and are big. Anything more complex though you'll probably want to write your own publish tool.
This doesn't answer your question, exactly, but my feeling is that unless you are a single developer publishing to a server, you would be better off doing builds on a dedicated workstation or server using MSBuild (or some other building and deploying solution) directly (and thereby would be able to very granularly control what goes up to production). MSBuild can not only build, but using some extensions (including open source types), it can also deploy. Microsoft has a product called MSDeploy in beta, and that might be an even better choice, but having no experience with it, I cannot say for certain.
In our situation, we have a virtual workstation as a build box, and all we have to do is double click on the batch file that starts up an MSBuild project. It labels all code using VSS, gets latest version, builds the solution, and then deploys it to both servers. We deploy exactly what we want to deploy and nothing more. We're quite happy with it.
The only downside, if it could be considered a downside, is that at least one of us had to learn how to use MSBuild. VS itself uses MSBuild.
For the files you don't want to go, loop at the properties and set the 'Copy to Output Directory' to 'Do not copy'
This option is not available for directories, however.
Can you not exclude them from the project through visual studio to stop them being published. They will the still exist in the filesystem
The only way that you can do this to my knowledge would be to exclude it from the project, do the publish, then re-include it in the project. That can be an issue.
There are probably much better ways to solve this problem but when we publish a build for our dev servers, we'll run a batch file when the build is complete to remove the un-needed folders and web.configs (so we don't override the ones that are already deployed).
According to http://www.mahingupta.com/mahingupta/blog/post/2009/12/04/AspNet-website-Exclude-folder-from-compilation.aspx you can just give the folder the "hidden" attribute in windows explorer and it won't publish. I tested this and it works for me.
Seems like a straightforward solution for quick and dirty purposes, but I don't think it will carry through our version control (mercurial).
Select all the files that should not be published.
Go to Properties
Set
Build Action -> None
Have to repeat the process for each sub-directory.

Temporary ASP.NET Files - duplicate file problem

I get an error when ever I replace a user control, or dll on th website. The solution is to stop iis and delete the contents of the folder, obviously not ideal to stop the site.
I read that this might be caused by class names being reused, as in when you make a copy of a control and add it to the solution.
Is it typical for this folder to be used, how can I avoid the site crashing whenever I make a change
Running on IIS7.0, ASP.NET 3.5
I get this problem if I update DLLs and don't clear out the BIN folder, because of the way my code is setup. For example, if I am using version 3.0.1 of a DLL and I add version 3.5.0 of that DLL, it causes conflicts.
As far as a solution, I would agree with the first answer though, which is to have a dev server and a live one, and publish up, although it may not be ideal for your situation.
you should separate development from production, and publish from dev to the prod iis.
btw, in case you actually have 2 classes with the same name, compilation should fail this way.
Use publish to publish the site, consider precompiling. The temporary folder is where resources compiled on the fly are cached.
Faking a web.config update to generate recompilation might also work as opposed to IIS restart? Though not ideal.

Different solutions/project files for Local vs Build environments

As part of improvements to our build process, we are currently debating whether we should have separate project/solution files on our CI production environment from our local development environments.
The reason this has come about is because of reference problems we experienced in our previous project. On a frequent basis people would mistakenly add a reference to an assembly in the wrong location, which would mean it would work okay on their local environment, but might break on someone else's or on the build machine.
Also, the reference paths are in the csproj.user files which means these must be committed to source control, so everyone has to share these same settings.
So we are thinking about having separate projects and solutions on our CI server, so that when we do a build it uses these projects rather than local development ones.
It has obvious drawbacks such as an overhead to maintaining these separate files and the associated process that would need to be defined and followed, but it has benefits in that we would be in more control over EXACTLY what happens in the production environment.
What I haven't been able to find is anything on this subject - can't believe we are the only people to think about this - so all thoughts are welcome.
I know it's anachronistic. But the single best way I've found to handle the references issue is to have a folder mapped to a drive letter such as R: and then all projects build into or copy output into that folder also. Then all references are R:\SomeFile.dll etc. This gets you around the problem that sometimes references are added by absolute path and sometimes they are added relatively. (there's something to do with "HintPath" which I can't really remember)
The nice thing then, is that you can still use the same solution files on your build server. Which to be honest is an absolute must as you lose the certainty that what is being built on the dev machine is the same as on the build server otherwise.
In our largest project (a system comprising of many applications) we have the following structure
/3rdPartyAssemblies /App1 /App2 /App3 /.....
All external assemblies are added to 3rdPartyAssemblies/Vendor/Version/...
We have a CoreBuild.sln file which acts as an MSBuild script for all of the assemblies that are shared to ensure building in dependancy order (ie, make sure App1.Interfaces is built before App2 as App2 has a reference to App1.Interfaces).
All inter-application references target the /bin folder (we don't use bin/debug and bin/release, just bin, this way the references remain the same and we just change the release configuration depending on the build target).
Cruise Control builds the core solution for any dependencies before building any other app, and because the 3rdPartAssemblies folder is present on the server we ensure developer machines and build server have the same development layout.
Usually, you would be creating Build projects/scripts in some form or another for your Production, and so putting together another Solution file doesn't come in the picture.
It would be easier to train everyone to use project references, and create a directory under the project file structure for external assembly references. This way everyone follows the same environment.
We have changed our project structure (making use of SVN Externals) where each project is now completely self-contained. That is, any references never go outwith the project directory (for example, if Project A references ASM X, then ASM X exists within a subfolder of ProjectA)
I suspect that this should go some way towards helping solve some of our problems, but I can still see some advantages of having more control over the build projects.
#David - believe it or not this is what we actually have just now, and yet it's still causing us problems!
We're making some changes though, which are forced upon us due to moving to TeamCity and multiple build agents - so we can't have references to directories outwith the current project, as I've mentioned in my previous answer.
Look at the Externals section of this link to see what I mean - http://www.dummzeuch.de/delphi/subversion/english.html
I would strongly recommend against this.
Reference paths aren't only stored in the .user file. A hint path is stored in the project file itself. You should never have to check a .user file into source control.
Let there be one set of (okay, possibly versioned) solution/project files which all developers use, and the Release configurations of which are what you're ultimately building in production. Having separate project files is going to cause confusion down the road, when some project setting is tweaked, not carried across, and slipped into production.
You might also check this out:
http://www.objectsharp.com/cs/blogs/barry/archive/2004/10/29/988.aspx
http://bytes.com/forum/thread268546.html

Resources