Skip to content

Add more options to branch.protect() function #1355

Closed

Description

@anderslindho

The branch.protect() function currently supports two arguments:

developers_can_push: bool
developers_can_merge: bool

per https://python-gitlab.readthedocs.io/en/stable/gl_objects/branches.html

Since gitlab allows for more granularity than this, I would propose adding the arguments:

maintainers_can_push: bool
maintainers_can_merge: bool

The documentation appears to support this by specifying a higher access level (60): https://docs.gitlab.com/ce/api/protected_branches.html#protected-branches-api

Activity

  1. JohnVillalovos commented on Mar 2, 2021

    @JohnVillalovos
    Member

    Have you looked at:

    https://python-gitlab.readthedocs.io/en/stable/gl_objects/protected_branches.html

    Create a protected branch:
    
    p_branch = project.protectedbranches.create({
        'name': '*-stable',
        'merge_access_level': gitlab.DEVELOPER_ACCESS,
        'push_access_level': gitlab.MAINTAINER_ACCESS
    })
    
    Create a protected branch with more granular access control:
    
    p_branch = project.protectedbranches.create({
        'name': '*-stable',
        'allowed_to_push': [{"user_id": 99}, {"user_id": 98}],
        'allowed_to_merge': [{"group_id": 653}],
        'allowed_to_unprotect': [{"access_level": gitlab.MAINTAINER_ACCESS}]
    })
    
    
  2. JohnVillalovos commented on Mar 2, 2021

    @JohnVillalovos
    Member

    Interestingly it looks like the code is calling an undocumented API. Maybe it was previously documented.

    https://docs.gitlab.com/ce/api/branches.html

    @exc.on_http_error(exc.GitlabProtectError)
    def protect(self, developers_can_push=False, developers_can_merge=False, **kwargs):
    """Protect the branch.
    Args:
    developers_can_push (bool): Set to True if developers are allowed
    to push to the branch
    developers_can_merge (bool): Set to True if developers are allowed
    to merge to the branch
    **kwargs: Extra options to send to the server (e.g. sudo)
    Raises:
    GitlabAuthenticationError: If authentication is not correct
    GitlabProtectError: If the branch could not be protected
    """
    id = self.get_id().replace("/", "%2F")
    path = "%s/%s/protect" % (self.manager.path, id)
    post_data = {
    "developers_can_push": developers_can_push,
    "developers_can_merge": developers_can_merge,
    }
    self.manager.gitlab.http_put(path, post_data=post_data, **kwargs)
    self._attrs["protected"] = True

  3. JohnVillalovos commented on Mar 3, 2021

    @JohnVillalovos
    Member

    It appears that branch.protect() was likely a v3 API thing. I'm guessing v4 still supports it but it is undocumented. I have not personally tried it.

    https://gitlab.com/gitlab-org/gitlab-foss/-/blob/8-16-stable/doc/api/branches.md

  4. anderslindho commented on Mar 3, 2021

    @anderslindho
    Author

    I had not seen the first link you provided - I will try out that approach.

    I have tried the branch.protect() function and can verifiy that it at least works with v4.

  5. anderslindho commented on Mar 3, 2021

    @anderslindho
    Author

    I've tried this alternative approach now (project.protectedbranches.create()), and it doesn't seem to work as intended - nothing updated in the UI and it appeared as if I could still push (albeit that part is a little bit trickier to confirm as I don't know the intention behind the 60 status level; me being owner of the repo might still qualify here).

  6. JohnVillalovos commented on Mar 3, 2021

    @JohnVillalovos
    Member

    Might be something like this:

        print("Deleting any existing projected branch info for:", args.branch)
        try:
            project.protectedbranches.delete(args.branch)
        except gitlab.exceptions.GitlabDeleteError:
            pass
        print("Protecting the branch:", args.branch)
        p_branch = project.protectedbranches.create(
            {
                "name": args.branch,
                "allowed_to_push": [{"access_level": gitlab.NO_ACCESS}],
            }
        )
        print("Protected branch:", pprint.pformat(vars(p_branch)))
    

    In the UI I then see that "No one" is allowed to push.

    I was also unable to do a git push to that branch.

  7. anderslindho commented on Mar 3, 2021

    @anderslindho
    Author

    That worked brilliantly - thank you very much! 🙏

    So my mistake was either:

    • that it expects a list as argument (seems unlikely due to the examples in the documentation)
    • that I typed in some minor error somewhere; but what's odd then is that everything seemed to work on the CLI-side (project.protectedbranches.list() showed that I had created new entries).

    Either way, there doesn't seem to be any reason to keep this issue open any longer. Thank you for the help!

  8. locked as resolved and limited conversation to collaborators on Mar 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions