Friday, November 05, 2010

Team Build + Web Deployment + Web Deploy + VS 2010 = Goodness

I have to confess this is one of the most requested blog post in Web Deployment via either direct emails, comments on the blogs, twitter, in conferences etc and it has been completely my bad to have prolonged this as long as I have. As it is said - better late than never, so without any delay let us get started.

In this blog post I am hoping to cover the topics of setting up your web deployment using Web Deploy (MsDeploy) and Team Build. When we talk about automated web deployment with Web Deploy (I love our naming J) there are multiple aspects that come into mind, let us clear few of the concepts before we proceed with the walkthrough:

· Web Packaging – Web Packaging is the process of creating a .zip file which can contain your web content (pages, images, CSS, JavaScript files etc), databases, IIS Settings, Application creation, ACLs etc. From your Team Build you can easily create Web Packages which you can ask your server admin or Test team to pick up and install on you web servers for testing. With Web Packages (.zip files) you will also get a .cmd file created by VS 2010 which can be run to install the package. There is not a direct automation to run this command file from team build but you can easily hook up post build step to execute the .cmd file if you would like to automate the installation of the package as well.

· Web Publishing – Web Publishing is the process of directly taking the source application (in Team Build case the sources are hopefully in your TFS source repository) and directly pushing it to the destination web server. In this case a .zip file is not created but if you would like that for archival then that is possible as well. If you want your web servers to have your latest web application installed in Continuous Integration (CI) fashion then Web Publishing is the direction I would recommend.

Note - Web Publishing can only work when you have your Web Servers configured to accept Web Deploy request. There is an earlier blog post about Setting up your Web Servers for Web Deploy, without having your Web Servers setup the below walkthrough (Publish Section) will not succeed so please make sure that you have your Web Servers configured correctly before proceeding.

Step 1: Get your TFS Build Server and Source Code Control Set up

I am going to assume that you have a license for VS 2010 TFS environment setup. Below are the simple steps to have TFS setup using basic configuration (i.e. everything installed as shown belowJ)

clip_image002

Once the product has installed and you get a successful “Setup is complete” dialog, finish the installation and you will see a TFS configuration wizard. First let us configure Team Foundation Application Server and then configure the Team Build service as shown below:

clip_image004

The TFS Basic install is sufficient as it is the simplest setup option and honestly it does most of the stuff that I need. Honestly in my opinion it is so many times better than TFS 2008 which was much more complicated to set up. For nearly all of the screens just simply keep clicking next and eventually the set up wizard will finish and hopefully you will agree with me that this setup is indeed a breeze.

Once the server configuration is complete, start the wizard for to Configure Team Foundation Build Service and it will come up with a Welcome Screen below:

clip_image006

Again, click Next for each page and accept the defaults, before even you know you will have a functional TFS server ready to go. I know that the above explanation will sound like a joke but really TFS 2010 setup is as simple as that and it is difficult to complicate it unless you really require all the bells and whistles. I did have a loaded Microsoft software box but if you don’t then there might be some minor pre-requisites required but I am sure the setup wizard will let you know that J

Glitch: Now there is one glitch in this entire set up still which I need to call out for you. When you build your web projects, you need the Team Build service to have all the .targets files your projects needs. The TFS installation I showed above does not include all the targets files that comes with Visual Studio 2010. To get the necessary files on your machines, install Visual Studio on the same machine as your TFS server so your projects can build successfully. Now that certainly does not sound very nice so the alternate back door option is to go to %Program Files (x86)%\MSBuild\Microsoft\VisualStudio\v10.0 on your Visual Studio IDE box and copy the target files on your Team Build Server at the similar path. For Web deployment you will most likely only need “Web” and “WebApplications” folder but there is nothing wrong with having all the tasks and targets there just in case you need them later.

Step 2: Connecting to your TFS server from Visual Studio and getting your project into source control

On the home screen of VS 2010 you now have an option to Connect to Team Foundation Server or alternatively you can do so from the “Team” menu within VS too as shown below:

clip_image008

clip_image010

You will then see the “Connect to Team Project” dialog where you point to your TFS Server. If your server isn’t already populated in the server list drop down, you can add it clicking the “Servers…” button:

clip_image012

Once you are connected, you need to create a new Team Project from the File menu:

clip_image014

Give your team project a name and click through the wizard to create your Team Project and finish the wizard. Once your team project is created, you are ready to get your app into the source code control.

If you need further help in setting up your source code control and build server then check out the links below:

· TFS 2010 Installation Guide

· Using Version Control with TFS 2010

· Understanding basic Build with TFS 2010

Step 3: Get your app running and checked into TFS Source Code Control

Well you know how to get your app up and running so I will not dive into that J but just for reference of this walkthrough below the is app I am using. I created this Web App for TechEd US 2010 in New Orleans using MVC Music store sample on CodePlex. (You can watch the TechEd US 2010 video here) As you can see in the sample below it is working on my localhost.

clip_image016

The site is also checked into my TFS source code control as shown below:

clip_image018

To check your application to Source Code Control you simply need to right click it and the menu options will guide you from there.

Step 4: Connect to TFS using Team Explorer

On VS 2010 Team Explorer you will find a button on the top right which will allow you to connect to a team project. When you click the button and select your Team project your Team should similar to what I have below:

clip_image019

Step 5: Create a new Build Definition

A build definition instructs TFS on how to trigger the build. In this case we want deployment to accompany the Build too so we will create a new Build Definition and configure it accordingly. For that right click on the “Builds” node of the Team Project and click “New Build Definition”

At this point you will see the below dialog where you can name your build definition appropriately.

clip_image020

Step 6: Configure your Trigger in TFS 2010 Build Definition

Trigger configuration informs Team Build on when to fire a build there are several options as shown below and I will explain them at high level for you to be able to make the right call

clip_image022

· Manual – As the name suggests this mode allows the Build to be triggered manually as you desire, for demo purposes I am going to use this but ideally you want to explore other options also to determine what works best for you.

· Continuous Integration – This is classic celebrated CI model where every check in into the source code control will cause a build and hence resultant deployment that we would configure.

· Rolling Builds - Sometimes when working in massive teams CI can be disruptive as there are several check ins happening every other hour. In that case you can inform your dev team that there will be a build happening every X minutes and they should plan for that. During end game period of the project this configuration may help to have routine quick builds coming out.

· Gated Check-Ins - This was one of the highly requested features for teams who did not want any broken builds due to bad check-ins. This will ensure that only check-ins which merge & build successfully.

· Scheduled Builds – As name suggests you can also have builds coming out during regular times every day. This is the model which is used by larger VS and .NET teams in general, we too get our builds created on a nightly basis. The funny part is that I do not think that VS & .NET build configuration is as easy as TFS 2010 makes it for everyone else J

Step 7: Configure your Workspace which needs to be built

This is where you specify what you want to build. As shown below I have configured my Project folder as the build target.

clip_image024

Step 8: Provide Drop Location where you want your builds to be dropped

This is relatively a simple step for creating a UNC folder with correct folder permissions so that your TFS build (which typically runs under NETWORK SERVICE) has correct permissions to write to build output path. My setting looks as below:

clip_image025

Step 9: Setup the Retention Policy

Retention Policy simply informs how to save the builds in the drop folder mentioned above. I did not modify mine so it looks as below, although you might want to change these settings based on the disk space that you available:

clip_image027

Step 10: Configuring the Deployment Process

For this you have to go to the “Process” tab which looks as below:

clip_image029

Most of the items in these are self explanatory but I want to spend some time explaining a few which matter in our case:

· Automated Tests – TFS allows you to run the tests in Tests.dll automatically during each build so if you would like to have some unit tests run during build and deployment then this is a great place to mention that. There is also a flag to stop running the tests in the grid which you can set if you do not want to disturb your configuration of this property.

· MSBuild Arguments - This is the location where you need to specific the hooks to mention that you want to trigger deployment as part of the build.

o Web Packaging – For Web Packaging the argument you want to specify is simply:

/p:DeployOnBuild=True;

The above property is going to tell the Web Publishing Pipeline (WPP) to engage after the build is successful. At the default target which executes is Packaging you should not need to provide any other properties.

o Web Publishing – For Web Publishing the arguments you want to specify are:

/p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True /p:MSDeployPublishMethod=InProc /p:MSDeployServiceUrl=localhost /p:DeployIisAppPath="Default Web Site/NewOrleansJazz" /p:UserName=domain\user /p:Password=myPassword

In this case because we want publishing with Web Deploy to happen we provide /p:DeployTarget value to be MsDeployPublish.

/p:CreatePackageOnPublish allows you to create a package before publishing, it will help you keep an archive of what you published on your local drops folder. Although do note that It will certainly slow down the deployment and eat your disk space so choose it as you see fit.

/p:MsDeployServiceUrl tells the WPP where the project needs to be published to. In the beginning of this post I had mentioned that you need to set up the remote Web Server for Publish, this is the place where it finally gets used. The URL format is typically https://ServerName:8172/MsDeploy.axd. As I am using localhost as my build as well as test server I do not need to provide the full URL (i.e. VS 2010 will complete it as needed) but since your test server is going to be different than build server in real world you will have to provide full URL.

[UPDATE: It was brought to my attention that I had missed a detail in this post which is certainly worth clarifying.  If you are using the Service URL by setting up the server as explained above then you will have to change MSDeployPublishMethod from InProc to WMSVC so the property should become /p:MSDeployPublishMethod=InProc  to /p:MSDeployPublishMethod=WMSVC  Note that if you are publishing to localhost VS can use Web Deploy APIs directly within the same process of VS hence I was using InProc as my option.  If you are publishing to a different server then InProc will not work and give you errors so please make the above change.  Apologies for missing this detail earlier.]

/p:DeployIisAppPath tells the publishing system the IIS Site Name/App Name that you want to publish to. E.g. Default Web Site/MVCMusicStore

/p:UserName=domain\user is the actual User Name which has access to the remote Web Server on which you set up the Web Deploy Publishing

/p:Password=myPassword is the actual Password for the User Name above

NOTE: Do note that the sample here can only publish to IIS 7 (Win2k8 and above), if you are running IIS6 or lower (i.e. Win2k3/ Win2k) then you need to follow slightly different process. Please drop a comment here and I will write a follow up post on that.

o File Copying – This will allow you to simply to a xCopy deployment without needing to setup any remote service

/p:DeployOnBuild=true /p:DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempRootDir=\\BuildServer\BuildDrops\MVCMusicStore /p:AutoParameterizationWebConfigConnectionStrings=false

/p:_PackageTempRootDir allows you to specify the remote server location on which you want xCopy to happen. Again the remote location will need permission to be writable by Team Build Agent which is running the deployment

/p:AutoParameterizationWebConfigConnectionStrings=false essentially tells WPP to not parameterize the Web.Config file since doing so will introduce replicable tokens within Web.Config which are used during Packaging & Publishing.

NOTE: File Copying was honestly never designed out of the box to be used from Team Build in such fashion but some people have been interested in using Web.Config Transformation during xCopy and hence I thought it was worthwhile mentioning this in the blog.

PS: Using properties which begin with underscore “_” is not typically recommended as they are considered private MSBuild variables by convention but in this case it is relatively easy way to accomplish the xCopy solution. Even in future versions of VS if this property changes I am hopeful there will be alternate/easier way to do this. In general if you can set up the Publishing on your web server using Web Deploy I think it will yield you longer term advantages and I think it is a worthwhile endeavor to take.

· Projects To Build - When you have only one web application and class libraries then it is easier to just have the Project (CSProj or VBProj) to build as shown in my example above, but if you have bunch of projects which all need to built then you might have to go with Solution Build option (.SLN).

Deployment for Web Apps is feasible at both Solution as well as Project build level although when it comes to Solution Build then you might want to make sure that the properties you are passing at Solution level will apply to all the projects in the solution which might not always the outcome you desire. In that situation all these properties can be set within the .csproj or .vbproj files too. You can do that by unloading your project file and in the top <PropertyGroup> section just add above properties as you like:

For e.g /p:DeployOnBuild=True can be added as <DeployOnBuild>True</DeployOnBuild>

Step 11: Trigger your Build Definition

Now that you have everything configured you can right click on the Build Definition and hit “Queue New Build”.. That will show you a dialog which you can simply hit OK on and you should soon get your Build ready and the site deployed as shown in my case below:

clip_image031

After a while when you check into the Completed section of the build you should see your new build lined up.

clip_image033

On inspecting the IIS and SQL Server you can see my sites & DBs are also deployed.

clip_image034 clip_image035

Finally on running the application it runs great too:

clip_image037

This was actually a combination of setting up my DB deployment settings too, to learn more about configuring your deployment in the right way check out TOC on Web deployment.

PS: If you get an error on TFS like below:

TF215097: An error occurred while initializing a build for build definition \TechEd-US-2010\MvcMusicStore: There was no endpoint listening at http://MyServer:9191/Build/v3.0/Services/Controller/1 that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

Then most likely you do not have your Build Service running, you can enable it by going to Start à All Programs à Team Foundation Administration Console à Build Configuration.

Conclusion

Hopefully this will get you going with your automated web deployments. Please write back if you feel anything is missing or if you have any other questions. If you have questions like how would you configure what gets deployed, how to set up DB deployment, how to change web.config etc etc we have tons of articles on how to customize your deployment. You can look at a whole list of them at Overview of Web Deployment

Hope this helps

Vishal

111 comments:

Jon said...

Thank you! This is indeed massively overdue, but at least it's here. I do wonder though, why does TFS have no built in support for configuring web publishing? Why do we have to do everything through custom msbuild parameters and undocumented targets like this instead of a nice interface like we get when publishing directly from VS2010? Web development is kinda important nowadays, but it seems like the TFS team never really considered it. Someone dropped the ball big time.

Jijo Venginikkadan said...

Very detailed....Thanks for sharing...

Pavel Chuchuva said...

Yes, please describe steps for IIS6.

Unknown said...

Its excellent.Really i loved read this blog.Its highly informative. I would be visiting your blog hereafter regularly to gather valuable information.You can also find interesting stuf here Website Development.

Unknown said...

Yeah the steps for IIS6 would be most excellent.

Unknown said...

Detailed one.I have a requirment of publishing the web site at every night in remote server.so, the MSBuild arguments set accordingly and the publish is ok, however,I want some files such as web.config,other files to be intact each time the publish happens.how can I instruct the Build not to overwrite certain files at remote server. your reply will greatly help me.

Sayed Ibrahim Hashimi said...

@NetGuy in order to do this you need to extend your build/package process. To do this create a file in the same directory as your project file with the name {ProjectName}.wpp.targets, where {ProjectName} is the name of your project. Inside that file place the contents I have at http://pastebin.com/3au0uB3v. I couldn't paste XML here otherwise I would have put it here.

Anonymous said...

Hi Sayed Hashmim,

Thanks for your reply and sorry for the delay in my response to you. I have tried what you suggested, but unfortunatley it did not work. Here is how did I test:

1.MSBuild Arguments set at Build Defnition

/p:DeployOnBuild=True
/p:DeployTarget=MsDeployPublish
/p:MSDeployPublishMethod=RemoteAgent
/p:CreatePackageOnPublish=True
/p:DeployIisAppPath="Default Web Site/MyWeb"
/p:MsDeployServiceUrl=http://server/
/p:username=user
/p:password=pwd

2. Copy my web project file say myweb.csproj and rename it as myweb.wpp.targets.

3. open the new file and replace the content with the xml from your link

4.logon to the remote server and modify some key values in the existing web.config file

5. Run the build from TFS

6. check the web.config file in remote server and found it overwritten by the build

7. I ran the build two times one without adding the myweb.wpp.targets file into the project and the other with adding the file. both did not work.

Am I missing anything here? please respond how I can make this to work.Thanks.

Anonymous said...

Please post the instructions for web publishing in IIS 6. I've tried everything but cannot get it to work. Thanks.

Anonymous said...

TeamCity is so much better than this. Honestly, give up and just give up.

Anonymous said...

Web Applications - I have spend all day looking for a way to automate the "Publish --> File System" for my web services and I found this helpful:
http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

Thank you so much Daniel Chambers!!!

Anonymous said...

Any guidance for web publishing to IIS 6 would be greatly appreciated. Thanks.

Anonymous said...

Another vote for IIS6 instructions. Thanks.

Anonymous said...

What if my solution contains both a web application project and a WCF service application project?

Vishal R Joshi said...

Q. What if my solution contains both a web application project and a WCF service application project?
A. If your project contains both and you want the action to happen only for one of them then you have following options:
1.) Call the build separately on both projects?
2.) Call a solution build but actually edit project file of each project and set all the properties mentioned above as "/p" in the project file itself. That will automatically trigger the build in team build environment.

hope this helps
Vishal

Anonymous said...

Hi Vishal Joshi,Your post is very useful.The topics you covered are very important and useful.(Connect to TFS using Team Explorer,Create a new Build Definition,Configure your Trigger in TFS 2010 Build Definition). Interesting post!!

http://gloriatech.com/microsoft-net-development-services.aspx

Nootn said...

Hi Vishal, are you able to post how to get this working with IIS6? I did try by changing a few of the things here but could not get it working.
Cheers.

Anonymous said...

Hi Vishal, We were able to get the web deployment piece to work correctly. But we have another issues were have a team project that contains 1000's of PDF that are needed by the web site. SInce there is no solution is there a way to publish the files to the site using the build service?

Anonymous said...

I have been using Web Deploy to publish websites/applications as web applications. But is there a way by which I can publish the application to a new Website. I am able to publish it to an Existing WebSite in IIS. But is there a way in which Web Deploy could even create the WebSite if it does not exist in IIS. If the Virtual Directory does not exist it creates it. But can it do the same for a Web site too.

Each time I try something like that I get the error:

Web deployment task failed. (Site '' does not exist.)

Vishal R Joshi said...

Q. Re: Creating a new web site in IIS from Web Deploy.
A. Before answering your question, let me provide 3 conceptual clarifications which will help.
IIS --> You might be aware that IIS has two high level concepts "Web Site" and an "Application". By default root of a web site is also an IIS application (means it can get its own app pool and run in its own isolation).
VS --> Now, in VS your project by default is created as an IIS Application i.e. it is a sub app under "Default Web Site".
Web Deploy --> Web Deploy can transfer only same "type" objects from source to destination i.e. it can move an app to app, a site to an site but cannot move an app to a site. In above scenario since your project is an IIS App it is trying to look for a parent IIS Site for it. If your local app was set up as a separate site (i.e. peer of Default Web Site) then you should not get the error.
Hope this helps.
-Vishal

Anonymous said...

Thanks for the clarification.But I am not sure how to do the stuff you mentioned:
"If your local app was set up as a separate site (i.e. peer of Default Web Site) then you should not get the error." You meant create a web site project?
I know to create an export (server) package from IIS. And then use in on another server. But doing it right inside the Visual Studio, I am not sure how. Can you please guide me on this?
If I use a Web Application project, it always mandates me to have a Virtual Directory which is very reasonable. But how do I do that with a web site project. I can see on Scott Gu's blog that Web Deploy is not yet supported for Web Site project in VS.
Is there a way by which I should be able to create a deployment package from Visual Studio which can be deployed on to a server.
The package should be able to create a web site if it does not exist.

Vishal R Joshi said...

Q. If I use a Web Application project, it always mandates me to have a Virtual Directory which is very reasonable. But how do I do that with a web site project.
A. Hi Anonymous :-), Can you clarify whether you are using Web Application Projects (WAP) or Web Site Projects(WSP). If you are using WAP then you can go to VS Project --> Properties and change your IIS url of the project to something like http://localhost:8122 where 8122 is your IIS Site ID. After this when you package it will automatically create a web site package. If you are using Web Site project you will have to download and use Web Deployment Project to get the packaging functionality.
Although once you clarify the project type then we can discuss more.
thanks
Vishal

suhas said...

vishal,
thanks for this usefull Article..,
good work

Unknown said...

Great post, much appreciated!

I have an issue; I am building a solution that contains multiple build configurations (QA, Production, Debug, etc...) and every time the build occurs the project is deployed to the server replacing the previous (QA is deployed, Production is deployed overwriting QA, etc...).

I include the following MSBuild argument: /p:DeployIisAppPath="Default Web Site/WebApplication1" and the web deployment occurs, but exhibits the behavior noted. If I remove this argument then the web deployment does not occur.

I would like to have the ability to deploy a specified build configuration, or even better would be to deploy all build configurations as long as the the IisAppPath value is obtained from each build configuration's project setting. I thought excluding /p:DeployIisAppPath would do that, but it does not; prevents the deploy from occurring.

Any ideas? Thanks

Vishal R Joshi said...

Hi Sean,
I am actually a tiny bit confused why such a behavior might be happening. Was your QA site already deployed at the same location? If so then the behavior is expected. You can set properties that you are passing in MsBuild within the project file itself (i.e. unload project by right clicking it, edit project file and set the properties there) in that situation you will not have to pass the properties in build definition.
If you can send your entire command line being used in an email at Vishal.Joshi@Microsoft.com then I can try to investigate it a little more and provide you with feedback.
Thanks
Vishal

Felix said...

Hi Vishal,

The Anonymous person above has a question about using Web Deploy with Web Site Projects. I have a classic asp site (and static HTML pages) that is configured as a Web Site Project. I also downloaded the Web Deployment Projects for VS2010. I'm trying to create a TFS Build script now that builds the Web Site Project AND creates a package. However, when I add the parameters the MSBuildArugments:
/p:DeployOnBuild=True /p:CreatePackageOnPublish=True
I can't get it to build an actual Web Deploy package.

It seems that everywhere I've searched references WAP with Web Deploy, but I can't find any documentation on WSP+WDP with Web Deploy. I also can't find any documentation on building .NET 3.5 apps (with environment web.config swapping).

Any ideas or suggestions on why the WSP+WDP might not be creating a package when built with TFS?

Thanks and great articles!
Felix

Tar's Arena said...

what to do if your solution contains more than one site? how can we configure for each website?

David Nelson said...

I am trying to set up my web application to build and package from TFS; deployment will be a separate step. I have spent the last two days researching Web Deploy and packaging, and have been making very slow progress; your blog has been very helpful, but Web Deploy desparately needs comprehensive documentation and scenario samples, not just "happy path" walkthroughs.

That said, I think I am making some headway, and hope to have a working build sometime next week. One thing that I have not been able to figure out though is how to change the "path" that gets generated by msbuild in the SourceMainfest.xml and archive.xml files. This path is set to the full path of the source folder of the build (which, given that it is just a placeholder and will never actually be used as a path, seems to be a very strange choice). This path then shows up when importing the package using IIS, and is very confusing for web server admins who think that the site will actually be copied into that path.

