Implementing Gitflow with TeamForge and Gerrit Part III – Alternative approaches.
In this blog post series we talk about access right mappings between TeamForge and its Gerrit integration. The topics covered by each part are:
- in Part I: What Gitflow is, and how to best use it with TeamForge/Gerrit user defined repository policies.
- in Part II: How to implement your own user-defined repo category with branch based permissions in TeamForge 7.1 and Gerrit 2.6.
- in Part III: Alternative approaches to implement branch based permissions (without user-defined repo categories) and when to use which approach.
Target audience: Project admins, Gerrit administrators using our TeamForge integration.
In the first part of this serie, we have looked into Gitflow’s branching model, configured it in TeamForge via a user-defined repo category called gitflow and verified that it actually works as expected.
In the second part, we have created the gitflow repo category by modifying the mappings file – TeamForgeMappings.xml on the server. So, far so good – this method is recommended, as it allows you to define the new category once and forever. The newly created category can be used across all your Git repositories. However, it does have one drawback: it requires access to the server filesystem to modify the mappings file and restart Gerrit. What if you don’t have such an access? In this case there is no way to add your newly created repo category. That’s true, but… do not panic! Fortunately there are two other options to set up the same access rights:
- Turn off the TeamForge auto-pilot by using our Custom category and by configuring access rights in Gerrit’s UI
- Use an already existing repo category as starting point and modify it so that it fits the required setup
Let’s have a look at both approaches.
The first one has already been described in my blog post about Managing Git branch level permissions with TeamForge and Gerrit but, as we have a new version of Gerrit and a new version of TeamForge, we will look at it again.
So how to implement gitflow model using custom repo category?
It is quite straightforward.
Implementing gitflow with Custom
category
First we have to go to TeamForge and create a new repository with custom category:
We don’t need to put [RepoCategory:custom]
entry into the description anymore. Instead we choose Custom from Repository Category
options. After the repository gets created we go to the Gerrit project corresponding to this repository (It will be custom_repo project) and click on Access
(to get to the access rights) and then click on Edit
button.
You have probably noticed that this page in our current version of Gerrit is quite different from what it was in version 2.1. Nevertheless, this is the place where you are supposed to add all the necessary rights for the gitflow model.
Now we are ready to start adding the access rights needed by gitflow. But wait – there is one hint: we won’t start from the Custom category, as this one is almost empty initially and adding all the rights would mean a lot of manual work to perform. Life is too short for that so we will use the fact that in the Custom category all rights added on Gerrit side are preserved. That means that if we switch the repo category to any other category (like Default) and then back to Custom we will get all the rights defined in Default category available in Custom.
Let’s do that: We go to Edit Repository
screen in TeamForge, switch the Repository Category to Default and click Save
. Then we go to edit repository again and select Custom Repo Category this time and click Save
again. After going back to our Access page on Gerrit you will see all the default rights, and that’s despite the fact that our repo category is Custom. So, instead of adding everything from scratch, we will actually modify the Default category to fit the gitflow.
Let’s start with Reference: refs/*
. After editing it should look like this:
that means that we have to perform the following steps:
- Remove Developer and Release Manager group from
Create References
. - Add Developer to
Forge Author Identity
. - Remove Release Manager from
Forge Committer Identity
. - Remove Developer and Release Manager from
Push
. - Remove all entries for
View
,Publish
andDelete Drafts
. - Add Developer and Release Manager to
Push Merge Commit
.
After those modifications we are done with Reference: refs/*
section.
In a similar way we have to modify References refs/for/refs/*
and refs/tags/*
. Here how it should look like just before hitting the Save
button:
And after saving:
At this point the remaining part is about adding the missing references for gitflow related branches: develop
, features/*
, hotfix/*
and release/*
. Here it goes:
And the last thing to do is to allow Release Manager to force push directly to master
:
After clicking the Save
button our setup is ready – gitflow can be used as intended which basically means that we are done.
As you can see, it is not the easiest approach to configure gitflow. But, thanks to our category switching trick we were able to perform all the changes in reasonable time. Remember that if you have another repository in gerrit you will have to repeat the work again (unless you play with Project inheritance which will let you do your changes in the parent project and inherit from it).
Now we can look at the second approach.
Implementing gitflow using internal Gerrit groups.
I have to admit that this approach does not allow to implement the gitflow model completely. But, I’ve included it as I feel that our journey through controlling Gerrit access rights from TeamForge wouldn’t be complete without describing this possibility. Plus, this approach is really useful in some cases.
So, what it is about? It is about creating an internal group in Gerrit and adding the TeamForge user groups in Included Groups
of this group.
Why would you need it?
Well, in all pre-defined categories other than Custom if one modify rights on Gerrit side those modification will be lost upon the sync between TeamForge and Gerrit. That’s why we had to use Custom repo category in the previous example. What if we wanted to use Default repo category instead? That’s where internal Gerrit groups come into play.
So let’s start with a repo with Default category, as we aready known that this category is the most similar to the gitflow one. We will configure references refs/*
for the Developer. Note that we cannot modify access rights for TF: demo: Developer
group anymore, because those modification will be wiped out during sync process (as we are using the Default category). What we do instead is to create internal Gerrit group called gitflow developer
which includes TF: demo: Developer
group. As the newly created group is internal the synchronization with TeamForge will not affect it. Here’s how to proceed.
First let’s go to Gerrit -> People -> Create New Group
and create a new gitflow developer
group:
As you see on the screenshot above we can add TF: demo: Developer
to included groups of gitflow developer
group. Of course, to implement gitflow model we would also need to create gitflow admin
, gitflow release manager
and gitflow observer
roles, each of which will include corresponding TeamForge group in included groups. I’m not going to go through that at the moment but you’ve got the idea.
Now, let’s have a look at Developer rights for references refs/*
in Default category. We know from the previous example (with custom category) that for Developer we will have to:
- Add Developer to
Forge Author Identity
andPush Merge Commit
. - Remove Developer from
Create References
,Push
andPush Merge Commit
.
Adding rights is simple – we just go to the project access rights page and add the rights there.
But what about removing permissions? Unfortunately, there is not much we can do. Well, we could try to use the BLOCK access rule
, but we don’t want that as this would have blocked everything below refs/heads/*
including our develop
, stable
, hotfix
and feature
branches, with no possibility to overcome it. The Exclusive Flag
is also not up to this task because there is no good way of applying it on refs/heads/*
. So the only option we have is to leave refs/heads/*
unchanged and restrict the access to remaining branches. That is we will modify access rights for refs/heads/develop
, refs/heads/hotfix/*
, refs/heads/release
and refs/heads/feature/*
branches.
Let’s have a look at refs/heads/hotfix/*
as an example, as other branches will be configured in a similar way:
Two things to notice:
- We use our newly created internal user groups instead of TeamForge groups to make sure the rights won’t get wiped out by TeamForge.
- we use
Exclusive flag
which basically prevents the access from people that do have access toref/heads/*
but don’t belong to developers nor release managers.
As you can see, this approach is far from optimal. One can add some rights but usually it is not possible to restrict them. Actually, I would recommend this approach only, if the existing repo category is almost there and some small modifications to gerrit access rights are required. Please also note that starting from Gerrit 2.7, you will need a special capability Create Group
to create a new internal Gerrit group.
And… that’s all folks. Congratulations, you have just finished the third (and last) part of my blog – alternative approaches to implement branch based permissions. After reading all three parts you should have a quite comprehensive knowledge about setting up Gerrit access rights and controlling them from TeamForge. What is your experience? Do you agree with my suggestions? Do you have other ideas? Which approach would you use and when? Please share your thoughts so others can benefit from it.