slow-cheetah icon indicating copy to clipboard operation
slow-cheetah copied to clipboard

Support for web

Open sayedihashimi opened this issue 11 years ago • 31 comments

If you are interested in this vote for it at http://slowcheetah.uservoice.com/forums/185106-general/suggestions/3385389-support-for-transforming-web-config-on-f5, we are only working on the most voted items

Figure out a way to make this work for web projects on F5.

sayedihashimi avatar Oct 29 '12 05:10 sayedihashimi

This would be a sweet feature.

tonysneed avatar Nov 19 '12 16:11 tonysneed

FYI in order to prioritize work we created http://slowcheetah.uservoice.com. I've already created a suggestion for this at http://slowcheetah.uservoice.com/forums/185106-general/suggestions/3385389-support-for-transforming-web-config-on-f5. If you care for this feature please vote for it as I can only work on the most wanted features.

sayedihashimi avatar Nov 24 '12 23:11 sayedihashimi

Please make this happen soon.

drknot avatar Dec 19 '12 19:12 drknot

What's the progress on this?

lorantd avatar Jan 17 '13 16:01 lorantd

Not yet but this will be the next feature that I work on after I close out #44. I'm pretty close to completing that so it makes sense to prioritize that instead of this.

sayedihashimi avatar Jan 18 '13 19:01 sayedihashimi

Hi Sayed

Any progress on this enhancement. Could you also please tell some more on exactly how you are gong to accomplish this?

jochenvangasse avatar Feb 21 '13 11:02 jochenvangasse

Sorry for the late reply here. I'm trying to convince @BillHiebert to help me with this feature. Need to get a real dev for this one.

Regarding the design, I've gone back and forth on this. I initially wanted to have a solution where web.config is modified in place. After thinking more about it, I do not think its feasible to have a reliable process using web.config and transforming it in place.

Instead here is what I'm currently thinking.

Add a new gesture on the right-click for web.config, Enable transform on build When that is invoked it will copy web.config to web.template.config When you build web.template.config will be transformed using web.{Config}.config and overwrite web.config

One concern that I have here is that we need to ensure that the transforms are applied only once during a publish/package operation. To facilitate that I think the behavior should be:

  1. Only transform web.config during build if BuildingInVisualStudio is true and a publish/package is not happening
  2. For command line scenarios disable transform on build by default, but have a property which can enable it

Regarding the actual implementation of the transformations, it will likely be based on my prototype at http://sedodream.com/2010/10/21/ASPNETWebProjectsWebdebugconfigWebreleaseconfig.aspx.

Can you let me know what you think about this approach? Will it work for you or not?

sayedihashimi avatar Mar 05 '13 05:03 sayedihashimi

Sounds good. This will definitely work for my common situations.

One side effect I can think of is you will get the "File has changed, do you want to refresh" warning in Visual Studio when you are building and you have the web.config open in the IDE. Not a dealbreaker though.

EDIT: I just thought of a potential issue though. If you transform the web.config when building in Visual Studio, and your using a source controlled project, isn't Team Explorer going to pick up you change, and put a pending change on the web.config file? You need to be careful not to check-in a transformed web.config file then.

jochenvangasse avatar Mar 05 '13 07:03 jochenvangasse

This is my biggest annoyance right now, and implementing this new feature in Slow-Cheetah would be great!. Not having the ability to do transformations when executing F5 build commands causes me problems.

Apparently Slow-Cheetah is already capable of transforming app.config files when executing F5 build commands, which I was not aware of previously. Just in case I am mistaken, that feature is critical for me in my current Silverlight project, and I need it to get the full benefit of this new feature. There may be other files with transformations, and hopefully Slow-Cheetah will be able to transform those as well at build time.

