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.
Related
I am designing a branching & merging strategy for my project (We use TFS). Project has plans to have multiple released versions. Currently we are testing v1.0alpha and working in v2.0
The plan is:
After imminent green light from testers, version v1.0 will be released to one client.
Version v1.1 (already in dev) will be deployed to 5-6 clients
Version v1.2 would be installed to dozens of clients.
etc.
We will try to force upgrade of old clients to most recent versions but due to the nature of project and market it can be months (years?) for clients to upgrade.
We want to use standard gitflow but seems more appropriate for having a single version. I have designed a simplification of gitflow:
The approach is:
If a client wants a bug fixed, we will fix it in the Release branch of his version and he has to upgrade to the latest revision of his version. For example client in v1.0 that has a bug would have to upgrade to v1.0.5. If the bug happens in other versions we will fix it there.
If the client wants a new feature we will develop it in the latest version and force them to upgrade if they want it. For example client in v1.0.5 that wants new version will have to upgrade to v1.2
If all the clients of a given version upgrade we will delete that Release branch. For example when the client of v1.0 upgrades we will burminate v1.0 Release branch.
So my questions in order of importance are:
Will my approach work? Any problems that you can see?
Does git-flow have any pattern for this "multiple versions scenario"?
Gitflow has a Master branch. Is it ok not having a Master branch? Could we consider the different Release branches as "Master"?
How will you name Dev and Releases branches?
Your approach should work. There is nothing magical to GitFlow, and variations catering to your needs are fine. Git itself has no issues with a different workflow. A good example is Github flow, take a look at http://scottchacon.com/2011/08/31/github-flow.html .
A few things you could consider:
a) "Principle of least surprise": Try to keep as close to a standard as you can. That means you i) point devs to available documentation on the web instead of writing up everything ii) make it easier for new devs to enter or just work with your projects.
Thus, you should keep the master branch, not because it is needed - it is not, but because it might confuse people when it is not there, and you would have to explain that for years to come.
Branches in git is "just" names (well, a bit more, but you get my meaning), so the only reason to name them the same is convention - making it easy for people.
b) How many devs are working on the projects? If there are many, you could consider the Dev branch an integration branch, and use the master branch as the stable branch. Having a dev branch that you allow to be unstable might solve many issues with many devs. Two teams committing, one from feature and one from a hotfix, the build goes red, the teams blaming each other, the third team try to get out a new release branch, but can't. Having a stable, always green build master branch, which you even could protect with pull requests, is very nice, and makes for a more relaxed environment.
2) Basic Gitflow is centered around a release, so not quite. You have multiple releases at the same time. So you are nearly there, but standard tools, like [Jakob Ehn's] (https://github.com/jakobehn) Gitflow extention to Visual Studio - which is supergreat - will make you try to close a release before you are allowed to open a new one. Ask Jakob to relax that, and the tool will work for you. Otherwise, just follow the convention, but do it manually - that works too.
3) See point 1 above about master and why it might not be a good idea to not have it. But of course you can consider the release branches as kind of masters, but they don't really behave that way in your description. And if so, which one is the real master, the one you create feature branches from, and the one you regard as the latest? Having a stable master solves a lot of questions that pops up without.
4) Dev or Develop, then features should have a name of the feature as close to what it does as possible, like Dev/NewHelpPage, or Feature/NewHelpPage (to be closer to gitflow convention). Release branches, it looks like you already follow the semantic versioning (http://semver.org) principle, so why not use that: Release/V1.0, Release/V1.1 and so on. A hotfix branch is then Release/V1.0.1 .
Let the naming be so that devs easily understand what it is, preferably without needing to have to ask anyone around.
Keep it simple, follow conventions as far as you can, and it tends to work out. Git itself works for mostly any branching scheme.
[Edit]
Just had a quick chat with Jakob, and he said he had requests to support support-branches, which is probably what you are really after. He also pointed to this excellent post on different gitflow scenarios, at the bottom there is the flow for support-branches.
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/
The Microsoft ALM Team describe the Basic Branch Plan as needing a MAIN, DEV, and RELEASE branch.
I am working on introducing branching/merging to a new team who currently uses source control with no branches whatsoever.
I was wondering how the RELEASE branch is actually used.
Can changes be made in the DEV branch then be merged up to the MAIN branch without needing a RELEASE branch? MAIN would still be read-only. It would basically be the RELEASE branch in essence. The reason I say this is because we don't have that many changes but I want to isolate the stable code from new changes. Our concept of a "release" per say is not yet well defined. I am still working on that.
I just don't know if my team needs a RELEASE branch (considering our needs specifically).
I would appreciate some comment about the strategy of just having a MAIN and DEV branch.
Typically the release branch(es) are used for "safekeeping". Basically the same as a label.
Releases to production are usually a pretty important event, and you want to know exactly what source you released (in case you ever need to go back to it). Way back when people used to create Labels to track this, but creating Release branches is better for a couple reasons:
Labels are mutable in TFS, meaning somebody could change a label and there would be no audit trail
Branches are also mutable of course (changes can be checked in), but this can be locked down via branch specific permissions
Also if a change is made to a Release branch (which it never should be), at least you have an audit trail through history
Even though a branch looks like a heavy-weight operation creating a copy of your entire code base, in reality TFS just creates a new pointer to the same files, so the storage cost is trivial
I went the other way when I implemented TFS at a client (replaced SVN). What I did was introduce a MAIN branch and a RELEASE branch and not a DEV branch initially as that seemed very confusing to the team. It is also hard to convey the purpose of a DEV branch to an SVN familiar team initially.
The main purpose of our RELEASE branch was to preserve a historical placeholder as said in another answer. Currently we are using Git and we have a CI server that does the release process and branches to release/$version_number. I think that concept might be easier to understand and convey to your team. i.e. automatically create release branches when you actually release.
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.