I have 3 solutions in Team Foundation Server. Prod which is branched to QAS which is branched to DEV.
I do all of my work in the DEV branch and check in any changes to this branch and when I check this in I associate the ChangeSet with a Work Item in TFS. Let's say I have 4 ChangeSets (ChangeSet #101, 102, 103, 104) at this point each one is associated with a different bug (Bug #1, 2, 3, and 4).
I then deploy the DEV branch of the project out for internal testing. Once this has been verified I then merge the DEV branch into the QAS and then check all of these changes in as ChangeSet #104.
Now here is where I have a problem. After the external testing Bug 1 and 2 have been confirmed and are ready to get deployed to Prod, but bug 3 and 4 are not. If I go into the Prod branch and merge from QAS back into prod it will grab all of the changes from QAS and push them into the prod branch. But this is not what I want because it will give me the code that is in error for bugs 3 and 4. What I really want is to just grab the same changes that came from ChangeSet 101 and 102, but I can't say to just pull in those changes because those were from DEV to QAS, which all then became a single ChangeSet.
So my question is how to get the Environment/ChangeSet setup in a manner, so that I could bring over just the pieces that I want.
You really can't do this without invalidating QA's work. Generally, releases are all-or-nothing. Every time you change code, you invalidate all prior testing done. This can be mitigated by having unit and integration tests to provide some safeguards against regressions, but fundamentally any time the code changes, something unexpected can break. It's worse in poorly architected spaghetti systems, but it's a risk in even the best-designed system.
Let's say you release once a week. You fix 4 bugs in that timeframe and pass all of them off to QA.
QA is able to validate that 2 of the bugs are fixed. What happens if you remove the other 2 bugfixes that aren't validated?
Nothing. The bugs and the code changed is actually completely orthogonal. Whew.
The combination of Bugfix 1 and Bugfix 3 actually fixes Bug Omega, that you didn't even know existed. Removing Bugfix 3 introduces a different bug. QA won't catch it because as far as they're concerned they tested and everything was working.
If QA typically can't complete their testing for a release within the timespan allocated for the release, then you have a bottleneck somewhere that needs to be identified and removed.
Related
I have a situation where we were working on feature branches against a main development branch ('trunk') and each release cycle, a release branch would be taken from the current development branch.
However, a release was cancelled very late on and instead we were asked to issue the previous release with only some features - after these were all integrated into the main dev branch.
So what happened was the previous release branch was taken as the base of the new mini-release, and we now have to re-apply specific changes that were already made against the development branch. I luckily still have my feature branch and it was never merged. It is based on the development branch, however my branch was taken fairly early on in the release cycle and was not updated by re-merging parent (trunk) changes - so my branch's parent is actually not too dissimilar from the new branch I need to apply it to.
I know TFS has some facilities for re-parenting and baseless merges but what is likely to work best? More importantly if I try re-parenting, can I break my branch or am I safe that I can try things, back them out and try again if there are problems?
My branch is fairly large, maybe 50 changesets applied to quite a few separate modules. I suppose I could try to apply each changeset one-by-one instead?
In my experience, baseless merges are always terrible. In most cases I find diffing and merging the two branches manually via a compare tool (like BeyondCompare) is easier and more reliable than using the TFS tooling.
That being said I would challenge you to consider going to a single main branch. We made the leap (a huge leap for us at the time) but it has paid dividends many times over at this point. The key is being Release Ready:
https://dotnetcatch.com/2016/02/16/are-you-release-ready/
We are trying to implement the "Basic Dual Branch Plan" as described by the ALM Rangers in the latest Visual Studio TFS Branching and Merging Guide. From the guidance:
The basic branch plan with a MAIN, DEV, and RELEASE branch enables concurrent development for your next release, a stable MAIN branch for testing and a RELEASE branch for any ship blocking bug fixes. Multiple development areas are supported by creating additional development branches from MAIN. These are peers to each other and children of MAIN.
Additional releases are supported by creating release branches for each product release. Each release branch is a child of MAIN and a peer to each other (e.g. release 2.0 branch is peer to release 3.0 and both are children of MAIN). If supporting only a single release in production at a time, you may consider a single release branch, and make bug fixes directly on this branch. Once the RELEASE branch is created MAIN and the development branches can start taking changes approved for the next product release.
We are undecided as to whether we want to use a single Release branch (and label releases), or create a new release branch per release. However, there are some questions that apply either way, that don't seem to be addressed by the guidance.
My main question is: At what point in time should we create a RELEASE branch (or move tested code to the single RELEASE branch if that's the way we go)?
My first reaction was to create it only when ready to do the release, but then you have the problem of creating a deadlock for development and testing of the next sprint's work; you cannot check these changes into MAIN until the RELEASE branch has been created (if you do, it's more difficult to separate out the changes you only want to go to RELEASE).
Second idea is to create the RELEASE branch at the beginning of the sprint, and as changes pass testing in MAIN, merge them down to the current RELEASE branch. Once we reach the end of the sprint, we can lock that RELEASE branch down, and create a new one for the next sprint. This sounds like it would work, but I see no discussion of it anywhere, so I just wanted to see what people are doing.
I would give the same advice as Adarsh Shah in that 2 branches (MAIN, RELEASE) are sufficient in most cases, and using feature branches for things that you don't want to commit into MAIN immediately because it would take a while to be fully ready for testing. And by RELEASE I mean a branch per actual release.
Keep in mind though that, in theory, MAIN should in a release-ready state at any moment. This means using feature branches for a lot of small changes too and not merging things into MAIN as long as the feature is not considered ready. Now, this is something that you should experiment with and see what works best in your environment. If you find that it is too hard to keep MAIN into a release-ready state, by all means, create a separate DEV branch to commit the daily work. In my experience however, with some good guidelines, automated and manual testing you quickly can get into a flow where MAIN can be considered quite stable. I've worked in environments where we had a DEV branch which was highly unstable and a stable MAIN branch, and environments where we didn't have a DEV branch. Sometimes the DEV branch was needed, sometimes it became a burden to keep them in sync as both DEV and MAIN were fairly stable and essentially just a copy of each other.
Now, when should you create the release branch. It depends on the type of development you are doing. For small desktop projects or websites which have a fairly steady release cycle (a single release per sprint, for example) I find it easiest to create a release branch at the end of a sprint, and only pushing it to production the sprint after.
S1 - - S2 - - S3 - - S4 // Each sprint
\ R1 - \ R2 - \ R3 // Release branch created at the end of a sprint
\ P1 - \ P2 // Pushed to production at the start of the next sprint
So, at the end of S1 I create the release branch R1 from MAIN but it's not pushed to production just yet. During S2 both new features are implemented on MAIN and critical bugs are fixed on R1. If a fix on R1 is approved, it gets merged back into MAIN too, if it's required. At the end of S2, a new R2 is created, and R1 is pushed into production. I have found this approach to work quite well. You basically have a full sprint to work out the last issues in a release branch.
Of course, if a serious critical bug appears on production this bug gets priority above all else. An RXa, RXb, ... branch can then be created of the existing R-branch that's in production, implement the hot-fix and push that hot-fix into production. You can then consider whether it's needed to merge the changes from the hot-fix into your MAIN branch. Don't create a hot-fix on the MAIN branch and merge it down though, you'll find that it quickly becomes too complex because on MAIN a lot of the surrounding code might have already changed.
Here is what I would suggest:
1) Do all development on the Main branch until Code Complete. Code complete is the time when developers stop working on new features for that sprint but can fix regression bugs. Code complete can be few days before the release or up to a week based on how long is your sprint).
2) Create a new RELEASE branch from the MAIN at that point . Deploy the branch to QA/Staging environment to do a smoke test. After that point QA team will use RELEASE branch to do the testing for the release.
3) Developers can start working on the new features for next sprint at that point and start checking-in changes to MAIN branch. Any regression issues found during testing will be fixed in RELEASE branch first and then merged back to MAIN.
4) Any changes to code in RELEASE branch will then be pushed to QA/Staging for further testing.
5) One the Release is done any bug found in production will be fixed in RELEASE branch and hot-fixed to Prod and also merged back to MAIN.
No. 1 will be too late and no. 2 will be too early IMO.
I would suggest to create a new branch for every RELEASE and then get rid of old RELEASE branches periodically instead of using labels.
Also, I prefer having only 2 branches MAIN(which is also DEV) and RELEASE except any branch developers need to any specific feature/framework change etc. Under the root folder I usually create MAIN, RELEASES(all release branches) and BRANCHES(all branches specific to a feature/framework changes etc. but these are created only in special cases not always)
Using TFS, we have the following:
A main baseline
A development branch for each development effort. These get merged back to the baseline.
A release branch that is created with each release. Bug fixes are made here, released, and merged back to the baseline.
Using shelvesets, we can share code across development branches if needed without contaminating the baseline. Useful for code reviews.
When we deliver our development changes to baseline we have an automated build that kicks off and automatically places our changes on the test server.
The problem is that the business analysts can't see our changes until they're on the test server, and currently the only way to get our changes on the test server is to check them into baseline. So if the BA's find something wrong, the code is, unfortunately, already in baseline and we would have to go through the trouble of taking it back out.
Is there a way we can change our branching strategy or process to get the BA's what they want to see without contaminating our baseline?
Your branching strategy sounds exactly what we decided on at my company. I don't think the issue is with your branching strategy, I think the issue is that you have to check changes into the baseline in order to apply them to the test server.
At my company, changes aren't checked into the baseline until they are promoted and running in production. Release branches are what are deployed to the test servers... if bugs are found, or the BAs want to change something, we don't have to go through the pain of removing the changes from the baseline.
However, if you have a lot of concurrent releases, this can become a pain to merge all of the releases together before moving them to production, since you aren't merging into the baseline until later in the process. At my company, we have a very strict release schedule, and try to only have a single release working its way to production at a time. Because of this, waiting to merge the release into the baseline until the release has been promoted into production hasn't created any issues for us, or extra work so far...
How often do you do releases? Would you be able to deploy release branches onto your test servers, and have the baseline represent what is currently deployed in production?
(I'd make this a comment, but I'm still working on earning that privilege...)
I would not prefer this approach, I would suggest:
A main baseline which contains stabilized code. The code will be merged into this branch from respective release branch only after successful release.
A Release branch which gets created from Main for each release. This branch will be used to generate Release Builds and will be deployed to test environment.
A Development Branch created from Release Branch, it will be used for Development efforts and will be merged to Release when I'm ready to give my build to test.
Question:
What is the best practice for creating branches for development and release based on the information provided below?
Background:
I work in a small development team (2.25 frontend, 2 backend), and we have a yearly release schedule. Our environment does not allow for patches or services packs mid-year, but every once in a while if our user's environment changes we will release a "recompiled" version with a few bug fixes thrown in (on the current stable version).
Currently we do all of our development on the mainline and then create a branch (5 so far) for the code freeze and do minor bug fixes and the bulk of our testing. Once the version is sent out for layering and deployment we merge these bug fixes back to the mainline where we have continued to develop new functionality for next year's release. The branch stays in our repository forever.
The way TFS does its branches is by having a new "folder" in the source control, and it is starting to get a little cluttered.
Thoughts:
Maybe the way we are doing this is right, but it just feels like in a few more years there will be a large number of branches that are never going to be touched... seemingly ever. Maybe it is possible to create a single "Stable Release" line that has each new version labeled on it, and then if we need to go back to do a mid-year release then it can be recovered from this single line.
Upgrade your environment to 2010 ASAP - TFS 2010 branching is vastly superior, including management.
Your idea sounds about right - you branch off a release version when you have one, then just fix it.
You just have to live with the versions accumulating. This makes sense - until you totally retire one (and "never" is not real here, I bet after 7-8 years you kill an old version) there simply is no other way.
A few places I have worked would handle that like this:
Devs never touch "main" branch directly and it always represents what is in production
A single "maintenance" branch is used for all of your changes throughout the year.
At the end of the year, after all of the changes are ready to go, label everything approprirately and the maintenance branch is merged back into the mainline. A new release build is prepared from the mainline and sent out.
Ongoing changes happen in the maintenance branch.
Rinse and repeat as needed.
Benefit is that you only ever have 2 branches. That makes some SCM related tasks easier to deal with since you don't have to keep dealing with changing folder names, etc.
I am working with a small development shop that consists of a group of 5 developers and 1 QA person. We are using TFS and need to get more sophisticated on how we use this tool.
Currently the development team checks in their code each evening. A nightly build runs and pushes the output out on a network share. Our QA person uses this build for testing the next day. Sometimes the build off the trunk codebase has issues/bugs that hinder the QA process, and it hasn’t been a giant issue in the past, but we now want to get to a state where we have our QA person testing on a stable QA build.
So I believe we need to create a branch (call it QA), and the developers will continue to develop off the trunk, but the QA person will use builds created from code in the QA branch.
Seems simple enough, but we have started doing code reviews as well. So we have another desire in that only code that has been code reviewed can be promoted to the QA branch. Each developer works off a TFS item, and when they check in a changeset, they do it against a TFS item which creates a link between a checked in code file and a TFS item. Eventually the TFS item becomes complete and ready for code review. All code attached to the TFS item is reviewed. How can the versions of these files get promoted to the QA branch?
In the QA branch, if a bug is found, we want to fix it in the QA branch and have the changes migrated back to the trunk. I believe TFS has a way to automatically do this doesn’t it?
Long story short, we want to get to a build and CM environment that I believe is pretty standard, but we are unaware of how to make this happen with TFS. Given our situation above, can someone point out a book or website(s) that would address our specific needs? We would like to make this happen without having to get too deep in CM theory or TFS.
I very much appreciate any and all suggestions!
Thanks,
John
You might want to take a gander at the resources on CodePlex. There are different strategies laid out for how you might want to build your branching model.