Online Mind Mapping and Brainstorming

Create your own awesome maps

Online Mind Mapping and Brainstorming

Even on the go

with our free apps for iPhone, iPad and Android

Get Started

Already have an account? Log In

Your Code is Not a Version: How 'Build for Disable' can bring you true continuous integration by Mind Map: Your Code is Not a Version: How 'Build for
Disable' can bring you true continuous
0.0 stars - reviews range from 0 to 5

Your Code is Not a Version: How 'Build for Disable' can bring you true continuous integration

Build for Disable Techniques

Code Example: OldMath vs NewMath

Original Code

Code can be found on my Bit Bucket

Simple if check with a static boolean

Code example

Add a method for the alternative approach and static boolean

Code Example, Tests

Writing tests could be challenging as you enable and disable, Make this boolean protected and set it for pertinent tests, When deleting old math, remove corresponding tests

Extend the class and override the methods you want to change. Point the app config at the new class, and to disable point to old class

Code example

This keeps tests separated from the other tests

When deleting Old Math copy the old tests into new test class and walk all failing tests, Ideally it will be deleting old/changed functionality, Maybe you broke something unintended

Actually USE interfaces!!

Decorator Pattern (sorta), Code example, Old Math Imp, Tests and Class can stay in place if desired, doesn't require being merged later, Sometimes this is a good design, sometimes not

Leads to better coding practices in general

Sometimes you find out, this is better architectually and that functionality shouldn't be mixed in where it was

Writing code in separate and distinct groups is easier to test, easier to maintain


Comment It Out, Hide Buttons, // showAwesomeFeatureButton();, Disable Web Service, // @RequestMapping(value = "/export", method = { RequestMethod.POST }) public ..., Short Circuit new functionality, // satellite.maskUglyAreas(THE_NO_KIDDING_THRESHOLD);

Presenter Info

Nicholas Tuck

Work at AFWA for AFWWEBS

This preso url:

Previous Brown Bags


Unit Testing

Pair Programming

twitter: @nicholastuck

Find me on G+ (not kidding) seriously...

The Goals

Be productive... every day

Stop fearing merging and start improving your product confidently

Thought Experiment

Stop thinking of your code as a version and Start thinking of your code as a living entity

The Room for Improvement

Feature Branch

aka Branch by Version Control

Each feature has it's own branch, See Graph (1a)

This process can work but not productive, Most features merged at the end, This week != fun, Requires the entire team, lots of coordination, in a short time period, The end of the sprint!, Often relies heavily on the most knowledgeable team members, Huge waste of time for this person, Merge first != win, Sometimes it feels good though, Final feature merges often work more than your early feature merges, Final merges did minimum to make your tests pass... you wrote tests right?, Constant testing on branches have limited value, Last minute integration adds bugs that were already fixed individually, but have been reintroduced due to merging complications and last minute testing, We have to redo alot tests after integration points and all merges, See Confidence Graph (1b), Duplicate Work, See Duplicate Work Graph (1c), Ever fix the same thing as someone else?, Ever fix it in exactly the same way?, Takes a lot of time convincing the other guy your way is better, Daily pulls do NOT fix this, Nothing to pull if no one is pushing until they are done, Large Feature Problem, Major feature missed code cut off, See Graph (1a - add Release), This is rarely 100% new code, It probably touched lots of the baseline (for the better), Constant daily improvements are not making it into our releases, This is not good, See Change / Time Graph (3)

Simple Solution

Commit Constantly and Push Hourly

This is not just DVC - commit hourly. This is actually push to the public repo hourly., See CI Graph (2a)

Push When Exactly?, - Worked on a feature for a few hours - Added tests around all the work - Push your code out to everyone else, - Fixed a small bug - Only a handful of lines of code - Write the test - Push the code, - Working a big feature that will take days, maybe weeks - Write a couple hours worth - Push it to everyone

Why This is Better, When you push daily you merge daily, No more nightmare merges, Continuous Testing, Constant integration means testing at any point is testing the entire state of the sprint, Integration problems are found early and fixed easily, More tests are being added across the integration points, Confidence is incredibly high at the end of a sprint, See Confidence Graph (2b), Eliminates Duplicate Work, We are literally at the latest changeset, we have all the work that exists, We can actually start helping eachother, Large Features Add Value Constantly, Large features consist of lots of small improvements, Every improvement makes it into the baseline as soon as as possible, See Change/Time Graph (3)