Also when I change environments I have to update the project properties on my Silverlight web project (for details see my new issue post at https://github.com/sayedihashimi/slow-cheetah/issues/77 - update .csproj at F5 build time). This is a related issue.

boomer57 avatar Mar 06 '13 03:03 boomer57

Looking forward to hearing an update from you.

Lemonade92 avatar Apr 11 '13 05:04 Lemonade92

Sorry for the delay here everyone. Updating web.config on F5 is much tricker than for app.config. Web.config is used from the source location where as app.config is used from a different location at runtime. Because of this we have to be very careful. We are dragging our feet here though. I'll discuss with @BillHiebert and @FriskyDev to see if we can speed this up.

sayedihashimi avatar Apr 14 '13 00:04 sayedihashimi

Thank you Sayed – It will be a very useful addition to the SlowCheetah tool!

boomer57 avatar Apr 17 '13 01:04 boomer57

Hi Sayed We have the issue of multiple release configs and web.config being source controlled here. The resolution is simple. Don't Source controll web.config. web.config is a distribution file, the source file is web.template.config.

So following you proposed solution would work very well for us.

pug2001 avatar May 21 '13 09:05 pug2001

I hope this feature will be released very quick because this is always the thing that we are missing in web projects...

LockTar avatar Jun 27 '13 09:06 LockTar

Would it be to much to ask to incorporate this feature into vs2013Šout of the box if possible? :) I love this tool by the way, and I also eagerly await for this feature to be released. I can help with testing it too!

