We recently adopted the concept of feature branches in one of our bigger projects, to segregate work on different aspects of the product that can be completed independently of each other.
For each so-called feature, we are creating the following:
a branch from 'main', aptly named after what the feature is supposed to be
a new team in the project portal, containing the people that will work on the feature
a build definition to validate check-ins against the source on the branch
The main point I would like to see discussed here is about the build definition. Currently, each one of them is set to gated checkins.
The question then, is: what is the best practice on associating work items to a build?
In our case, these feature branches are supposed to be disposable: we would like to be able to delete these builds/branches/teams later on when the feature is complete, but still be able to track them throughout the product lifecycle.
If I associate work items with these temporary builds, I'll lose tracking capability later on when the feature implementation ends. At the same time, I just found out that gated checkins always associate work items, regardless of what is configured in the build definition.
Would it be feasible to disable work item integration with the feature branches (in this case also converting them from gated to continuous integration) and enable it in the main build, so that these features can be tracked in the main product line? Or maybe this should be only enabled for Release build definitions, so that we can find out what was integrated on a certain release? For those of you who follow the sprint/feature concept, how do you handle this situation? Do you also have a build for each branch?
Update:
I just found something similar (but not exactly like what I wanted) in this question. The answer there lead me to a plugin that automatically associates work items on merge checkins. This should offer great traceability on it's own, so I think I'll give it a shot.
Would still like to hear what your thoughts are in regards to the builds in this scenario.
You're approaching this wrong IMO. You shouldn't be worrying about associating Builds and WI's, but rather associating Changesets and WI's. When your developers check-in changes in the feature branch you should ensure that they are linking them to the relevant WI(s). You can even enforce this via a Check-In Policy.
Now if you ever want to inspect that feature in the future to see all the changes associated with it, you can by inspecting the Feature WI, and looking at all linked Changesets. Even if you delete the branch all the Changesets are still available.
Related
Right now I have an Azure PaaS solution with a single repo in TFS - we right-click publish from VS to an App Service and then swap slots to get code to production. Small team, disciplined check-ins (or so I thought), etc.
I made a decision to check code in that wasn’t production ready, thinking if needed, I could roll back and publish a hotfix should the need arise.
Well, the need has arisen and I've rolled things back to apply the fix. This was a bit of a headache though.
I’m a little unclear on what the right thing to do is moving forward. What I want to try is:
Create a branch from our MAIN repo and stick all ongoing development there, call it DEV. We'll create two workspaces on our machines - one for each branch.
When we're ready to push a feature, merge down to MAIN and then QA before right-click publishing > Staging > Prod.
At a high level, does this seem like a step in the right direction?
What I’m trying to do is keep this project/alm lean and simple. I don't want to go as far as introducing a build server with RM and other expensive (time, materials, process) components - I just want a sensible, incremental upgrade in the maturity of our current setup to avoid the above headache and this is all I could come up with.
That's two way for your reference, one base on the working flow , one base on the publish (releaseing)
A. Just using mainline and tagging for release
Pros:
Avoid merge hell.
Keeping to the mainline encourages some best practices like proper
release planning, not introducing a lot of WIP, using branching by
abstraction to deal with out-of-band long term work, and using the
open closed system and configurable features for dealing with
managing works in progress that may; or may not; need to be disabled
now or in the future in order to release or to avoid a full rollback.
Cons:
Dealing with works in progress becomes an issue and adds to potential
surface attack area when it comes time to release. However, if your
developers are disciplined then new features should be configurable
and modular and therefore easily disabled/enabled, or there is no WIP
and at each release point all work is either completed or has not yet
been started (i.e. Scrum).
Large scale/out-of-band changes require more thinking ahead of time
to implement.
B. Branch by release
Pros:
You can begin working on the next iteration while the current
iteration finishes its round of acceptance testing.
Cons:
Tons of branches.
Still need to tag branches at release points.
Still need to deal with WIP and merge WIP from previous release
branch into next release branch if it's not going to make it and
still need to disable or yank it of release branch and re-run
acceptance tests.
Hot fixes need to be applied to more branches (release branch +
hotfix + new tag merge hotfix into vnext branch and possibly
vnextnext depending on where the hotfix fails.)
With respect to your point 1. I would not recommend using two workspaces, since you already are running "two workspaces" internally with two branches. The approach is not that bad, just a litte hard to do in TFVC, meaning the old server based version control inside TFS. I do hope your planning to merge everything from dev to main at point in time.
In general your guide is more matching with Git as source-control, and especially gitflow http://nvie.com/posts/a-successful-git-branching-model/ as a branching model. We are running that with success within my team.
You can migrate from TFVC to git using git-tf http://git-tfs.com/
If you are looking for a cheap model that scales out with buildservers and such I would reccommend looking at Visual studio team services https://www.visualstudio.com/en-us/products/visual-studio-team-services-vs.aspx as well to host and build your code. There you also have Release management integrated without cost(up to 5 people/free for all visual studio subscribers)
My company is using Jenkins for continuous integration and I'm trying to move towards CD. I'm using git hub as a code repository. Right now we are merging feature branches into a uat environment and when a particular feature has been accepted the feature branch will be merged to our production branch.
This is obviously dangerous because two changes could be tested together and deployed separately.
Ideally we would have a package tested and deployed without rebuilding but I'm having trouble seeing how this is possible. If two people work on two different features, the first is finished, packaged and goes into testing, the second is then finished and packaged without the first? But then how can I deploy the package without invalidating the testing of the other feature?
I'm not sure on the correct way to integrate features with a single deployable package.
Any help would be greatly appreciated.
Further,
If you look at http://ptgmedia.pearsoncmg.com/images/chap5_9780321601919/elementLinks/fig5_6.jpg
my concern is that check-in 1 can be deployed when it passes acceptance testing and that package will be deployed, but what if acceptance testing failed? Check-in 5 contains the same problem as check-in 1 so no deployment to production can be done until check-in 1 is fixed or removed. Removing the change would be annoying as there could be multiple commits to be removed, and a fix + testing could take a long time.
Continuous Delivery is an extension of Continuous Integration. CI is all about evaluating your changes in the context of everyone else's on a frequent basis (if you commit less than once per day it can't count as CI)
Branching, of any kind, is all about isolating change and so is fundamentally at odds with CI. Feature branching and CI are opposed.
What most organisations do is merge branches before testing. This compromises the value of the feature branch, but retains the value of CI. If you don't do this then the CI has little real value for the reasons that you describe - you are not evaluating changes in a realistic context.
Sorry but you can't have both, they are opposites!
Regarding the difference in cycle time of hotfixes vs less critical things have you looked into feature toggles? http://martinfowler.com/bliki/FeatureToggle.html
If you want to do Continuous Delivery then branching is a no-no. Well, mostly. Releases should be tagged in SCM, the fix applied to release and merged back into HEAD.
You should also have automated tests to prove the fix actually fixes the problem. This might be hard in some circumstances. In that case the minimum you should do is verify the fix doesn't break existing behaviour (if that's the intention of the fix).
Feature toggles are good, so is branching by abstraction, however in practice this is adopted only by the most mature and experienced teams who have adopted CD. I suspect you're not at that point yet, so this will help you overcome your bump until you're more comfortable with CD.
If two features are supposed to be deployed at the same time, then I guess you should use the TDD principle of creating a FAILING test first, then implementing code to make it go green. Check that test in, so no build can move forward until you've got it implemented. This will make it absolutely clear this build isn't destined for production, as the feature isn't complete. Not a good idea for this test to be a CI, but at a latest phase of testing... providing you have multiple test phases that is!
What's the best way in your experience to designate where work items should be coded? Do you use a particular field? We currently use a custom "Version to Fix" field in our WIT, but it doesn't relate directly to Dev or the Main line code branches. We end up communicating which Versions (v6.1, v6.2, etc) relate to which branches, but there is still a "mapping" that needs to be done. This really only works for a "Hot Fix" in a released version because the branch is named the same as the "Version to Fix". How are work items designated so that is easy for developers to know where to code and provides the least amount of maintenance?
Updated: Just to clarify a bit ... we have Dev, Main, and Release (one for each release) branches. We do 90% of our development in Dev. Once an iteration has ended we reverse integrate Dev to Main, however we don't release it at that point. Testing is done on Main for a while and select bugs could be fixed on Main. This all goes on while the next Iteration (new stories) moves on in Dev. Once things look good on Main we'll branch to a new version (new Release branch) and development on Main will end until the next iteration starts and we again Reverse Integrate to Main from Dev. Of course we forward integrate Main to Dev once things are fixed on Main. At any point we may have a bug that we want fixed on Dev, Main, or on a Released version. Where we have bug fixes going on in Main, Dev, and Release we are confusing some developers. We tell them the "version" but they have to know what future or current version links back to what Branch. That's where I'm trying to find the best practice with the Task work item.
You can have multiple versions (changesets) within a branch, but the proliferation of branches is not a good idea.
A simple (but powerful) branching strategy is to create a main brach, then create 2 children: 1) Dev, 2) QA Now the question is a non-question. Developers do their work in the Dev branch. When they're ready they reverse integrate changes to main. Then changes are forward integrated to QA. If the build passes QA, then it can be rolled to production.
Some organizations will employ special branching practices like creating a branch for a new Major version or even a branch for a special feature. These follow the same process of reverse integration into main (and subsequent forward integration dev branches when appropriate).
Builds can be linked to changesets. If a particular build has a bug, the developers look up the changeset number, pull it down from version control, check the work in associating it with appropriate work items for the Bug, and rebuild it. That new "bug fix" version now has a unique build id and changeset id associated with it.
That's really going to depend on your shop; our environment works on an iterative build, so the bug fixes always go into the most recent branch (named via date stamp - IE Branch_05252011 or so).
If you have some other kind of versioning / branching strategy, the best option would be to place the desired fix branch in the title:
V6.2 - Fix the ItExplodedException occuring in SomeClass
Alternatively, I believe TFS can also even offer a specialized drop down that you can populate when creating the work item with custom content. You could then populate that with the branch to target.
Here is a very effective solution: Set up a check-in policy using TFS Power Tools, and associate a Custom Path policy with a Work Item Query policy, so that all checkins for a branch will require association with a work item that falls into a branch-specific query. That way if the checkin does not have a work item that matches the branch, it will not be allowed. The query can be defined using whatever criteria you need, and the queries themselves can be updates and reassigned to different branches as needed.
One caveat, however: the queries themselves are evaluated at client-side, so as an administrator you can update the query to block or allow certain items into a branch, but the developers will need to refresh Team Explorer to update their query, otherwise it can allow unauthorized items in, or it can block items that are authorized. One solution I am looking into for this issue is to add a custom check-in policy that will always be satisfied but in the meantime will cause the VS IDE to refresh Team Explorer. I have asked MS to add this directly to their TFS Power Tools Work Item Query checkin policy but they have not responded.
I've been doing some reading about continuous integration recently and there is a scenario which could occur which I don't understand how to deal with appropriately.
We have a stable mainline/trunk branch and create branches for features. Each developer will keep their own feature branches up to date by merging from trunk into their branch on a regular basis. However it is entirely possible that two or more feature branches could be created and worked on over a period of several weeks or months. In this time many releases of the software could be deployed. This where my confusion arises.
It is very likely that changes for one feature branch will cause merge conflicts with other feature branches. CI suggests you should merge into trunk at least daily which would resolve the conflicts quickly. However, you may not want to merge the feature code into trunk because it may not be finished or you may not want that feature available in the next release. So, how do you deal with this scenario and still follow CI principles of daily code integration?
There are no feature branches in proper CI. Use feature toggles instead.
The idea explained more fully in this article is to merge from the trunk/release branch to feature branches daily, but only merge back in the other direction once a feature meets your definition of 'done'.
Code written by one feature team will be pushed into the trunk once it's complete, and will be 'distributed' to the other teams, where conflicts can be dealt with, as part of the daily merge process.
This doesn't go as far as satisfying Nick's desire for a version control system that can be used a backup tool, unless the changes being made are small enough that they can be committed to the feature branch within a timeframe where the the risk of losing your work is acceptable.
I personally don't try to reintegrate code into the release branch before it's done, and although I've never really tried, I'm sure building feature toggles in for unfinished work has its own issues.
I think they mean merging mainline into the feature branch, not the other way 'round. This way, the feature branch will not deviate from mainline too much, and be kept in an easily mergeable state.
The git folks do the same thing by rebasing feature branches on top of the master branch before submitting a feature.
In my experience with CI, the way that you should keep your feature branches up to date with the main line changes as others have suggested. This has been working me for several releases. If you are using subversion make sure you to merge with the merge history enable. This way when you are trying to merge your changes back to line it will only like you are merging the feature changes to line, not trying resolve conflicts which your feature might have with the main line. If you are using more advance VCS like git the first merge will be a rebase where the second will be a merge.
There are tools that can support you to get thins done more smoothly like this Feature branches with Bamboo
Feature branches committing back into the mainline, and OFTEN is an essential feature of Continuous Integration. For a thorough breakdown, see This Article
There's now some good resources showing how to combine both CI and feature branches. Bamboo or Feature Branch Notifier are some ways to look.
And this is another quite long article showing pros of so called distributed CI. Hereunder, one excerpt explaining the benefits:
Distributed CI has the advantage for Continuous Deployment because it keeps a clean and stable Mainline branch that can always be deployed to Production. During a Centralized CI process, an unstable Mainline will exist if code does not integrate properly (broken build) or if there is unfinished work integrated. This works quite well with iteration release planning, but creates a bottleneck for Continuous Deployment. The direct line from developer branch to Production must be kept clean in CD, Distributed CI does this by only allowing Production ready code to be put into the Mainline.
One thing that still can be challenging is keeping the branch build isolated so that it doesn't pollute your repository of binaries by pushing its branch builds to it. Bamboo seems to address that, but not sure it's as easy with Jenkins.
I'm looking for a workflow-type description of the series of steps you perform to switch from one software development task to another. If a step involves a tool, please specify which tool and how it's used. The goal of the workflow is to have the smoothest possible transition from task #1 to task #2 and back to task #1.
Consider this scenario...
You're implementing a new user story and, while you've made progress so far today, it's not quite done and you haven't implemented your tests yet.
Your lead comes to you with a high priority bug that's blocking your test team. You need to stop what you're doing and get the bug fixed. The bug is in a build from three days ago, which is the most recent build the test team has picked up.
You can fix the bug in a new version of the sources, but it has to be a stable version and can't include the incomplete feature you're currently working on.
Alt + Tab is how we do it.
Task switching is a thing of the brain. I don't think there is a tool to do that for you. If there is, I am also interested.
Each person has its own way of preparing, some don't prepare at all and are in another thing like a snap, some take more time etc. It depends on the man/woman.
Sure, you can try to create some mental milestones (taking a note, place a reminder etc) to return to it when getting back to the task, but this again depends on other factors (how long was the task switch, how quiet the office, familiarity with the task, moon phases etc).
The most efficient way for a developer to switch between tasks I think is subjective.
Meanwhile, have you read the Human Task Switches Considered Harmful from Joel Spolsky?
I would say the steps you need to take in the scenario you describe are 100% dependent on the development environment and tools you have set up.
Using Perforce for source code version control, we have set up a branching system where the releases are separate from development work and all development branches stem from a single "acceptance" branch. Each branch is used for a single issue, or for a set of very closely related issues. No other issues can be worked on in a branch until the changes have been integrated up to the acceptance branch.
Yes, it does mean we have a lot of branches. Yes, we do a lot of syncing (acceptance down to a work branch) and integrating (work branch up to acceptance). But its worth is incalculable when it comes to easily switching from one task to another, going back to a test-built, spotting two issues biting each other, etc.
After development has done its thing (including their own tests), an issue is tested by the QA team. First in isolation in its own branch. After that is is integrated into the acceptance branch and a regression test is done to find any problems with independent issues biting each other. When all issues for a release have thus been integrated into acceptance, a full regression and new functionality test is executed by the QA team.
So, the acceptance branch is always the "latest" state of development for the app.
In this set up the scenario you describe would play out as:
Leave my current task as it is, possibly check in any outstanding changes so as not to lose them when my computer crashes. If that means breaking a daily build of that branch, I wouldn't check in, unless it is easy to fix the compile errors. (Please note that we have many apps in our application suite and while my changes may compile in the app I am working on, they may still break the compilation of other apps in our suite) Our rule is: each submit may break functionality, but must not break the build process.
Find an "empty" branch - a branch that is not currently being used for any development work, or, if all branches are taken, create a new one.
Force sync the acceptance branch and the selected work branch so my machine is guaranteed to have the latest state for both branches.
Synchronize (forced if necessary) the latest state of the acceptance branch to the work branch, so the selected work branch is the same as the acceptance branch.
Open up that branch's application suite in the IDE, debug and solve. Submit to the work branch.
Tell QA to have a look at it in the work branch. If they are satisfied with it, integrate the changes up to acceptance so they can continue their test.
Switch the IDE back to work on the application suite in the branch I was working on before.
Rinse and repeat.
Considering your scenario,
you could check out the stable version of sources in another working copy, correct the bug, commit.
When you come back to your incomplete work, do an update and continue to work.
When you're working on something you usually have a few ideas, few things you're planning to do, some stuff that is not clear and has to be solved later. It tends to get lost when you switch to other task.
I found it useful to write them down somewhere - take a brain snapshot. Later it's easier to restore it and get back faster to your original task.
I make a note of every file I'm working on inside of a Task/Todo item with a reminder in approx. the amount of time I will be away from it. Then I save and close each of those files to prevent them from distracting me/eliminate the clutter/create room for the new task on my desktop. I have the memory of a flea, so I need all the help I can get.