In Scott Hanselman's MIX talk (http://www.hanselman.com/blog/WebDeploymentMadeAwesomeIfYoureUsingXCopyYoureDoingItWrong.aspx), he shows how to import dasBlog in IIS, and it did not have the same scary path; instead it just showed "dasBlogce". This is what I want to do, but dasBlog had a custom and static package, whereas I also want to be able to take advantage of Visual Studio to build my package for me. How can I accomplish this?

Vishal R Joshi said...

Q. David said: A long path shows up when importing the package using IIS, and is very confusing for web server admins who think that the site will actually be copied into that path.
A. As you can imagine your web project contains .aspx.cs files which get compiled to .dll in your /bin folder. If you hit F4 on any file within your solution explorer you should get property grid which sets "Build Action" of each file. If it is set to compile it should not be included in your deployed destination otherwise it will create conflict with classes defined in your .dll file. To avoid VS copies the actually output to temporary package location and that is given as the source in the source manifest as well as to Web Deploy.
As Web Deploy works on provider model each provider captures its source location and destination locations. The source location goes to Source Manifest and within the .zip file to Archive XML. You do not need to share Source Manifest file with the IT Admins except for logging purposes. The Archive XML which is inside the .zip file is really the implementation detail of way Web Deploy keeps reference checks and passes controls to the correct provider. Trying to overwrite that will result into incorrect behavior.
Now it is a very valid point that this path should not show when importing package using IIS. I think if you go to your Package/Publish Web tab within web project property pages in VS 2010 then you can set Physical location over there. Once you set this then that value is what should ideally show up in your IIS UI. Can you please check that and confirm.
Thanks
Vishal

Vishal R Joshi said...

Q. Tar asked: what to do if your solution contains more than one site? how can we configure for each website?
A. Tar in this situation you can set all the properties mentioned in Step 10 of the walkthrough in the project file(csproj/vbproj) of your web project. Then you can have deployment for each web project when you pass solution file to team build definition.
The key setting is DeployOnBuild should be set to true for each project then the magic will happen.
Thanks
Vishal

Vishal R Joshi said...

Q. Felix asked: Any ideas or suggestions on why the WSP+WDP might not be creating a package when built with TFS?
A. Felix, as you might already know in case of WSP you have to actually have WDP build in TFS. WDP has a wdproj file which is also an MSBuild file just like csproj or vbproj. For WDP all the standard Web Publishing Pipeline (WPP) events have been hooked up just like WAP .csproj or .vbproj file. What this means is that you should be able to pass all the properties used by WAP to WPP via commandline as simply as /t:Package /p:Configuration=Release /p:DeployOnBuild=True etc.
Also a trick to remember is that you can take a WAP project, use its property pages (Package/Publish Web & Package/Publish SQL) to edit its settings. You can then unload the WAP project open the .csproj file in XML editor and copy all the settings from there and simply paste them in WDP project file. They all should work. So in a way Web Sites can get most of functionality that WAPs have but by some manual tweaks.
If you still have more questions do not hesitate to write back to me at Vishal.Joshi@Microsoft.com
Thanks
Vishal

Anonymous said...

When deploying to IIS6 from TFS 2010 the build does not copy to the remote server share even though full permission to everyone exist to the share. What is missing here? Does it have to do with this "remote location will need permission to be writable by Team Build Agent" What is the default account Team Build Agent runs under? Please any help would be appreciated.

Vishal R Joshi said...

I think the Team Build Agent runs under Network Service, but am not 100% can you try that.
thx
Vishal

Timm Krause said...

Hi.

The more I read, the more this topic confuses me.

Take a look at here:

http://blogs.blackmarble.co.uk/blogs/rfennell/archive/2010/08/06/running-msdeploy-to-a-remote-box-from-inside-a-tfs-2010-build.aspx

http://blogs.blackmarble.co.uk/blogs/rfennell/archive/2010/08/13/running-msdeploy-to-a-remote-box-from-inside-a-tfs-2010-build-part-2.aspx

This guy writes about the same topic, but with less MSBuild arguments. Instead he modifies the build template to call the MSDeploy.exe with some parameters to deploy the web project.

I think your way is much more elegant but why has he gone this complicated way of deploying?

2nd question: Do your MSBuild argument invoke MSDeploy in the background?

Hope to get some feedback that lets me see light at the end of the tunnel.

Vishal R Joshi said...

Hi Timm,
Sorry about the confusion that you are facing. The black marble blog (Richard Fennell blog) uses different means of accomplishing the same thing and that is perfectly acceptable.
Here are some clarifications on different approaches.
* VS wraps msdeploy APIs into Msbuild tasks & targets which makes it easy to use them from team build. So short answer to your question is yes, VS does call MSdeploy in the background.
* VS generally has better understanding of your project then msdeploy commandline will ever have. This is because VS knows what files are content, what files are compiled in dll, what files are referenced etc. Due to this using VS MSBuild tasks and targets is preferable as it will eliminate .csproj, .sln, .suo, .cs, .vb etc files from your deployment as they are not required on the server.
* Team build has a way to customize your build using Workflow. Calling msbuild tasks created by VS via workflow approach still does the same thing so it not a problem chosing that if that is what you find simpler (2nd post by Richard Fennell does something similar)
* There are two basic concepts to remember "Package (aka offline)" and "Publish (aka online)". My flow above uses "Publish" this means that your code is taken from source control, it is built on TFS and it is directly moved to remote machine using MSdeployPublish msbuild target. The reason why I call this online is due to the fact that connection to the destination machine is required to do this operation.
* MSDeploy also allows you to do something I call as offline deployment. In this model you can create a .zip file (Package) out of your web and then take it in a USB drive to a different server and then use MSDeploy to install it there. To install the .zip package VS also produces an accompanying .cmd file, also the .zip package can be installed by using IIS Manager UI. As this option does not require direct connection between the source and destination machine, I call this offline deployment.
* Now in both of Richard'sblog posts he uses package model which produces .zip file and then he uses .cmd file to install the package. Since he calls .cmd file on Team Build machine itself giving it the /M switch and computer name it runs the cmd file and in a way "Publishes (aka online)" to remote machine.
* There is nothing wrong with that approach as well. Richard's approach produces the package and then publishes it. Above approach directly publishes it and in the process of publishing can produce a backup package (by passing /P=CreatePackageOnPublish=True)

So depending on your preference you can go in either direction, both will continue to work and are reasonably ok approaches. The reason why I did not document the other approaches is 1.) I did not find time to do so :-) 2.) coz based on discussions with different users and their scenarios, "publish" from TFS is what they seemed to be interested in more than "package and then publish the package".
Hope this helps.
Thx
Vishal

Timm Krause said...

Yes. Great.

Two things I would like to add:

1. The MSBuild way also deploys (publishes) even if some tests would fail, right? Fennell states this in his second post. Within the workflow method you will have the chance to ask for successfull tests.

2. In my opinion the MSBuild way is more flexible. You could edit the build definition you want for different machines or you are able to clone build definitions to modify them for different target machines (Test, Staging, Prod).
Within the workflow method you will always have to create new build process templates and modify these (too much work imho).

A workaround could be:

Some days ago I read something about custom arguments, this arguments will show up in "Process" tab within the build definition dialog. Maybe these self defined parameters could be used within the workflow to set some machine targets etc.

Anyway, for the first time I'll use the MSBuild way.

Thank you for making this clear to me! :)

(Your PDC 09 session about "Web Deployment Painkillers" was very interesting as well!)

Timm Krause said...

