

How GitHub Does Enterprise - ropiku
http://zachholman.com/2010/07/enslaving-branches-how-github-does-enterprise/

======
pilif
We are maintaining and developing a huge web application
(<http://www.popscan.com/> for those interested. Trust me. It's nothing YOU
would want to buy :p ) which we also have to heavily customize for various
customers and their very special wishes (even though I'd rather not as you'll
see).

Some of these installations, we host ourselves, some are hosted by our
customers.

We maintain a development head which becomes a release branch every 6 months.
This is the core of our application and development done to the core is then
part of the new release we give our customers either as part of a maintenance
contract or for an upgrade fee.

Early on, we found that it's impossible to give all customers the same
solution. Heck, it's not even possible to give them the same version with a
completely altered skin. Part of this could be that we have fierce competitors
in our customer base, so they want some way to differentiate.

So this is what we have invented the "Customizers" for. Our app is sprinkled
with Hooks (currently 305, but steadily increasing) that a customizer can hook
into altering just about any behavior that a customer could possible want to
have altered. Sometimes it's just for altering data, sometimes, you can
outright replace functionality.

That worked quite well, but over time, we needed even more power at which
point we added even more stuff like pluggable modules (think very powerful
controller if you come from a Rails world), pluggable amendments to existing
modules and most recently template overrides:

Our application comes with three base styles (consisting of Smarty (yeah. it's
PHP, but quite clean. And 6 years old) templates plus basic CSS and JS) plus a
customer specific theme (consisting of CSS plus images).

Of course, sometimes not even that is enough which is why we can now inject
smarty code based on the customer at which point our application will load the
overridden template instead of the original.

Let me tell you this: This customization is the most painful thing I have ever
done in my life. Even though the core application is the same for all our
customers, no two apps look (or even work) the same. Hours and hours are spent
tweaking every aspect of the application to the customers demand, sometimes
even turning cool features off because "it looks to similar to what competitor
B has".

None the less: Using the strict separation between core and customization, we
can move the product forward without filling the core with customer specific
crap and without constantly merging.

It's true: We don't need customer specific branches.

There's just the HEAD and the bi-yearly release branches (auto-deployed weekly
to the systems we host). Customer specific changes are done in the
customization part of the application and by design they can't affect the core
(or, heaven forbid, the customization of another customer).

The only merges we do is the "Friday-merge" in which we forward-port bugfixes
made to the release-branches - from oldest to newest to master.

This is where git is really awesome in that it's extremely good at merging
making these friday-merges a pleasure to do.

Doing them weekly on a set time removes the need for each developer to
manually merge every change (unless they need it in another branch - then they
have to cherry-pick) and doing it weekly means that the changes are fresh
enough for whoever does the merge to remember what the nature of a change was
should a conflict arise.

So while the thing still is a huge, marketing-driven mess, we DO have it under
control and are still able to move the product itself forward without the need
of having to track a branch per customer (we tried that. it turned out much
worse).

In the perfect world though, the customization would not exist and our
customers would use the same product maybe with some styling using CSS, but
unfortunately, that's plain not possible (for other technical reasons too, but
this is already getting long).

------
jlangenauer
For me, this was very interesting, as it mirrors a lot of the work we've done
at Constrex with our first product Tender.ly - currently being sold as
downloadable software, but one which started life as a SaaS offering, changed
from that, and will be returning to that as well in the near future.

However, we explicitly do not keep separate branches for the SaaS and
downloadable versions of Tender.ly, as the last thing we want is divergent
code branches. This is a bit different of a situation to GitHub, which has
separate products, but makes our development a bit easier at the expense of a
bit more up-front thought when doing the coding - which probably isn't a bad
thing.

We ended up coming up with the same solution as GitHub - coalescing all the
divergent code into sets of modules, which are then included based on the
rails environment loaded at start-up. As we don't want purchasers of the
software establishing themselves as competitors (despite the license
conditions), all the SaaS code is simply deleted by the build scripts we use
to release.

As an aside, JRuby + Glassfish + Rails is a very nice stack for selling
downloadable web software - the same code runs on Windows and Linux with
minimal changes, and some simple scripts to do the database setup. I really
should write a blog post about it at some stage. Perhaps when the day is
extended to 25 or 26 hours.

edit: Apparently I can't conjugate English verbs.

~~~
holman
That's actually pretty similar to how we do it, too: we precompile models,
controllers, and most other relevant private libraries, then we deliver it on
a JRuby stack.

It's actually quite slick and works pretty well, unless you have a ton of non-
Java compiled gems to deal with. We've been able to get through that pretty
well or find alternatives, although it looks like JRuby's looking to support
those libraries in the near future, too, which is great. Makes JRuby quite an
attractive platform for this type of stuff.

------
josephruscio
The "Conditional Inherited Modules" seems to be one (of many) possible
implementations of the venerable Strategy pattern from GoF
(<http://en.wikipedia.org/wiki/Strategy_pattern>). It's a really elegant and
one of my favorites. Just define a clean interface and pick between different
implementations at runtime.

~~~
tomjen3
Thats funny, the Strategy Pattern has always felt like a hack to work around
Javas Fucking embarrassing lack of closures.

~~~
josephruscio
GoF wrote about the Strategy Pattern (and the rest of them) in 1994, so I'm
pretty sure Java (first public release in 1995) was the least of their
concerns at the time. And believe it or not, there are times when languages
with closures are not an option.

------
samstokes
This article was more interesting than I expected from the title. I was
expecting something about how GitHub sells FI to enterprise clients, or what
features they have to add to FI to make it palatable to enterprises (the
latter is touched on a bit).

A more informative title would be "How GitHub manages long-lived development
branches". Usually long-lived branches mean you're Doing It Wrong (TM), but as
the article indicates, enterprise customisation is one case when a long-lived,
occasionally-synced branch makes sense; another is maintaining released
versions of installed software.