Rules That Have to Change, Taboos, Never commit code that doesn't fully work, Our code already doesn't work - called bugs, We work daily with features that have bugs but we don't know about them yet, The unknown is hard to work with, Features that are not yet finished we work with daily, The known is pretty easy to work with, If we did commit what isn't finished, We could actually work as a team on anything, - If something doesn't work and you need it, fix it. - Old bug, new bug, current featuure, let's work together, - Requires daily communication to deconflict duplicate work - aka Daily Scrum, Never commit commented code, Commented code is generally bad because it never goes away because no one knows anything about it, Keep this attitude, If no one knows anything about it, get rid of it, With this CI approach, We know about it, We are working it, It will get cleaned up tomorrow, The known is easy to work with, This is how we code, - Comment Code - Copy Code - TODOs - Magic Numbers, Let's not hide this, Let's embrace it, BUT let's ensure we clean up after ourselves, Rules to Re-enforce, Don't break the build!!, We still want a broken build to flag a problem, and we still want pizza, A feature you are in the middle of is not a problem, it's progress, Add ignore annotations or comment out failing tests, Maybe implement rollback in jenkins if a build breaks

Why Isn't Everyone Doing This? Introducing 'Build for Disable'

Few teams are implementing true continuous integration because we believe our code exists in versions

We believe we are working to deliver an idealized version of our code to production, Implied (ABC) versions in Graph 1, This version of code is on a pedestal, Only 100% done code is comitted, Only Code that works without bugs is committed (yah right), All features undone are in a different version, It's like the superhero of all code versions, We try to have the public repo represent perfect versions of the code, This gives us warm fuzzies, Why We Do This, We tend to develop processes around our tools, We model our process on how the tool represents our code, svn/cvs branches == feature branches, We need to develop our process then find a tool that works, Our single mitigation on how not to ship a product with half working features or buggy features, This is a myth, What about that guy who pushed code to head when he shouldn't have, Scramble to learn all the fancy features of our version control to pretend like it never happened, We try an hg rollback, revert, bifercate mulligan and hope the dice roll sevens, Plus we ignore the iminent problem that awaits us the day after the release when we try to merge in the mess we just made worse, Implemented with restrictions on who can push to certain repos, More restrictions don't make us more productive, they make us slower, much slower

The Solution

Your Code is NOT a Version!, Your code IS a living entity, It is always, improving, moving forward, changing, It's being fed while you push code, It's being exercised under test, It's being relieved during refactoring, It is basically alive, Stop looking back at what might be a stable version, Spend more time looking ahead and creating the product we want to ship, (Bad) Car Analogy, If we were iterrating on building a rocket car, You had all 4 wheels on the car but no steering wheel, You don't take the wheels off, you just put the brakes on, Don't have brakes? Maybe finally over tighten bolts?, I'm not a car guy

Introducing 'Build for Disable' aka Branch by Abstraction (VS Branch by Source Control) (Similar to Feature Toggle), What is it?, Build significant changes so that they can be trivially disabled, Disabled can mean, A simple boolean calls the old code instead of the new code, A few lines of code are commented to remove an enhancement, The gui is hidden from the user preventing use of the feature/code, When producing the product for a release, Identify changes the team has not completed, Disable them with whatever means chosen, We don't fall back, We push forward, An example for comparison, Show Failed Feature Graph (1e), Second to last feature merged was found to have critical bug, Try to pull it out but last feature relied on it, 1-3 days of mess to deal with, Show Failed Feature Graph (2d), Disable feature C aka The Comment, Done in 10 minutes, 8 minutes was jenkins building and running all the tests, But all the code is going to PROD!!!!, OMG, How do you know it won't affect anything?!?!?, It will affect things, Isn't it awesome?, All your improvements will be shipped, Continuous Improvement, Everything at this point was tested, we know what works, everything will still pass, no risk was introduced, only reduced, We have high confidence because we know what is being shipped, What was being shipped the other way? Did anyone know?

In closing

Your code as a version

See Graphs (1), Versioned progress, Low confidence, Feature pulling fiasco

Your code alive

See Graphs (2), Steady progress, Consistent confidence, Disabling mechanisms

Review Goals


How do you manage peer reviews with everyone's code mixed together

Fisheye and Mercurial do a pretty good job

Spend 5 minutes to cleanup your peer review for others

Peer reviewing other's code isn't bad but sometimes it's undone

Does this only work if there exists a good automated test suite on the project?

No, it helps even more, This means most of your testing is done manually, Merging at the end means repeating all manual efforts and re-troubleshoot very difficult problems while merging, Merging along the way means any manual tests are done across that integration, Gaining more confidence and more manual test coverage throughout the iteration

When do we remove the extra and disable code?

When it makes sense, Once the team accepts the code and is ready to make the feature production, Once the risks of the feature are overcome, Once everyone feels comfortable with the burn in time, Basically when your team is ready

When do we peer review the code? Before disable code is removed or after?

Both, You will want a full review of the code before disable code has been removed so that the team can agree to move forward with the code, Then you will need a very quick/easy follow up review of removing the disable code and the extra tests