Two additional questions: I hope I'm not annoying you with this stuff.

1. Is there already a follow up for lower IIS versions -- I am not able to find one?
Would THIS be possible with invoking MSDeploy within the workflow?
Or is MSDeploy not compatible with IIS 6 in general?

2. For the future: With VS2010 and its GUI we are able to set up a One-Click deployment environment (via configuration manager) and with Web.config transforms it has become much more beautiful.

Why is it not possible to do this with MSBuild? /p:Configuration: /p:DeployOnBuild=True -- And that could/should be it. Period. All the configuration parameters and targets already EXIST and they're not bound to some limitations like "IIS 7 + Win2k8 or higher".

It don't understand why this isn't possible but I'm sure this is based on missing knowledge.

Hope to get in conversatin with you once again.

Vishal R Joshi said...

IIS6 related Instructions

For lower versions of IIS you will have to install MSDeploy Remote Agent service. You can learn more about isntallation of MSDeploy Remote Agent Service on the server by reading http://technet.microsoft.com/en-us/library/dd569059(WS.10).aspx

Once you have the Remote Agent service running on server machine then on team build you can pass /p:MSDeployPublishMethod=RemoteAgent and /p:MsDeployServiceUrl=

where you can replace with your actual installed URL on the server.

Finally while deploying using RemoteAgent you have to run your build with the credentials that are admin on the remote box. This is due to the fact that IIS6 does not have the delegation model which was introduced in IIS7 and later :-(

Vishal R Joshi said...

Hi Timm, your suggestions for the improvements in Team build environment are valid. Unfortunately getting msdeploy created, have it working within VS, having web.config transforms built etc etc took a lot of time during VS 2010 cycle. For the future we will certainly consider your feedback. Thanks much again.
-Vishal

Timm Krause said...

Wonderful.

Now one last question remains for me: What kind of provider does VS use if I do a manual publish via "Filesystem"? I am able to type in an url there: "http://mymachine/whatever/directory".
This seems to have nothing to do with MSDeploy or Remote Agent Service and is compatible through all IIS versions (I think).

Isn't it possible to use the same provider within an automated build process?

Unknown said...

For a build-and-deploy scenario, after building a solution that contains multiple build configurations (QA, Production, Debug, etc...) then deploying, all of the build configurations are deployed. This is a great thing but, what if I wish to only deploy one of the build configurations? Is there a way to do this via inserting custom settings within the .csproj file?

Any ideas, tips, samples would be much appreciated... thanks!

Vishal R Joshi said...

Hey Sean, All you have to do is to pass /p:Configuration=Production in the Team build environment. Your.csproj already should have configuration specific settings. Would that solve your problem?
thanks
Vishal

Vishal R Joshi said...

Hi Timm,
FileSystem publish does not use MsDeploy in anyway. It is glorified xCopy as it knows what files need to be excluded etc. The section on File System in the above post does exactly the same.

/p:DeployOnBuild=true /p:DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempRootDir=\\BuildServer\BuildDrops\MVCMusicStore /p:AutoParameterizationWebConfigConnectionStrings=false

Hope this helps
-Vishal

Unknown said...

Vishal,
I have added "/p:Configuration=[name of config]", and still all of the build configurations are deployed.

Here are my settings:
/p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:MSDeployPublishMethod=RemoteAgent /p:CreatePackageOnPublish=True /p:MsDeployServiceUrl=test.url.net /p:Username=SomeUsername /p:Password=SomePassword /p:Configuration=QA

Vishal R Joshi said...

Hi Sean,
Sorry for the confusion. In TFS 2010 when you go to editing your Build Definition there is a left tab called "Process". Inside that in 1. Required section there is "Items to Build" when you expand that there is "Configurations to Build". You will have to go there and provide the configurations that you would like to build as part of your daily build. This should fix your problem hopefully.
Thanks
Vishal

Unknown said...

What you are suggesting is to have multiple individual builds, which is not optimal. I would only like to have one build for all build configurations but only deploy one configuration.

Vishal R Joshi said...

Sean, in that case you can copy the properties like /p:DeployOnBuild=True inside the .csproj/.vbproj file directly and not pass those arguments into Team Build directly.
Thanks
Vishal

Unknown said...

Ok, how about this: I would like the .zip packages to be created but only one build configuration to actually auto-publish.

Vishal R Joshi said...

You should be able to do that too. You can edit configuration specific sections in project file. Set DeployOnBuild=True for all but change the configuration you want to have publish to have below properties
DeployOnBuild=True
DeployTarget=MsDeployPublish
CreatePackageOnPublish=True
MSDeployPublishMethod=InProc or RemoteAgent or WMSVC MSDeployServiceUrl=your URL
DeployIisAppPath="Default Web Site/NewOrleansJazz"
UserName=userName
Password=myPassword
Hope this helps.

Vercellone said...

I have a large solution with 11 Web Application Projects (WAPs). One of the WAP's serves as the root IIS web site content, whereas the remaining WAPs represent physical sub folders. I have been using a custom team foundation workflow activity to simply fixup the folder structure to my liking (including bin folder consolidation at the root) as a basis for xcopy deployment.

Instead I'd like to generate a single web deploy package. I have been able to successfully output 11 distinct packages to my drop location, but I would like to combine them into a single package.

Q: What is the best way to go about combining multiple WAPs into a single package?

Anonymous said...

Vishal,

Thanks for the great blog post! Very helpful!

I am having trouble with the File Copying commands for MsDeploy. I used the commands from your blog (and the comments above) – “/p:DeployOnBuild=true /p:DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempRootDir=\\vmdevweb01\TFSDeploy\collier /p:AutoParameterizationWebConfigConnectionStrings=false”. When doing so, there are no files copied to the location specified with the _PackageTempRootDir parameter. The build seems to work, but there are just no files copied to the _PackageTempRootDir location.

However, if I use this command – “/p:DeployOnBuild=True /p:Configuration=Debug /p:DeployTarget=Package /p:UseWPP_CopyWebApplication=True /p:PipelineDependsOnBuild=False /p:PackageLocation=\\vmdevweb01\TFSDeploy\collier\MyCompany.Web\MyCompany.Web_package.zip” – then I do get the web package files in the location specified by the PackageLocation parameter. So, this command seems to work.

My environment is VS2010, TFS2010, and an IIS6 web server (Win2k3). I do not want to deploy to the web server though. Right now I have a solution file with one web application project and multiple supporting class library projects.

My end goal is to have TeamBuild build the web app, apply the web config transformations, and copy the web package file to a network share. From there we can import/deploy the package into the appropriate server environments. My question to you is what is the right way to do this?

Vishal R Joshi said...

Hi Michael,
sorry for the delay in response. if the second command works for you then is there a reason why you would not want to use it?
Thanks
Vishal

Vishal R Joshi said...

Hi Vercellone,
Can you drop me an email at Vishal.Joshi@Microsoft.com I will connect you with a bunch of folks were we can discuss the best possible way to solve your problem.
thanks
Vishal

qntmfred said...

Hi Vishal
Very informative post. Here's a question for you

I have two solutions
SolutionA.sln
- WebApplication1.csproj

SolutionB.sln
- WebApplication1.csproj
- WebApplication2.csproj

I also have two build configurations
BuildConfigA
- should build SolutionA and deploy WebApplication1

BuildConfigB
- should build SolutionB and deploy WebApplication2 (but not WebApplication1)


To prevent BuildConfigB from trying to deploy WebApplication1, I put a false in WebApplication1.csproj. But that also prevents BuildConfigA from deploying it. How would you suggest accommodating this scenario? Thanks

Vishal R Joshi said...

Ken, In one of the build configurations you can pass the msbuild flag manually in MSBuild Properties section. That way only one build configuration will override the value. I am referring to the MSBuild arguments mentioned in Step 10 above.
Thanks
Vishal

qntmfred said...

Thanks Vishal. How do you specify which web application project in the solution the /p:DeployOnBuild=True applies to? It appears to be deploying both WebApplication2 and then overwriting WebApplication1 on top of it

Vishal R Joshi said...

Ken, you cannot specify which project it applies to but if you pass it in the solution which has only one project then it should work right?
The alternate option would be to create an msbuild file add it to the solution and inside it call the correct msbuild flags for each projects. I know that is slight overkill so I am hoping the previous option might work.
Thanks
Vishal

Anonymous said...

Hi,

can this be used for deploying Windows Forms application too ?
I am looking for deploying Form application on remote servers, from TFS build.
thanks,
Vijay

Vishal R Joshi said...

Hi Vijay,
Unfortunately out of the box it cannot be used to install Windows Forms Applications. Have you tried using ClickOnce for that?
There is certainly an option to extend Web Deploy to do so. If you are interested in that then drop me a line at Vishal.Joshi@Microsoft.com and I can connect you with members of our team who can help.
Thx
Vishal

Korls said...

Great article! What about FTP?

Vishal R Joshi said...

Hey Korls,
Unfortunately FTP is not a MsBuild task so it is not doable out of the box. Sorry about that.
-Vishal

M's blog said...

VS 2010 WAP+WDP simply config transformation is not working.

I created new solution with WAP, I added WDP, I changed config to release, in web.config in WAP I added customErrors section and set mode to off, in web.release.config I added releplace transformation from comments, and I'm trying to build deployment package on WDP, and results are:

WDP applies its own config transformations, it sets debug=false, but does not replace customErrors section, as it supposed to.


VS 2010 WebSite+WDP output was not merged to single assembly (side issue for now) the most important thing, config transformations were not applied.

please correct me if I got wrong impression. WDP should transform config files, when I click build deployment package, according to configuration settings. it should work out of the box, right? or we need do some magic stuff?

all actions were performed in VS IDE not on a build server.

WDP is very useful because I don't have to click through every page and compile aspx on server to check if markup will compile. so if new web deploy stuff won't work with WDP, this hole new stuff is useless... if your web app has 5 pages, you can try to click through them, if you have 500 pages... you get my point. I don't want to put on stage something that won't compile.

brad said...

I have one application that I need to deploy to 7 different QA sites that each have separate database connections, so that our testers each have their own isolated data environment to work in. I could create a build script for each one, but that seems like unnecessary overhead to get the source from TFS and compile 7 times when I really only need to do it once, and just deploy using 7 different web.config transforms.

Is this possible without heavily modifying the default build template?

Thanks.

Vishal R Joshi said...

Hi Brad,
To deploy to 7 different QA environments you can simply create a web package.zip. Next to the package should be deploy.cmd file and setParams.xml file. You can change the connectionString on the SetParams.xml file for each QA environment and then run the package. That feels like the simplest way to do this.
Hope this helps.
-Vishal

M's blog said...

Vishal, any comments on config transformations in WDP? more info in my previous post.

Maciej

brad said...

Vishal,

Thanks for the feedback. I have some great news: this is all available using the default template. I didn't notice this on my attempts before making the previous post, but after going setting up the build process again, I noticed it is possible to select multiple configurations to build by clicking on the ellipsis on "Items to Build", going to the "Configurations" tab, and then adding the 7 configurations. See the following screenshot:

http://i.imgur.com/Ty1qK.png

This is really cool stuff!

Vishal R Joshi said...

That is awesome Brad. I should had thought about this before, sorry did not occur to me. But I am glad that it works for you plus thanks for the comment, I am sure it will help other people too.
-Vishal

Andrey Nikiforov said...

Vishal,

I am packaging WAP using TFS2010. When deploying to dst server, I want to deploy it as a root of the specific site. If site does not exist, I want webdeploy to create it. If app pool does not exist, I want webdeploy to create it with specific settings. That way deploying package on new IIS or updating existing IIS should give same results.

How can I archive this? I assume enabling WAP "Include IIS settings as configured in IIS" setting in VS2010 is pointless, since I am not planning on setting IIS on TFS build server.

I looked at writing custom target in .wpp.targets file to add appHostConfig into SourceManifest.xml, but haven't succeeded with figuring out all needed parameters for appHostConfig.

Any guidance will be appreciated.
~Andrey

Anonymous said...

Vishal,

Other people have asked this question in one form or another, which is "is it possible to build once via TFS Team Build, but then deploy using different configurations?"

The answer you offered was to Sean's question: "What you are suggesting is to have multiple individual builds, which is not optimal. I would only like to have one build for all build configurations but only deploy one configuration."

was: "Sean, in that case you can copy the properties like /p:DeployOnBuild=True inside the .csproj/.vbproj file directly and not pass those arguments into Team Build directly."

So my question is, what is the build output of what Sean is proposing? If I have 2 different environments, a DEV server and a QA server, and I need to make sure my web.config transforms are replaced correctly, does that mean if I put BOTH configurations into the Items to Build -> Configurations to Build section of the build definition that I will end up with two separate builds, one ready for DEV and one ready for QA?

Thanks,
Mike

indiecodemonkey said...

For the FileSystem example above:
/p:DeployOnBuild=true /p:DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempRootDir=\\BuildServer\BuildDrops\MVCMusicStore /p:AutoParameterizationWebConfigConnectionStrings=false

What does this actually do? Just created to Package on the build server, or does it actually move the files to the server in your configuration?

Unknown said...

Great article!

Anonymous said...

Hello Vishal -

Thanks for your article, It really helps, I have a question.

When we use /p:DeployOnBuild=true , our package file does not have Bin folder which is mandatory for website, Is there any other option to include bin folder in the package?

Shaik

Shaik said...

Hello Vishal -

Thanks for your article, It really helps, I have a question.

When we use /p:DeployOnBuild=true , our package file does not have Bin folder which is mandatory for website, Is there any other option to include bin folder in the package?

Shaik

Vishal R Joshi said...

Hi Shaik,
/p:DeployOnBuild=True is just creating a package out of what is built and what is marked to be copied to the destination website. As part of the build the /bin folder should be generated and should get copied, it feels something unusaul is going on in your case.
Can you try to create a new MVC/Web Application Project and try to see if you can recreate this issue. If you are not able to reproduce the thing to look at might be what is build action of the files that are inside your /bin folder and compare them with what you see out of new MVC/Web App project. I think somewhere in the process that property might be altered.
JFYI: whether a file gets copied to destination location is driven by "Build Action" property of the file. You can access the property by right clicking the file and clicking "properties".
Hope this helps.
Vishal

Vishal R Joshi said...

Hi indiecodemonkey,
The Filesystem example does not create a package. The way it works is that MsBuild Target "PipelinePreDeployCopyAllFilesToOneFolder" is a pre-cursor to package or publish step. What we are doing here is asking the web publishing pipeline to simply stop at the point where the files are copied to a temporary location.
The web publishing pipeline usually creates the temp folder with all the files required and then packages them using web deploy or publishes them to remote destination. If you would rather simply copy the files and not go through the web deploy step then that is where you use this option.
If you are using this option then "_PackageTempRootDir" property can help determine where you want the files to be copied.
Hope this helps.
-Vishal

Vishal R Joshi said...

Hi Mike,
Re: Package Once and deploy multiple times. The drawback of the design today is that web.config transformation works as part of build workflow. The build workflow ends when web deploy package is created.
When you are deploying using web deploy package then the transformed web.config file is already in your package hence it is not easy to create the same package and deploy it multiple times using web.QA.config or web.dev.config etc. We are considering that feature and the way to accomplish it is by making "Web Deploy" have intrinsic knowledge of web.config transformation. Till we get that knowledge built inside Web Deploy people have to follow the workarounds. Sorry about that :-(
Now about the workaround itself. The bottom line is that we can produce two packages at the same time which contains identical bits but different web.configs. This can be done by building multiple configurations inside team build at the same time. In your build configuration definition there is a way to specify that.
Next about /p:DeployOnBuild=True property. This property is relatively simple, it just hooks up web publishing pipeline (which will apply web.config transforms and build your web deploy package) as a post build step. Team build will typically invoke build on your solution/project. Passing this property will allow the participating projects (aka MVC/Web Application Projects) to engage the web publishing pipeline. If you are building multiple configurations then the web publishing pipeline will be engaged for all of those configurations producing multiple web packages. If you are building on a nightly basis then producing multiple packages will happen behind the scenes and unless your configuration has got specific logic for different configurations the package output should be the same except for different web.config files.
Finally adding the DeployOnBuild=True in your project file as opposed to passing as arguments in your team build is merely reducing clutter in your build definition parameters and if your solution contains non MVC/Web Apps then keeping the property in the project where it applies just makes it cleaner. The design takes care that putting this property in the project file does not cause deployment to happen within VS, hence it should not create perf impact on daily basis. Although if you use commandline msbuild exe to build your projects then this property will be honored and in that case putting the property in the build definition inside of TFS makes more sense.
Hope this helps
Vishal

Srinivas Banda said...

Hi Vishal
Currently I am working on nightly build to deploy data base project into respective server and its working fine. But want to deploy whenever any changes happen in Schema that time I need to deploy into data base otherwise skip the deploy. Could please help me how can i restrict in Team build to verify schema change happens or not
Please help me to resolve the issue?

Vishal R Joshi said...

Hi Srinivas, for what you are looking you need to be able to compare your v1 DB with your v2 DB and generate schema diff SQL Scripts. Team build does not have the capability to this by itself. You can generate these diff scripts using TS Data projects available in Visual Studio or alternatively using tools like RedGate.
You will then have to configure these projects to build before your web project and consume the output of these in your web project deployment from the build server.
Please find links to these posts in the DB Section of http://vishaljoshi.blogspot.com/2009/09/overview-post-for-web-deployment-in-vs.html, in particularly reference the posts titled:
"Extending Web Publishing Pipeline (WPP) to package SQL files generated by TS Data Projects" AND
"How to use VS Database Projects (TS Data/Data Dude) with VS 2010 Web Deployment"
Hope this helps
-Vishal

Anonymous said...

Hello Vishal -

Thanks for your article, It really helps, I have a question.

i face some problem in web publishing configuration window .In my office has a domain and i am domain user.when i give my user name and password for web publishing ,it shown some authorization error.so i can't publish.So pls help me

Vishal R Joshi said...

Hi Anonymous,
You need to make sure that the server you are trying to deploy has Web Deploy delegation configured to allow you to publish. To being with try to set yourself as the admin on the server and test out if the publishing works. If it does then you know it is delegation rules which is the problem. If that is the case then check out Web Deploy IIS Remote Management delegation configuration. That should help out with the problem.
thx
Vishal

Team Building Providers said...

Thanks Vishal, this sort of stuff should publish time to time to spread the knowledge, i had a question similar as Anonymous said... now i find the answer.
Regards

sandhyabhavani said...

Hi Vishal,

After deployment if we run the application with those files while redirecting to other page it is getting error "HTTP 404 not found"
Actually my scenario is -In my shopping cart application once we adding products to cart and then click Checkout page it will redirect to other application(one more VirtualDirectory) login page.We have code like this also "~/Login.aspx?returnUrl=EditAddress.aspx"..still same error getting.please can you suggest me some idea.

Sabrina Veksler said...

Hi Vishal,

Thank you so much for the insightful article. I'm facing a bizarre situation where my MVC3 application deploys successfully when I manually run "Publish" using Web Deploy from Visual Studio, however the Publish does not work when triggered from one of my TFS Builds, even though I have tried every possible combination of settings in my MSBuild Arguments. Can you please provide some guidance on where to look for possible errors? There is nothing in my Event Viewer, and the logs in my build drop location all indicate Success! Yet the website in IIS remains not updated. I've searched the event viewer on the TFS Build machine, on the Deploy server and on the Dev server from where the build was initiated, all with no luck. If at least there was an error, maybe I'd know how to proceed! What am I supposed to be seeing in the Build Drop location? All that's in there are the log files, which tell me the build was successful.

Thank you so much,
-Sabrina

Doug H said...

Hi Vishal,
I set up TFS/TFS Build on one server, and Web Deploy on another IIS server as directed, but when I try to run a deploy to the IIS server, I get the following error during the deploy:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets (3588): Web deployment task failed.(Could not complete the request to remote agent URL 'https://IISServer:8172/MsDeploy.axd?site=SiteName'.) Could not complete the request to remote agent URL 'https://IISServer:8172/MsDeploy.axd?site=SiteName'. The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. The remote certificate is invalid according to the validation procedure.

I tried installing the certificate for the IIS Server into the Trusted Certification Authority store on the TFS server, but it still fails.

Any ideas what I might have done wrong here?

Thanks.

Vishal R Joshi said...

Hi Doug,
It feels like you need to pass AllowUntrustedCertificate=True as a property as well. You most likely do not have formally trusted cert (like verisign) etc on the IIS machine and it will give this error in that case.
thx
Vishal

Vishal R Joshi said...

Hi Sabrina,
In the TFS build logs do you see msdeploy references anywhere? If not then probably publish may not be even happening. Are you setting deployOnBuild=True?
What are the exact set of parameters you are passing in team build. If you can share those then we can probably troubleshoot.
thx
Vishal

Sabrina Veksler said...

Hi Vishal,

Thanks for the reply. There are no MSDeploy references anywhere in my build logs. I've pasted the contents of my latest build log below, for your information. Please note that due to the way my project is structured, only the build configuration Debug|.NET seems to result in a successful build. This is because my main project has a project reference to a project outside of its own TFS branch, and when I use the default configuration, it tries to find the assembly reference in a weird path that never gets resolved - something like this: C:\Builds\1\AwesomeSuite\Copy of CI Dev Build\Sources\Godzilla-Main\..\..\Annalect.Common\Annalect.Common-Main\Annalect.Common\Annalect.Common.csproj

I've tried playing with the Workspace settings to manipulate where the Annalect.Common project is dumped on the build server, but because of the way the project reference is structured in my main project's csproj file, it always attempts to use relative paths to find that other assembly. Perhaps you can recommend a better way of building projects that have dependencies on projects in other TFS branches. "Annalect.Common" and "AwesomeSuite" are siblings under our site collection.

MSBuild Arguments: /p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True /p:MsDeployPublishMethod=WMSVC /p:MsDeployServiceUrl=https://anlctwebdev1.global.com:8172/MsDeploy.axd /p:DeployIisAppPath=tools.annalect.com/Scenario /p:Username=GLOBAL\service.tfsproxy /p:Password=[password]
MSBuild Platform: X86

Here is the contents of my latest Build log:
Build started 3/12/2012 3:54:42 PM.
Project "C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln" on node 1 (default targets).
C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln.metaproj : warning MSB4126: The specified solution configuration "Debug|.NET" is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties blank to use the default solution configuration. [C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln]
Done Building Project "C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln" (default targets).

Build succeeded.

"C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln" (default target) (1) ->
(ValidateSolutionConfiguration target) ->
C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln.metaproj : warning MSB4126: The specified solution configuration "Debug|.NET" is invalid. Please specify a valid solution configuration using the Configuration and Platform properties (e.g. MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") or leave those properties blank to use the default solution configuration. [C:\Builds\1\AwesomeSuite\CI Dev Build\Sources\Godzilla-Main\Godzilla.sln]

1 Warning(s)
0 Error(s)

Time Elapsed 00:00:00.15

Thank you again,
-Sabrina

Eric said...

how do i deploy to multiple locations? i'm using the MSDeployPublish method mentioned in this article. i'm deploying to a MSDeployServiceUrl, but basically i want to deploy to two different urls (actually two different machines in a farm).

Vishal R Joshi said...

Unfortunately Eric, you either have to run Publish twice either via a new build definition or custom msbuild command.

Jeremy said...

How do i specify the -UseCheckSum flag with Team Build. I can always specify it from the package level with cmd deploy but when i go the ui or when i deploy using msbuild then i get all files deployed. It's because with team build the build machine's time stamps are different. I have a large package and a web cluster to sync across. I'd rather not deploy my whole package every time. Can i specify this flag from the UI of the IIS deploy? Can i specify it on Msbuild somehow?

Anonymous said...

I has IIS-6 internally. Can you please post the steps how to BUILD and Configure.

Anonymous said...

Was anyone ever successful in creating a deployment package with the web.configs transformation happening in the packaged zip file. I have manged to get the transformation to be working in _PublishedWebsites folder and TempBuildDir also packagetmp but on TFS server the package is created before the transformation.

tried everything that I could. I dont want to give up but not sure what else to do.

Anyone ever successsful in doing it?

Thanks

Vishal R Joshi said...

The package actually contains tokenized connectionStrings so that you can replace them while deploying. Along with the package.zip file should also see setParameters.xml file which is where you can change connectionStrings on the fly. If you do not want that behavior then there should be a property to turn off auto connection string parameterization in package which can be found in the msbuild C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets
Hope this helps.
-Vishal

Anonymous said...

Thanks Vishal for responding. The setparameters xml contains the original development config settings.

The issue is that in the log files on my local it creates package after Web config transformation but on the TFS it is doing transformation after Package is created. I am using this in my deployment package :















$(AfterBuildDependsOn);$(PrepareForRunDependsOn)



Anonymous said...

Thanks Vishal for responding. The setparameters xml contains the original development config settings.

The issue is that in the log files on my local it creates package after Web config transformation but on the TFS it is doing transformation after Package is created. I am using this in my deployment package :















$(AfterBuildDependsOn);$(PrepareForRunDependsOn)



jessica john said...

Very important, comprehensive and effective information you shared with us and no doubt it is necessary for every firm to build an awesome team of professionals then the firm can get benefits and achieve the goals.

BieNor said...

If you install Web Deploy 3 by using the Windows UI, the Web Deploy remote service will listen on http://+:80/MsDeployAgentService/.

http://technet.microsoft.com/en-us/library/dd569059(v=ws.10).aspx

Corporate team building said...

The post is sharing team building for web deployment. Good post

web development team said...

A good approach to web development and a nice step wise guide to introduce well the whole process. There are now more things to consider while building a normal site.

Anonymous said...

Vishal,

I am using Default template as well as BRDLite template to deploy our WCF services. We have Multiple services projects in a single solution, and I would like to deploy each service to its own Virtual Directory where the directory name should be the project Name.

In BRDLite I tried to get the project name from Run MS Build step, from foreach project in BuildSettings.ProjectsToBuild. But the virtual directory created was with the name of my solution and all the services are deployed to the same directory one after another, so I end up with only one service in the virtual directory.

Any ideas how to get project names and deploy each service to it's own virtual directory.

Vintage Furniture said...

This is really an interesting piece of information here on your website. Keep up the good work and continue providing us more quality information from time to time.

Anonymous said...

Hi Vishal,

I created a new web site named Ex:- "DEV-branch-brach1" in vs.net 2010 and could successfully able to do Continuous Integration (CI). When i connected to my Build server and see the drop folder I could see my successfull builds files as soon as i check-in my changes. The folder herirachy is given below

DEV-branch-brach1_20130605.8
_PublishedWebsites
DEV-branch-branch1
"Account" Folder
"bin" Folder
"Scripts" Folder
"Styles" Folder
About.aspx
Default.aspx
PrecompiledApp
Site.master
Web.config
logs
DEV-branch-brach1.log


Now i am planning to do automatic deployment of my website to my dev server.

I also started "Web Deployment Agent Service"
and "Web Management Service" and they are currently running and i made them to run automatic. I stopped my IIS. I followed the below article and could set the "Enable remote connections" in my "Management Service" of IIS of "DEV Server". I started my "IIS".

http://blogs.msdn.com/b/webdev/archive/2009/06/05/basic-microsoft-web-deployment-tool-setup-for-visual-studio-2010.aspx

Build options in my local VS.NET 2010 TFS build "DEV-branch-brach1" are as follows:-
_________________________
/p:DeployOnBuild=True
/p:DeployTarget=MsDeployPublish
/p:CreatePackageOnPublish=True
/p:MSDeployPublishMethod=WMSVC
/p:MSDeployServiceUrl=http://:8172/MSDeploy.axd
/p:DeployIisAppPath="VZWEUSApps/DEV-branch-branch1"
/p:UserName=
/p:Password=


I tried below way too (/p:MSDeployPublishMethod=RemoteAgent):-
__________________________________________
/p:DeployOnBuild=True
/p:DeployTarget=MsDeployPublish
/p:CreatePackageOnPublish=True
/p:MSDeployPublishMethod=RemoteAgent
/p:MSDeployServiceUrl=http://:8172/MSDeploy.axd
/p:DeployIisAppPath="VZWEUSApps/DEV-branch-branch1"
/p:UserName=
/p:Password=

I created a "Add Application" in "Dev Server". See the below herirachy of my IIS

IIS Root
Application Pools
Sites
Defalut WebSite
Custom Web Site
DEV-branch-brach1 (This is my web site whcih added as application)

I did not see any errors in event log as well as "%SystemDrive%\Inetpub\logs\WMSvc" But even though my CI builds are successfull, i can not see my new changes in my IIS Website.Could you tell me what, i am missing or what i did wrong?

Note:-
_______
Both my "Web Deployment Agent Service" and "Web Management Services are running all the time.

Vishal R Joshi said...

Do take a look at the documentation at:

http://www.asp.net/mvc/tutorials/deployment/visual-studio-web-deployment/command-line-deployment.

AK said...

Hi,

I want execute the db scripts along with the deployment. Can you please elaborate that process or provide me some pointers.

Thanks
AK

Sayed Ibrahim Hashimi said...

Hi Ak, if you are using VS2010 and need to execute scripts during publish you can configure those on the Packge/Publish SQL tab for the project in VS. Please make sure to configure the setting under the correct build configuration(s).

Anonymous said...

Its possible to deploy site from TFS to ftp location.

If possible then can you explain.

Anonymous said...

Its possible to deploy site from TFS to ftp location.

If possible then can you explain.

Anonymous said...

Its possible to deploy site from TFS to ftp location.

If possible then can you explain.

Anonymous said...

Its possible to deploy site from TFS to ftp location.

If possible then can you explain.

Anonymous said...

Its possible to deploy site from TFS to ftp location.

If possible then can you explain.

Anonymous said...

hi , i am using vs2012 and tfs ,i want to trigger build one automatic and one is manual

when autmoatic build is triggered, i found error

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets (4253): The 'MyProject-Web.config Connection String' argument cannot be null or empty.