Ask HN: What's your branch and merge strategy till production deployment? - sunasra
======
akuji1993
Usually it's

> master (used only for deploying on prod)

> dev (used for merging feature branches into the "new" master branch that's
> going to be deployed in a few weeks)

> feature-branch (based off of the current dev build, getting merged back into
> dev when it's finished)

We usually have a prod machine and a test machine running, the test machine
usually runs dev for QA to test out the future build. If we need to test a
feature branch before merging, we're deploying that one there instead and swap
it out for dev when the test is finished. This model obviously only works with
a finite number of developers up to a certain point. But for us this is enough
to be productive and not get into each other's way when developing multiple
features.

------
bitherd
We "Feature branch." With a twist on some of the busier repositories. We have
a repository per application. We use Subversion (VisualSVN the Windows port)

1\. Branch current live revision from Release to branches/ticket-ref (Our
Release is what others may call main, trunk or master)

2\. Work on feature.

3\. Code review.

4\. Merge to Release, CI (Jenkins) picks up change and builds NuGet package(s)
pushes them to Octopus Deploy

5\. Deploy into Test environment

6\. QA pass/reject

7\. If reject go back to 2.

8\. If pass Deploy to production (single click in Octopus Deploy)

9\. The twist for busy repositories with lots of changes: Cherry-pick merge to
a Stable branch, which CI builds and pushes to Octopus Deploy Live channel

10\. Deploy to production

Biggest issue we have is concurrent features x y z all being worked on, x y z
are all deployed in test environment, y is passed by QA but can't be deployed
because that versioned package also contains x which is rejected, so has to
wait until x is fixed, which will then of course contain z. This is only
really a problem when we want to get an emergency hotfix w into production.
Right now we have to revert x y z from the Release branch, merge w build and
deploy then put x y z back in.

This has taken 2 years to perfect so far. Changes we are considering:

a) Jenkins plugin that automatically creates a build configuration the moment
you create a feature branch in SVN, this way we can keep x y z in separate
versioned packages (I personally feel this is not true "integration" because
you are keeping things separate.

b) Feature switches. So if y is good but x and z are not ready we just deploy
with those features switched off.

We deploy on Tuesday/Wednesday/Thursday most weeks, never Friday - Monday.

------
shoo
I don't argue the following is good, but it's what's been done for a couple of
years for an internally used line of business app with a sole enterprise
owner/client. Release frequency is roughly fortnightly for feature work.

there's one main team git repo for application code, people push feature
branches into it, then there's code review (gitlab with automated pre-merge
runs off the unit tests) and automated post merge runs of all the automated
tests (takes more like 1-2 hours).

dev - main integration branch

feature/$ticket - branched off dev, typically merged into dev after code
review but before serious testing or uat

master - dev is merged into master infrequently, when we have dev branch in a
state that plausibly resembles releasable software.

We can build deployment packages from any branch, but typically build packages
from dev branch to deploy into test environments. When we merge dev into
master, build a package from master, then do full dry run of release into
staging env before deploying same package to production.

What doesn't work so well:

* Same issue as bitherd's comment: since features are merged into dev branch before manual QA/uat process, quite often dev branch contains mix of new changes that are good to release, and changes that are broken and block release from that branch. there is increasing automated test coverage to catch some of this, but historically culture was not to write automated tests and try to manually test everything (yup, that doesn't scale for regression testing).

* because of above, when the current date is a week or less from a planned prod release, devs cannot merge new feature branches into dev branch unless they are small patches to stabilise dev. This could be trivially avoided by forking release branches off dev branch and using these to stabilise to decouple from dev branch, but we never started doing that...

* i lied by omission earlier: instead there are actually multiple "dev" integration branches , say dev dev2, targeting different release dates. When we are gearing up to do a release from dev branch then more experimental changes that haven't gone through uat can be merged into dev2 targeting a later release date. dev is merged into dev2 every day. After a release dev2 is merged into dev. the worst it ever got was dev, dev2, dev3 and devbarr when there were large batches of features that had been planned and were in some state of contruction but stakeholders weren't yet agreed should be released for consumption by users. At some point obviously you can't kid yourself this is continuous integration, is continuous something but not integration.

* I lied by omission earlier - above is what we do for application code, we have multiple other repos (related to Jenkins build scripts, per-environment configuration) where we more or less just feature branch off master, merge into master and try to keep master stable.

We're in a place now where in principle we could bake a package off any random
branch and deploy it to prod environment in about half an hour (without
testing and with an outage), so even though some parts of our branching
strategy are not ideal probably the main blocker to a higher release cadence
is just getting the different stakeholders (business, users, support, ops,
dev, change management approval process) to agree to it.

