Inconsistency between branch.protected attribute and project.protected_branches api
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
Sometimes, but not always, when I create a branch and then protect it using the protected_branches api the branch.protected attribute will still be false
and this never seems to change even after many minutes/hours. This seems inconsistent at best and can lead to problems with other code that checks the branch.protected attribute.
See also the discussion here: https://github.com/python-gitlab/python-gitlab/discussions/2730
Steps to reproduce
This not reliably reproducible, and I suspect a race/timing issue in the GitLab.com backend. When automating the mass creating/protecting branches in a large group of projects I see approximately 10% of projects exhibit the problem, but have no way to reliably force the failure case.
I create the branch and protected branch state like this:
file.save(
start_branch=project.default_branch,
branch=f"{branch_name}",
commit_message="First commit to new branch",
)
# A delay before using the protectedbranches API on the new branch
# as while the 'protectedbranches' config is updated the 'branch.protected'
# attributes is never set. Even if the branches.get() returns the branch.
# But even with a 20 second sleep the problems is still present! :-(
# Possibly some race in the GitLab backend?
sleep(20)
project.refresh()
new_branch = project.branches.get(f"{branch_name}")
protected_branch = project.protectedbranches.create(
{
"name": new_branch.name,
"merge_access_level": gitlab.const.AccessLevel.MAINTAINER,
"push_access_level": gitlab.const.AccessLevel.NO_ACCESS,
"unprotect_access_level": gitlab.const.AccessLevel.MAINTAINER,
"allow_force_push": False,
}
)
sleep(20)
self.refresh()
new_branch = self.branches.get(f"{branch_name}")
if not new_branch.protected:
log.warning(f"Branch {new_branch.name} not protected: {self.path_with_namespace}")
and most of time it works, but sometimes, and no matter how long the sleep both between creating the branch and protecting it, and checking branch.protected
, the branch still has branch.protected
set to false
when it should be 'true' and this never changes even when checking later.
What is the current bug behavior?
I'll see the branch protected attribute is false
:
$ gitlab --output json project-branch get --project-id group/project --name foo | jq
{
"name": "foo",
"commit": {
"id": "9b6de136b5f0158c60844f85286a593cb70fb364",
"short_id": "9b6de13",
"created_at": "2023-11-23T15:56:19.000+00:00",
"parent_ids": [
"05c8c94ed407499279b2a552e7ee9bb03e859b7b"
],
"title": "First commit to new branch",
"message": "First commit to new branch",
"author_name": "Nick Brown",
"author_email": "nick@foo.com",
"authored_date": "2023-11-23T15:56:19.000+00:00",
"committer_name": "Nick Brown",
"committer_email": "nick@foo.com",
"committed_date": "2023-11-23T15:56:19.000+00:00",
"trailers": {},
"web_url": "https://gitlab.com/group/project/-/commit/9b6de136b5f0158c60844f85286a593cb70fb364"
},
"merged": false,
"protected": false,
"developers_can_push": false,
"developers_can_merge": false,
"can_push": true,
"default": false,
"web_url": "https://gitlab.com/group/project/-/tree/foo"
}
while there is definitely protected branch state:
$ gitlab --output json project-protected-branch get --project-id group/project --name foo | jq
{
"id": 85715646,
"name": "foo",
"push_access_levels": [
{
"id": 100709939,
"access_level": 0,
"access_level_description": "No one",
"deploy_key_id": null,
"user_id": null,
"group_id": null
}
],
"merge_access_levels": [
{
"id": 91311949,
"access_level": 40,
"access_level_description": "Maintainers",
"user_id": null,
"group_id": null
}
],
"allow_force_push": false,
"unprotect_access_levels": [
{
"id": 40016310,
"access_level": 40,
"access_level_description": "Maintainers",
"user_id": null,
"group_id": null
}
],
"code_owner_approval_required": false,
"inherited": false
}
and even checking this again several hours later branch.protected
is never 'true'.
What is the expected correct behavior?
That after using the protect branches api that the branch api always has branch.protected set to true
.
Output of checks
This bug happens on GitLab.com
Possible fixes
There does not appear to be any work-around.