From: Ralph Jansen [email protected] Reply-To: sayedihashimi/slow-cheetah <reply+i-7927086-b8ef04338112238c535ff46d331b1be082e32269-143497@reply.githu b.com> Date: Thursday, June 27, 2013 2:03 AM To: sayedihashimi/slow-cheetah [email protected] Subject: Re: [slow-cheetah] Support for web (#39)

I hope this feature will be released very quick because this is always the thing that we are missing in web projects...

‹ Reply to this email directly or view it on GitHub <https://github.com/sayedihashimi/slow-cheetah/issues/39#issuecomment-201053 92> .

jpvelasco avatar Jun 28 '13 02:06 jpvelasco

Tried the solution mentioned in http://sedodream.com/CommentView,guid,68b7e248-b9f5-4d07-bdfe-eb037bcf2cbb.aspx#commentstart

Following the steps mentioned in the above link is generating the web.config file; but in debug mode if I click F5, Visual Studio is showing "Debugging Not Enabled" dialog with 2 options.

  1. Add a new Web.config file with debugging enabled
  2. Run without debugging

I have enabled debugger attribute in web.template.config and the same is available in transformed web.config file also. <compilation debug="true" targetFramework="4.5" />

Please let me know how to resolve this; because it is defeating the purpose of transformation in DEBUG mode.

kamalt avatar Sep 05 '13 21:09 kamalt

Hi Kamalt,

I think that I know what your problem is. You created a new web application and started on the workaround without running (debugging by hitting F5) de site first. If you create a new web application and run it for the first time, you will get that popup. It only asks if you want debugging enabled in your application. It has nothing to do with the workaround. Just say yes that you want debugging enabled in your application.

Check my blog post about the web.config transforms. Give it a comment if you like it or need some help. http://www.locktar.nl/general/use-config-transforms-when-debugging-your-web-application/

Ralph

LockTar avatar Sep 06 '13 05:09 LockTar

@Ralph My scenario is not with new web application. We have a web application which has DEV/QA/UAT/Staging and Production environments. It is hard to maintain single web.config for all the environment. So, renamed web.config to web.base.config and have similar versions for all other environment; implemented web.config transformation as mentioned in http://sedodream.com/CommentView,guid,68b7e248-b9f5-4d07-bdfe-eb037bcf2cbb.aspx#commentstart

Now I am getting the transformed web.config during build process. But if I click F5 to debug, Visual Studio prompts the dialog "Debugging not enabled". Visual Studio expects the web.config file to be included as part of the web application project.

kamalt avatar Sep 06 '13 05:09 kamalt

@kamalt, If I understand you correctly, the web.config is not in your web application. There must be web.config file. In mentioned this in my blog. http://www.locktar.nl/general/use-config-transforms-when-debugging-your-web-application/ If you check everything in, open source control explorer. Remove the web.config from source control. No every transform is also marked for deleten and het project file is checkout for editing. Undo everythings except the deletion of the web.config. Now the project file thinks that the web.config is in your project but it doesn't exist on your hard disk (you can delete it if you want). When you build the project, a new web.config is generated and placed on your hard disk. The alert icon by the web.config in your solution explorer is now also gone.

Then your problem is gone. Well it's gone if I understand you correct ;-)

LockTar avatar Sep 09 '13 11:09 LockTar

Note that my solution in the blog post is slight different than the blog that you gave me. See the difference in the wpp file.

LockTar avatar Sep 09 '13 11:09 LockTar

@LockTar thanks Ralph; will give a try and keep you posted.

kamalt avatar Sep 10 '13 08:09 kamalt

@sayedihashimi I don't know if you remember, but I spoke to you about a year ago about this at a conference. This is how I would solve this problem:

  • Web.config is renamed Web.base.config.
  • Thus Web.config is no longer part of the project and as such is not source controlled. Web.base.config is part of the project and thus is source controlled.
  • On build, take Web.base.config and apply the appropriate transformation base on selected build config to generate the in place web.config.
  • The rest of the build pipeline, which assumes web.config is the file to use when running locally, will see that newly generated file in place. This ensures the assumptions the rest of the pipeline makes about the web.config name/location aren't broken.
  • It is important that the generated web.config not actually be a file included in the project since it is going to be generated on build, and we want to avoid it being source controlled(of course someone might explicitly add it to source control, but so long as it is not part of the project, and just lives in the folder, then it should be treated like a transient file and thus not source controlled, otherwise it's constantly going to get checked out for no reason).

If I understand your prior comments, the issue is with in place modification. The reason this is problematic is because transforms are meant to be a one way process that goes from source to destination. When they were only used for deployments this was fine. When you start dealing with the local inplace web.config, then you need to separate the source of the transform from the result. By renaming the source to web.base.config and making web.config the result of the transform, you eliminate that problem.

I'm not sure if you are still with Microsoft, but I don't understand why this wouldn't be considered for inclusion upstream as a first class feature of ASP.NET project, rather than being a part of slow cheetah. This feature could go along with a new version of VS project, and when loading a project that is an older version, the upgrade process for the project would rename the web.config -> web.base.config and from there on the new feature would take care of generating the web.config.

Then in a future iteration of ASP.NET, perhaps it can be improved to look for web.config in the output folder of the build, instead of inside the project folder. This would fit more with other conventions for files generated from the build process since they are transient.

I've proposed this feature before on Connect and had it closed because the reviewer claimed it was already supported, and I've seen the same thing proposed for WebAPI on UserVoice for ASP.NET and get closed because the reviewer claimed it was already supported, which we both know is absolutely not true: http://aspnet.uservoice.com/forums/147201-asp-net-web-api/suggestions/4273563-support-web-config-transformations-on-build

Clearly this guy doesn't understand what "on build" means.

AaronLS avatar Jan 14 '15 05:01 AaronLS

+1 @AaronLS I have done exactly what you describe on many projects and it is the best solution that I (we) have come up with as well. The only issue is that it splats your Web.config on each build which will cause IIS to reload which makes development a little slower than it really should be...

todthomson avatar Jan 14 '15 05:01 todthomson

@AaronLS that's a great proposal but Visual Studio has a lot of tooling that will automatically create (and modify existing) web.config files. So the issue is when web.base.config exists and you drag and drop an item onto a web form, or perform some gesture to add a connection string to web.config, it goes into the wrong file.

I've asked Dan Roth to update the uservoice item to remove the Completed marker

FYI SlowCheetah project is now in maintenance mode https://github.com/sayedihashimi/slow-cheetah/issues/158. I will not be adding any features myself.

sayedihashimi avatar Jan 14 '15 05:01 sayedihashimi

Let's talk about ASP.NET 5 though (I own the VS project system for that). I have the following questions.

  • Given that the application config is in config.json and that it has a simple API to load other config files if needed, do we need XML transforms on publish for ASP.NET 5?
    • Just today someone sent me an email stating that they need this feature because they use SiteFinity which is heavy on XML files. I'd like to see if others need this for ASP.NET 5 as well.
  • What about transforming on build? Is there anything that you think you'll need to transform on build? FYI we will likely have support to have custom config settings for F5 by using environment variables.

sayedihashimi avatar Jan 14 '15 05:01 sayedihashimi

@sayedihashimi Had not thought of that, darn. Along those lines there are nuget packages that automatically add their default configuration using an install time transformation would need to have that transformation applied to .base. instead. That does make it a bigger problem to solve. Thanks for having them look at that issue. I've never had any luck replying to closed issues, it seems like once its closed there is no notification mechanism to bring it to anyone's attention.

AaronLS avatar Jan 14 '15 05:01 AaronLS

I went ahead and reactivated the uservoice item. Feel free to add votes if you are interested in it. We will need a lot of votes to implement that though. We looked at it before as I stated and it's a lot of work, requires a bunch of changes. The Add Reference dialog touches web.config as well.

Thanks for having them look at that issue.

It's my team, I wanted to enable F5 and transform web.config but it was too costly.

For ASP.NET 5 I do not believe that we need to apply transforms on build because we are planning to have an experience where you can have custom app settings/con strings via environment variables that you define in the debug profile.

sayedihashimi avatar Jan 14 '15 05:01 sayedihashimi

@sayedihashimi If I understand you correctly about ASP .NET 5 (maybe we should start a separate topic about this somewhere), we can have custom variables for a specific solution config? So they can be set somewhere in the solution configuration manager? This is great news!

As I mentioned before, I wrote an article about web.config transforms just as @AaronLS said. http://www.locktar.nl/general/use-config-transforms-when-debugging-your-web-application/

The thing is that we have 1 application with a lot of settings for enabling and disabling functionality in the application. But that application is released for multiple "labels" (labels are companies that work almost the same but have totally different styling, javascript files etc.). So on build time we have transforms for setting the connectionstring, theme name etc. in the solution so we have still 1 solution for all the labels. So we have created a separate solution configuration for each label.

LockTar avatar Jan 14 '15 07:01 LockTar

Of course the downside is that if we install in example a Nuget package. The wrong web.config is transformed (in example updating MVC 4 to MVC 5). You have to update the "base" config by hand.

LockTar avatar Jan 14 '15 07:01 LockTar

@sayedihashimi The only examples I've seen of providing any sort of transformation to config.json involve either providing a specific value on the command line value-by-value: >k run --display:font:color Purple or via environment variable: MONGO_CONNECTION=mongodb://MY.IP k kestrel

Maybe I'm missing how this is intended to be used. I have read about new project json files quite a bit, but haven't seen much on config.json. This is starting to sound like trying to compile something using make where you had all kinds of environment variables to wrestle with and/or construct this huge one liner of a command line string with all your variables on the command line.

Usually for each deployment(we have places we might deploy to) we would transform an entire section. In the above techniques, what that means to me is tediously providing a value for every element in the section in a syntax that is very different the original config.json it is influencing. So let's say for simplicity we have a section that contains 3 values that are different for every deployment: a SQL Server connection string, a Raven DB connection string, a key/value pair that identifies the deployment type(if it's a test system we have some conditional code).

What we do now At my current workplace, we have 5 fairly static deployments. localhost, which isn't really a deployment, just runs using default web.config.

Two are live environments that allow clients to login to our website to utilize our product as software-as-service. Basically a multi-tenant system. One deployment is where they can configure their portal and change/preview content, and the second is the live system where they publish changes.

Two are test deployments that mirror the two live deployments.

So currently we have web.config, plus 4 transforms for the 2 test and 2 live deployments.

Where compile time transforms would help It would be great if we could switch localhost to one of the two test configurations so we could test different scenarios against the other test databases before checking in changesets for a new feature. This is where compile time transformation would be great. Another scenario I've wished I had is when making changes to DB structure, I restore a copy of production data to do pre-production testing to verify that the next release won't break existing data. Being able to easily switch to a configuration that points to that DB would make this process alot easier.

Solution with Config.json? So I try to imagine how I would pull this off with the new environment variables. Let's forget about the desire to be able to switch configuration on localhost for now, and just think about what deploy-time transformations do now. Instead of having a web.testing.config transform, I would take all those values and put them on a single command line for launching the web server. OR I could build a *.bat file that modifies environment variables using the setx command. Neither one of these seems very well structured. I now have what is essentially the same configuration living in two very different syntaxes, the original config.json, and the transformation which in the form of either a huge command line or a batch file of environment variable commands.

I wouldn't want to directly modify env variables on the target deployment server directly without having that information source controlled, hence why I'd go for a batch file. There's a ton of other configuration that differs between test and production. Things like log4net which are much more verbose in test and log in a unobtrusive way, versus production where only serious unhandled exceptions are of interest and these generate emails. Log4net configuration involves large sections of values. These configurations have been carefully tweaked, and if we ever have to rebuild these servers, or expand our web farm beyond two servers, we wouldn't want to have to set environment variable by environment variable from memory on the new server. If I have to provide a huge list of environment variables, value by value, then I'm going to choose batch files so that I at least have some file I can source control.

This means deployment transformations no longer happen automatically. I need to remember to run my little batch file for that which applies to that particular deployment.

Transforms are source controlled, because we carefully decide what the production configuration will be at design time. This might be a stark contrast to applications such as mediawiki that are designed to encourage users/administrators to modify configuration, but in environments I've worked in, configuration for each application/service requires intimate knowledge of the application design, and administrators never touch these configurations. If we make a decision to change configuration at runtime in production, a developer usually does so after careful review by the team. But we then make the same change to the applicable transform in source control, so that future deployments of the next release will preserve that change. So we still have the flexibility to change values at runtime.

Environment variables/command line variables are a movement in the direction of moving this configuration decisions away from design time decisions, to runtime decisions. This is pretty common for things like mediawiki where alot of effort has been made to allow the app to be deployed and integrated in many different environments. This comes along with a burden on the administrator to install the app with a vast knowledge of how all the configuration options work.

The other end of the spectrum is web transforms, that are source controlled and thus are configurations decided at design time. Consider all the people who have asked for this feature. If transforms are exactly what they want, and they just want to be able to easily swap them out and/or marry them with build configurations, then it seems they are pretty happy with making configuration decisions at design-time about the various target deployments they are planning.

If you were to build the MVC .NET equivalent of GMail, you wouldn't care about making your software-as-a-service application to be configurable like mediawiki. You're going to have a very finite set of deployments. A couple for test, one with test data, one pre-production using some subset of production data, and a bunch of identically configured production servers in a web farm. You might have a few different production configs catering to different regional datacenters, but its still a finite set. You can anticipate these deployments at design time, decide the best configuration for each, and check those decisions into source control as transforms, and ensure you get consistent deployments.

Source controlled configuration transforms are to configuration, as code-first EF is to database structure management. Prior to EF code-first, database first was pretty common. Trying to reverse engineer a graphical EDM that produced exactly the DB structure you wanted was problematic, so you instead modified your database structure and then refreshed your EDM. You had to go and touch every database to modify its structure. EF code-first+migrations changed all that, allowing you to manage your DB structure through source control, and ensure deployments of your application coincided with deployments of new database structure. Transformations provide this same experience by ensuring new configuration for a new version of the application is deployed along with the application. Deploy to test, don't have to remember to do any extra steps. Later on, deploy to production. Do I have to remember to tediously add environment variables? Nope, the transform I already planned/designed at design time gets deployed automatically to all servers int he farm.

If we add a new configuration section, and if it is something that needs different configuration for test vs production, I'm going to have to go and add a new environment variable to each and every server?

And should we ever rebuild a server or add servers to the web farm, we just choose the particular transform appropriate for that deployment.

Dependency on environment variables makes for lots of "works on my machine but not yours" scenarios. This is exactly why dependency on GAC installed libraries has slowly died out to be replaced by side-by-side DLLs, and then evolved into tools like Nuget that manage those side-by-side DLLs to reduce the affect of environment variations between developer machines.

It encourages people to do one-off configurations via typing in a command line or modifying environment variables. If I as a developer inherit a project, which has specific configuration customizations for production, then it's a heck of alot easier to understand a transform file that is easily found in source control, than to have to remote into all the various test and production servers and poke through environment variables. If the customization were entered on the command line, where am I going to find those? I would have to actually use a process inspector to see what the command line was it was run with, assuming the test servers are running at the time! Imagine a command line with a value-by-value entry for the dozen values that make up a log4net configuration, each one having to index to it's location in the structure with this syntax of appender:parameter:parameterName. Often times getting up to speed on how a legacy application works involves not just understanding the code, but understanding the configuration.

So to me, it seems like a step in a direction that makes what is currently possible, deploy time transformation, much more difficult. This doesn't even get into the desired feature of swapping configuration locally at build time.

AaronLS avatar Jan 14 '15 07:01 AaronLS