Reputation: 837
I have recently started using Git and have recently me & my team have agreed on below workflow. We don't use CI/CD and there are no future plans for it yet. We have 3 environments for testing:
Currently we are following feature branch workflow and our branching structure is as follows:
master -> integration
master -> devtest
master -> preprod
We are a team of 6 developers and at any point of time different features need to be available on dev test and preprod environments.
All features are checked out from master and after development is completed, for first round of testing we merge the feature into devtest branch.
Once this is approved by tester, feature is merged into preprod branch for UAT. After getting approval we merge this changes to integration branch and finally merge to master after deployment. Also create a tag after merging integration into master.
Q1. Since we are not advanced git users, I want opinion on this branching strategy, if there could have been a better alternative, flaws in this approach or improvements.
Q2. I am currently looking into git flow
and git flow avh
, but both of them do not support my branching strategy. Is there a way to configure those commands as per my need?
Thank you in advance.
Upvotes: 1
Views: 794
Reputation: 2818
Although you already mentioned it in your question, I would suggest sticking close to the vanilla Gitflow Workflow outlined by Atlassian.
There usually isn't a need to have a separate branch for each environment, as you've described. This strategy is going to add unnecessary branching overhead with no additional value for your dev team.
Keeping master
as your snapshot of what's in prod is great. You can spin off hotfix branches from there if the need arises.
I would maintain a develop
branch (off of master
) that you use as the parent for all of your feature branches. When you've added a sufficient amount of features to develop
and you're ready to spin off a release, then create a release branch. You can promote that release branch through your environments and make changes as needed.
Once you're ready for prod, merge your release branch into master
and tag it. If you made additional changes to the release branch after forking off of the develop
branch, you'll want to merge those in to develop
, as well.
When you get to the point of setting up CI/CD, I would use the develop
branch for CI builds and releases to you dev environment (or whatever you call your lowest tier environment). Then you can get continuous, immediate feedback on your changes. Then you can use release branches to drive the automation of releases to your other, higher environments.
UPDATE: New Scenario
You know you're cutting a release branch tomorrow and you have five developers who have finished with their feature branches this morning. You have many options to "gate" their merge into develop
.
You can discuss at your stand-up or planning meeting, "Hey--I've finished my work on XYZ, should I merge it in to develop
"? This is a great opportunity for your tech lead, PO, whoever to say, "No, we're planning to cut a release tomorrow and we don't want your changes included."
You can also lock the develop
branch, only allowing merges via merge/pull requests. When a merge request for a feature branch comes it, then you decide: should this be included now or should we hold off until the next release?
So, perhaps only three of the five feature branches get merged into develop
before you cut the release. Great -- that's what you want.
The feature branches are not going to spontaneously disappear. While you should try to merge them in to develop
as soon as you can, you don't have to merge them in immediately. You can hold off if you need to hold off.
UPDATE: Address Comments
If you MUST cherry-pick features branches to promote to your UAT environment, then you can attempt to do this with your release branches. Your five developers all finish developing their features and merge their changes into the develop
branch (don't delete the feature branches like you normally would). The feature branches associated with the features that are "approved" can be merged in to a new release branch that is forked off of master
. That release branch is ready for UAT (or whatever other environments are appropriate).
I would strongly urge against this strategy. It's going to be messy and completely cumbersome.
Instead of micro-managing feature branches between develop
and release branches (described above), get your features "approved" before you start developing them. Once features are successfully merged in to develop
(use merge/pull requests for a code/quality review process), their associated feature branches can be deleted. Once develop
is in a good enough state to cut a release branch, fork develop
and create a new release branch that is promoted through your many environments.
If a feature branch is merged into develop
, but the business has changed their mind and wants the feature removed, then create another feature branch that removes it. If a feature branch is merged into develop
, but the the dev team has decided that the changes from that branch introduce bugs or unreasonably add to your tech debt, then reevaluate your code review process and make a new feature branch that removes those unwanted changes. Aim to update the develop
branch to be the next release. Once it's ready, cut a release.
If a feature branch shouldn't be merged in to develop
(because of approval or whatever other reason), then don't merge it.
Feature Toggling (Not via Source Control)
There are dev teams that strive to make their new features toggle-able via some sort of configuration mechanism. This introduces additional programming overhead since you must build in a way to enable/disable your new features. Now you have more code to write, test, and maintain. You also have to micro-manage any cross-feature dependencies that arise. You may build Feature C with the understanding that it will ship with an enabled Feature A, but the business decides to disable Feature A for the next release. What could go wrong?
Although, this technique allows teams to ship new features as they are added to the codebase without having to enable them for the end user. That means your "unapproved" features can still be included with the rest of the features when cutting a release branch, but they will be disabled. I would try to avoid doing this, if possible, as it can get overly complicated. It may be a strategy you decide to employ, however, if your product owners are demanding such flexibility. Be sure to remind them that this is a costly tactic, though.
Read more on feature toggling if this interests you. Martin Fowler did a pretty nice writeup on it.
Upvotes: 1