This is a best practices question for release management of an app. But this scenario is a bit different than what I've been able to find myself.

Essentially my company maintains a fork of its own app. There are two versions of the app that will have different configurations of bug fixes / features. These fixes and features come from a common pool of what's completed. The reason for the two configurations is that there are two main testing environments with different goals.

Let me explain that a bit more with a scenario:

  1. We have features 1, 2, & 3 and bug fixes 1, 3, & 3 being worked on at the same time by different devs.
  2. For the upcomming releases to QC, Config-1 of the app wants to include feature 1, and bug fixes 1 & 2, and Config-2 wants to include features 2 & 4.
  3. For subsequent releases to QC, certain features may get rejected as being incomplete, buggy, no longer needed, etc. And same with the bug fixes.

#3 is important because not all features get removed or synced between the two configurations. This means that the two configurations diverge slightly over time. But only in the short term for what's in active development. Over the long term, the code base is in sync with what's in production.

So, as a diagram, the builds could look like this over time (with some added features / bugs from the bulleted scenario above):

Builds Over Time of Two Related but Different Configurations

Basically a normal development life cycle, but with twin timelines. There's the main app, and a fork of it that's derived merely by a different combination of the available patches. Patch queues would work well but we use a build server to produce the builds which requires us to publicly push committed changes (as far as I can figure out) to a remote repo.

My question is really about what the easiest way to manage this is, at the actual source control level. What we've done in the past is (using Mercurial) maintain two repositories (one per configuration) and all features / bugs would get imported as needed as patches. Removing items would be done using a variety of ways, backouts probably being the most common. The problem with this is that the two repos ended up wildly different from each other with different items being applied at different times. So the entire changeset stack would be a different order.

What we're thinking about doing, is still maintain two separate repos, but every effort (features, bugs) would be developed as a branch and that branch gets pushed to the repo it's needed in. Within a given repo, if the branch is wanted in the upcoming build, it gets merged in the build branch which is monitored by our Jenkins server and produces the builds.

Is there a better way? An ironed out best practice that prevents messy build branches as a result of backing out items, and possibly even other issues that we don't know about yet?

  • 1
    If I were you, at this point I would try to move away from managing features on the repository level and instead incorporate selective feature management in the app itself - something like martinfowler.com/bliki/CanaryRelease.html (and then of course maintain a single code base) – Pawel Gorczynski Jan 8 '19 at 10:12
  • 1
    @PawelGorczynski: I guess you meant Feature Toggles? – Doc Brown Jan 8 '19 at 21:33
  • @DocBrown yeah, seems so, thanks for the wording :) – Pawel Gorczynski Jan 9 '19 at 15:43

Short answer

Single repo with Mercurial Queues for any amount of "configurations"

Longer answer

If all features are just patches on top of common clean code-base, MQ is your best friend: you can have every feature (even as WIP) in separate MQ-patch and apply|unapply when it needed. Because MQ-patches aren't part of repository (FIXME!) and if feature can be developed|used more than one developer, you can also be interested in MQCollab extension in order to share MQ-patches in easy and natural way between different locations

More longer answer

If all your future MQ-patches are independent of others (by design and idea - by code is the responsibility of the end developer), you can use single queue and just change order of patches in it before applying to code

If your patches will have internal dependences (bad idea, but... shit happens), you can separate dependent patches into separate queues with own stack of patches (main+dependent) in each and apply patches not "by patch", but "by full queue"

What we're thinking about doing, is still maintain two separate repos, but every effort (features, bugs) would be developed as a branch and that branch gets pushed to the repo it's needed in.

Congrats, you rediscover "Release Branch" strategy in 2019. And yes, it works in a lot of cases and can work for you too

  1. You can use single repo with "branch per task" workflow
  2. Release Branch is permanent branch with merge-only commits in it (by policy) - no backouts, no hotfixes
  • Since Patch Queues aren't a part of the repository, our build server wouldn't be able to see it to make the build. Also, for a little self defense, we have been using a release branch strategy for a few years elsewhere, but it's been an issue of migrating and this project, with it's bizarre multi-config testing requirements has been left until last. – CrazyPenguin Jan 8 '19 at 14:29
  • I took a look at MqCollab as that sounded interesting, but it needs to be updated to work with the newer versions of Mercurial. As an example, it's using cmdutil.command which was dropped back in May 2018 – CrazyPenguin Jan 8 '19 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.