I would like to hear the best practices or know how people perform the following task in TFS 2008.
I am intending on using TFS for building and storing web applications projects. Sometimes these projects can contain 100's of files (*.cs, *.acsx etc)
During the lifetime of the website, a small bug will get raised resulting in say a stylesheet change, and a change to default.aspx.cs for example.
On checking in these changes to TFS, and automated build would be triggered (great!), however for deploying the changes to the target production machine, I only need to deploy for example:
style.css
default.asx
MyWebApplications.dll
So my question is, can MSBuild be customized to generate a "code pack" of only the files which require deploying to the production server based on the changeset which cause the re-build?
You are probably going to have a hard time getting MSBuild itself to do this, but the ideal tool to use in your situation is the Web Deployment Tool, aka MSDeploy. With this tool you can tell it to deploy the changes to the target website. It will determine only the changed files and then just deploy those. Also you can perform customization to the deployment and a whole bunch of other stuff. It's a really great tool.
Related
I'm starting to dive into TFS 2012 and I have a basic understanding of the tiers and how build servers, controllers and agents work and how different build scripts can have different configurations and projects.
However, one of the things I'm struggling with is a requirement for our source control solution that says that I need to be able to prove a particular changeset or shelfset produced a particular build. That is, given a particular binary, I can point to a release changeset that generated that binary. I should also be able to point to the test changeset that was merged into the release branch. The idea here is not just a separation of duty, but validating that because the release and test changesets are identical, no code was injected into a project by a code reviewer.
I've read one blog post that talks about "Binary promotions" -- would that concept be useful in my situation? I'm having a hard time finding how this binary promotion is set up in TFS.
Deployment
Out of the box TFS doesn't really support deployments, it can deploy to 1 location on build which often is a test server (think lab management). TFS 2012 has built in support for Azure deployments, but they still happen at the end of a build and the build artifacts cannot be automatically deployed to a new location.
You could modify the build template to allow to release to different locations, but that would still be a fresh build for every environment and not true binary promotions.
TFS does, however, have a concept of build quality and actually fires off events when this quality is changed. TFS Deployer is a 3rd party tool that hooks into the quality change event and can execute powershell scripts. This means with a simple change of a dropdown value you can automatically kickoff a script that releases to any environment you want. You can customize the build quality list (per team collection) to be a list of environments (dev, uat, staging, production etc) which the script then figures out where to release the specific build to.
VS2012 also has some nice improvements to web deploy which means deployment configurations are stored in source control with the project, which in theory means they'll be available in the drop folder for TFS Deployer to make use of.
I don't believe TFS keeps a history of build qualities, which means you can't really use the build quality history to maintain a list of what is deployed to which environment. You could fairly easily record this information as part of the deployment script though. Or at the very least add a custom summary node to the build with information about the release.
TFS2012 does have the ability to mark a build as deployed as part of the Azure deployment functionality, you mark tfs deployer builds as deployed using a script but it doesn't feel very useful.
Octopus Deploy is another project that's worth checking out, and could be used instead of TFS Deployer if your build template creates NuGet packages. It requires a bit more control over the production hardware as you need to install agents on each environment to handle releases, but it solves a lot of other issues with deployment.
Versioning
Once you have a nice consistent way of automatically releasing that people don't bypass, you can look at enhancing the build template to inject the build version, or changeset number as the assembly version for anything built as part of that automated build. There's a number of different ways to do it and plenty of blog posts and tools to help you achieve that.
Alternatively you could just use automatic assembly versioning ([assembly: AssemblyVersion("1.0.*")]) to give you the date/time the build occurred, which ends up like 1.0.1234.123 where 1234 is something like the days since jan 1st 2000, and 123 is the minutes since midnight (my specifics may be wrong here).
If you're deploying websites, then I highly recommend injecting the current build version into the html somewhere. This way you can check what version a website is running without needing access to the bin directory. It can also be appended as a querystring to css/js file imports to ensure no browser caching occurs between versions.
Thoughts
Personally I'm hoping Microsoft realise that the xaml build workflows are trying to do too much and that they split the different concerns (build, test, deployment...) into different scriptable parts. Of course that would not be until the next major release of TFS which is years away. Although with Team Foundation Service they are trying to iterate a lot quicker, so they may actually extend the Azure deployment stuff into something more useful in the nearer future.
So, we're using continuous integration in our current Team Foundation Server 2010 setup, and so far it's working great. We're doing shelvesets, the build is running on the Build Manager in TFS, and it's also running our MSTest unit tests for us.
My question is, and I can't seem to find any information on this, is how to move the "build unit" that is created by the Build Manager on TFS to another server?
Aka, how do I "promote" this build to our QA, staging, etc... environments?
Before, we've were using VS2010's Publish Web feature, which allows us to set up publish "profiles", and each profile can have a different web.config related to it. This is really useful for anything we keep in our config files, like db connection strings, paths to app servers, etc... changing automatically based on our Publish Profile. We choose the profile, build locally, then use the "Publish" button to move the entire app to another server.
This setup worked great for when there were two of us working, and we were using TFS for just its source repository, but now the builds are happening on the TFS server.
What I'm looking for is a way for when TFS does the build for us (it's no longer being done locally on our machine, but by TFS Build Manager) to:
take into account which "publish profile" to use. This will effect what web.config is used and other items you can associate with a profile in your IDE.
once the build is created, to find a way to "push" the build to one of our other servers (QA, Staging, production) FROM TFS.
I don't even know if that is possible or not. Maybe it's still a manual job to take the build created on TFS, and copy it over by hand, and unzip the project/files into the correct file path on the deployed server? Or maybe it's part of the workflow in TFS, and I still have yet to find it.
This is surely possible already from TFS. Read the posts from Vishal Joshi on this topic, starting with: http://vishaljoshi.blogspot.com/2011/07/documenting-key-end-to-end-deployment.html
The solution I came up with is I wrote my own build handler for TFS, and use that code to push builds to our different environments. Here is the link I used to help me: http://geekswithblogs.net/jakob/archive/2010/10/27/devleoping-and-debugging-server-side-event-handlers-in-tfs-2010.aspx.
If anyone wants more specifics, just contact me and I'll be glad to help you.
I apologize for the length of this post but I needed to include a lot of information for proper answers. I hope this does not discourage responses...
Our shop historically has coded web sites using Classic ASP with some newer ASP.NET sites configured as web sites. As everyone knows this means that the source files (*.asp, *.aspx, and *.aspx.vb (or *.aspx.cs)) files are deployed to development and production servers as is.
The configuration management process was (and still is) entirely manual and includes the following steps (requirements):
Taking copies of the modified files and storing them in a "release" folder for archiving.
Taking copies of the production files that will be replaced and storing them in a "archive" folder for easier rollback.
Generating a diff report of before and after source files for code review or general reference when diagnosing a post-release issue.
The developer who coded the changes is not the person who performs the production release. The original developer is required to hand off the source files to another developer for some additional testing and production deployment.
To make the situation more difficult (not with the above..but with what I talk about below) we do not follow a formal release schedule. As individual bugs or enhancements are completed they are released. This means we could easily be making several releases to a site a week. It is even possible that a given site gets two different releases to individual pages on the same day!
Since I came on board I have been trying to transition the team to newer technologies like ASP.NET web applications and ASP.NET MVC. (We have also taken on responsibility for stand-alone applications and console utilities used for non-web processes...so my dilemma still applies.)
The difference between these technologies and the legacy technologies is the pre-compiling. Instead of deploying the code-behind files (*.aspx.vb (or *.aspx.cs)) a dll or exe gets deployed. This type of deployment package has raised several questions (issues ??).
Generating difference reports when the source has been compiled. While the newly modified source files are sitting on the developers system the production copy is a compiled copy.
Making sure that changes related to other bugs or enhancements are not included in the particular release. This would apply to both the original developer and the person performing the release.
Allowing the original developer to pass along the changed files to another developer for build, testing, and deployment.
Up to now I was the only developer on the team working on these types of sites and applications so the conflicts and issues mentioned above where non-existent. (I skip the difference report step and the I do my own deployments.) However, I am trying to push the rest of the team to embrace this plus allow for better distribution of bugs and enhancement tasks.
We are currently using VSS but I am pushing (and will most likely succeed) in getting us moved over to TFS. Some ideas I have are
Setting up a separate build system for use by the developer to do the deployment. This will solve two problems -- (1) Different versions/patches of Visual Studio and other libraries between developers and (2) instances where the person performing the release has checked out files locally for another change. (Of course this does not guarantee differences between the build system and the original developer but at least that means the release is from a consistent config.
Using labels to tag just the modified files. My problem is that while I can identify (and pull down for a build) the modified files, how do I identify the files that need to be included in the build but have not changed. Again, the idea is to not included checked in files that are related to un-released changes.
Using labels to tag all the files for the release (the modified files and the unchanged files). My problem with this is similar to the last one...how do I make sure that a file checked in by another developer (say they went on vacation) for an un-related change is not labelled and included in this build.
Using the labels I could probably write a script to generate difference reports for the labeled version and the previously labeled version. If the process works properly that should result in exactly what changes are included in the the particular release..?
Any other ideas, concerns, points of interest? While I do have some flexibility of the process some of the requirements (like difference report or some way to easily view differences and having separate developer/deployer) are most likely untouchable.
Thank you so much for any help you can provide on this.
To keep track of different versions of the code and to help you manage very fast release cycles (daily) vs long term enhancements you can use branches in TFS.
There is a ton of information out there on branching, but in general I like to try to keep things simple. For example, have one branch called "release" and another "development". Everybody works on the development branch but the code to be deployed to production is merged into the release branch right before release.
This blog post describes the process:
http://team-foundation-server.blogspot.com/2008/01/how-we-branch-our-code-in-tfs.html
Well, based on my experience with VS2003 vs VS2010 for example is that the project structures are different and allowing VS to do a conversion often times results in a solution that either requires a lot of refactoring or is unusable. Having said that; if you can transition everything over to TFS2010 then one way to handle it is to setup different projects for each solution and use the TFS built in version handling for the different releases. You can also set up a build server and schedule nightly builds. If the build is ok then you can push this version into testing and ultimately production. You should really read up on TFS because it's totally different from VSS and is definitely a huge upgrade in allowing you to do team-focused development.
P.S. TFS has a really good Sharepoint integration which will help you and your team keep track of all the bugs and tasks.
I'm currently working on integrating the TFS source control system at my work ... I run into one small problem ... I need different version of web.config (among other config files) for different branches (due to the environment that we're releasing the web application to).
(for example - i don't want to merge the web.config file all the time even though there are differences ...)
Is there a good way to keep track of that (instead of manually diff-ing the files)?
thanks!
What I have seen so far is that people write installers that manipulate the settings that are needed. So you don't have to bother with other environments than the development environment. Also because in some companies the people in development aren't allowed knowledge of all the settings in the production environment.
I haven't used it myself but know/knew of people using web.config transformations. That might be an option for you.
Web Deployment: Web.Config Transformation
Visual Studio Web Config Transformations and TFS Build
This seems like it should be obvious so maybe I am not understanding something. I have TFS setup. My web apps code is in source control. I can check-in/out and create builds but I don't quite understand what the recommended method for publishing the code to the production environment is? I was looking for something like "publish release to web server" but can't find anything. I think my larger problem is that I can't find a good work-flow diagram for how a team is supposed to move from editing code to testing and then to deploying to the production servers all within the TFS system. If anyone has any thoughts or links to good walkthroughs on publishing a website from within TFS that would be fantastic.
For the workflow I would suggest the code promotion model.
Within TFS you have the idea of build quality. SO when you initially check code in the build will kick off with a quality of say "ready for test" if the build passes the testers can decide when they want to take a build for testing, when they have tested a build they can mark it as "ready for deployment", you can then use that realeas to deploy.
Unless things have changed in TFS 2010 you have to roll your own implementation for deployment. We used MS build to build MSIs using Wix, then had the testers test the deployment process for us.
Have a look at the following msbuild extensions to help with deploying to test/live environments:
http://msbuildtasks.tigris.org/
http://msbuildextensionpack.codeplex.com/
I would really recommend you spend a little time on your build process and get it water tight, there is nothing more embarrassing that deploying a release to live that doesn't work and the client loosing faith over it.
I don't believe there is a built-in mechanism in Team Build to publish websites, however this can be achieved by overriding AfterDropBuild or AfterEndToEndIteration in your build definition to include necessary tasks for copying the build output to your web servers.