53

We recently had a problem whereby a feature for our webapp (automatic signup) was postponed by management because they felt the start was too "cold" but they wanted all the other features we had been working on to go live.

The problem is that this functionality had been merged into develop when it was finished along with all the other features that we expected to push live on the next release so we couldnt just merge dev -> test -> master like we usually do.

How could we have avoided this issue?

  • Depending on your point of view on how you want to solve that, this question is better fitting for the workplace, if you are not looking for a technical solution. – Malavos Sep 3 '15 at 16:32
74

One approach is feature flagging it. It can live in the code base but be disabled by configuration.

Another option it to make a revert commit that reverts the feature merge so that it's not in develop any more. A new branch can be made which reverts the revert, and be left pending to merge later. If you're using Github pull requests, you can do this easily with the "revert merge" button on a merged pull request.

  • 9
    Doesn't configuration flagging imply a doubling of the testing effort for that code? You've got to test both paths. – user40980 Sep 2 '15 at 13:20
  • 16
    In this case, since you won't be turning on that flag in production, you could test the off case now for the release, then test the on case when it's ready to go to prod. That should be approximately the same work as testing a revert and recommit. – Alan Shutko Sep 2 '15 at 13:44
  • 4
    The common term is Feature Toggle. If there is a small "feature entry point", this can probably be done after the management decision. If not, one will get problems with this method as well as with any method, too. – Doc Brown Sep 2 '15 at 14:04
  • 3
    We have features that are in development for 6+ months that are hidden by Feature Toggling, as Doc Brown called it. This also allows us to test the feature (or absence of it) in non-production environments. Sometimes these features add on to existing features, in which case we should have unit tests for both the old and new feature set. Each unit test would just set the flag to whatever it needs to do the current test. – ps2goat Sep 2 '15 at 18:15
26

How could we have avoided this issue?

From a process perspective, figure out:

  • Who was the decision maker to start this work?
  • Why did the decision to release this feature change?
    • Missed expectations?
    • Miscommunication?
    • Inadequate business support?
    • No customer involvement?

More than likely there were drops in communication along the way. This is important to have because when it doesn't work, your development process(es) will be based on false and wrong understandings of business requirements.

  • 9
    +10. As soon as management started to doubt the release of the feature, they should have informed the developers, so that the possible removal could have been taken into account when deciding to merge the feature into develop. – Bart van Ingen Schenau Sep 2 '15 at 13:37
  • 14
    This isn't a very constructive answer - sometimes things go sideways for all manner of reasons. Sure, finding out that it shouldn't be merged sooner rather than later is important, but that doesn't mean eventually a feature will be pulled at the last minute. Maybe contract changes, maybe your customer doesn't pay up, maybe legal issues appear.. you still have to manage the problem instead of pointing the finger of blame – gbjbaanb Sep 2 '15 at 15:17
  • 11
    If there are people in your organisation who are sufficiently powerful to refuse to admit fault, and also sufficiently childish not to wish to avoid faults, then you should still post-mortem problems for your own information. You just don't want to tell them (or write it down too explicitly). That said, enderland does not use the word "blame", and if the organisation interprets this advice as "find out who is to blame" then that is in itself a problem for the organisation to work on. All this says is "understand why the problem occurred", which is essential to avoiding it in future. – Steve Jessop Sep 2 '15 at 15:35
  • 2
    I completely agree, this is a management screwup, not a developer one. – durron597 Sep 2 '15 at 16:02
  • 3
    @enderland my point is that you cannot avoid some problems, so you have to consider how to repair the situation. Hopefully you won't get that far very often, but its bound to happen sooner or later so plan accordingly. – gbjbaanb Sep 2 '15 at 16:55
19

Forget for a moment the issue with your management, and imagine you had the "automatic signup feature" already in your latest production release, deeply integrated into your codebase. Now you get the new requirement to add an "off-switch" for "automatic signup". How would you handle this in your Git workflow?

I guess you would declare "disabling of automatic signup by configuration" simply as an additional feature (it is just a form of Feature Toggle), so this should integrate smoothly into your workflow. You can estimate the effort, if you like you can use a feature branch for it (or not, if you do not use feature branches for such issues). And you can definitely use the usal "merge dev -> test -> master" flow you described.

And that is actually the way you can handle this in your current situation. From the viewpoint of the git workflow, it should not matter if the change request comes from management for release 1.0, or if the change request is a new customer wish for release 2.0.

  • Fowler has some really good output, but I can't support this method for feature introduction. The coordinated effort for such switches seems like an unnecessary burden. I can support adding feature toggles to remove features after merge, but building in a switch as part of the requirement makes me uncomfortable. – Gusdor Sep 3 '15 at 8:53
  • @Gusdor: see my edit. – Doc Brown Sep 3 '15 at 12:57
1

This is the exact issue I have with gitflow and GitHub flow, and it seems that with web applications this happens often - or more like the norm. It seems you would either resolve this issue retroactively (mentioned above) or proactively (example below).

I've created 'bundle branches' in addition to the standard gitflow branches. The bundle consists of all the features that are ready for uat/qa. A list of uat/qa features are created. These are merged into the temporary bundle, and that bundle gets deployed to uat/qa. Any bug fixing happens on the original feature branch, and that gets remerged back into the bundle and deployed. This separates the coming release as well as allows testing those features together prior to them finding their way to the develop branch. Those branches that are approved get a pull request into develop - following the gitflow process. Test ready features can be added to or removed from the temporary bundle branch and redeployed.

  • This keeps master always reflecting production-ready state (can automate with hook)
  • Develop always reflects latest delivered (and tested) next release candidate

Cons include managing the bundle list and adding another branch type; however, besides the retro fix, which I think is too late, this seems to be the more viable solution.

With a GUI addon, it might be optimal to tick off feature branches per bundle deployment - with automation in mind.

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