25
Branching Strategies Chris Birchall 2013/06/21 #m3_dev

Branching Strategies: Feature Branches vs Branch by Abstraction

Embed Size (px)

DESCRIPTION

A look at some of the problems introduced by feature branches, and a short introduction to using Branch by Abstraction as an alternative.

Citation preview

Page 1: Branching Strategies: Feature Branches vs Branch by Abstraction

Branching Strategies

Chris Birchall

2013/06/21#m3_dev

Page 2: Branching Strategies: Feature Branches vs Branch by Abstraction

Branching strategies

Feature Branchesvs

Branch By Abstraction

Page 3: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature Branches

● master branch is used for rollouts

● Little work done directly on master

● For every feature/bugfix, cut a branch

● To rollout a feature, merge to master

master

feature A

feature B

Page 4: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature Branches: Problems

Merging is HARD WORK

Page 5: Branching Strategies: Feature Branches vs Branch by Abstraction

Merging is HARD WORK

Sometimes impossible for git/svn to auto-merge

master

feature A

feature B

BOOM!

Page 6: Branching Strategies: Feature Branches vs Branch by Abstraction

Me

class FooService

interface FooService

classDefaultFooService

classCachingFooService

changed class to interface

Other dev

class FooService

● altered a bunch of existing methods

● added a bunch of new methods

BOOM!

Real life example (happened last week)

Took over an hour to merge manually

Page 7: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature Branches: Problems

Merging is SCARY

Page 8: Branching Strategies: Feature Branches vs Branch by Abstraction

Merging is SCARY

Do you trust your tools to merge correctly?

Have had problems with buggy tools (e.g. git-svn)

Page 9: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature Branches: Problems

Merging is A CHANGE

to the codebase

Page 10: Branching Strategies: Feature Branches vs Branch by Abstraction

Merging is A CHANGE to the codebase

Merging counts as a change to the codebase

→ Need to perform manual tests before rollout

End up doing same tests before and after merge

Page 11: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature Branches: Problems

Feature branches are not

subject to CI

Page 12: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature branches are not subject to CI

Jenkins is only working against master

Manually creating a job per feature branch is silly

Can automate it, but it's complicated and brittle

Page 13: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature Branches: Problems

Feature branches go ROGUE

Page 14: Branching Strategies: Feature Branches vs Branch by Abstraction

Feature branches go ROGUE

Branch can diverge massively from master

Becomes impossible to merge safely

Branch lives for weeks, months, ...

Page 15: Branching Strategies: Feature Branches vs Branch by Abstraction

A solution?

Branch by Abstraction

Page 16: Branching Strategies: Feature Branches vs Branch by Abstraction

Branch by Abstraction

The name is misleading...

Using B by A, we DON'T BRANCH!

NO BRANCHES == No MERGING

Page 17: Branching Strategies: Feature Branches vs Branch by Abstraction

Branch by Abstraction

● All dev is done on master

● Incomplete work is disabled using feature flags

● master is always stable, ready for rollout

● Changes performed by introducing abstraction

Page 18: Branching Strategies: Feature Branches vs Branch by Abstraction

Making a change using B by A

1. Add abstraction layer around the code you want to

change. (Extract interfaces, etc.)

2. Add the new implementation, but keep using the

old implementation in production.

3. Flip the switch! (Update flags, switch Guice modules, etc.)

4. Remove old implementation if no longer needed

Page 19: Branching Strategies: Feature Branches vs Branch by Abstraction

Example: Switching to a new auth API

1. Refactor concrete class LoginService into interface + impl class

class LoginService

interface LoginService

classLegacyLoginServic

e

Update surrounding code to use LegacyLoginService

(Maybe add a factory to provide the implementation?)

Page 20: Branching Strategies: Feature Branches vs Branch by Abstraction

Example: Switching to a new auth API

2. Add new implementation (+ unit tests, of course!)

interface LoginService

classLegacyLoginServic

e

Add feature flag to allow switching between implementations in

test environment

interface LoginService

classLegacyLoginServic

e

classNewLoginService

Page 21: Branching Strategies: Feature Branches vs Branch by Abstraction

Example: Switching to a new auth API

3. Flip the switch!

Update the value of the feature flag in production

Page 22: Branching Strategies: Feature Branches vs Branch by Abstraction

Example: Switching to a new auth API

4. Remove old implementation

interface LoginService

classLegacyLoginServic

e

interface LoginService

classDefaultLoginServic

e

classNewLoginService

Refactor (change class names, etc.) if necessary

Page 23: Branching Strategies: Feature Branches vs Branch by Abstraction

Example: Switching to a new auth API

Finished!

Remember:

● All this happened on master

● Codebase was stable throughout the process

● Both new and old impls were subject to CI

● No merging!

Page 24: Branching Strategies: Feature Branches vs Branch by Abstraction

Branch by Abstraction: Prerequisites

● Reasonably good, modular codebase○ Easy to introduce abstractions

● Good devs!○ Can be trusted not to break the build

● A good suite of unit tests

● A feature flag system○ Ideally, well-integrated with toolchain

○ e.g. enable features using checkboxes in Jenkins

Page 25: Branching Strategies: Feature Branches vs Branch by Abstraction

Thank you!

Further reading:

http://paulhammant.com/blog/branch_by_abstraction.html/