[go: up one dir, main page]

Persisted branch rules design concepts

🥅 Goal

This issue will hold design concepts for how we could proceed with Branch rules moving forward as a part of the Branch rules refactor in &17485.

📘 Context

What are branch rules?

  • Branch rules are the guardrails that protect the most important code branches in a repository
  • Rules that enforce quality standards by controlling how code can be pushed, merged, and deployed in a branch
  • Security and compliance automatically built into the development workflow
  • GitLab Branch rules are an evolution of our former offering of Protected branches. See them at Settings > Repository > Branch rules.

Why do they matter to enterprise customers?

  • Regulatory Compliance
    • Automatically enforce approval workflows and create audit trails required for industry standards and compliance frameworks
  • Risk Mitigation
    • Prevent costly production outages and security vulnerabilities by catching issues before they reach critical systems
  • Quality at Scale
    • Maintain consistent code standards across hundreds of developers and repositories without manual oversight and bottlenecks

👤 Job performers

See #554196 (comment 2698832047)

Repository manager

I oversee multiple development teams in my enterprise organization. I need branch rules to maintain code quality and compliance within my organization with hundreds of repositories and developers. I need the confidence that critical systems are protected, without slowing down my developers or become a bottleneck in their workflow. When organizational standards shift, I need to easily update repository protections for the hundreds of repositories I manage.

Code author

I write code everyday for my enterprise organization, and I need to contribute confidently without worrying about accidentally breaking production or violating company policies. I want to write code efficiently, create test environments, and debug without organizational policies blocking my workflows. I need a clear understanding of what organization policies are so I can effectively adhere to them.

🤝 Values of enterprise customers

See #554196 (comment 2698830930)

From analyzing the feedback we've gotten from users about GitLab's Branch rules in #554195, these are the core values that our enterprise customers care about most:

Compliance

Give users robust protection for the code that makes their business run. Investing in compliance to protect code is less risky and expensive than dealing with a critical incident.

  • Enforce code quality
  • Security standards
  • ROI through risk reduction / prevention of unauthorized changes

Confidence

Build unshakeable trust in the system. Users who can trust a system / company with protecting their code are trusting you with a critical piece of their business success. The system should be predictable and scalable enough that users are confident about how rules and conflicts will resolve.

  • Trust that settings are properly configured to maintain compliance
  • Confidence in the safety nets protecting code

Scale

Make growth effortless. Enterprise organizations with hundreds of repositories and hundreds of developers should be able to manage protections with ease. Allow users to switch from other platforms by quickly setting up branch protections for hundreds of repositories. When organizational requirements change, the system should allow repository managers to easily respond and enforce compliance.

  • Set up and manage hundreds of repos
  • Smooth collaboration with hundreds of devs
  • Security & compliance at scale

Flexibility

Give organizations governance without friction. Developers want to quickly and efficiently write compliant code without being blocked. The system should accommodate varying team needs, as sometimes teams want to quickly test and debug code without restriction. Developers need to clearly understand what branch protection rules apply to them, so they can write compliant code.

  • Fast but compliant development
  • Governance without friction
  • Custom workflows for varying team needs

values.jpg

Vision statement

See #580568:

Empower teams to protect and manage branches confidently and flexibly at scale.

[WIP] Source Code Branch Rules_ Design vision.jpg

⛰️ Key challenges

See #554196 (comment 2885775628)

Key constraints

Avoiding breaking changes

  • We need to create a system that can scale to serve enterprise needs, while also supporting the old system that doesn’t fully serve user needs
  • Adding Settings to GitLab is high risk
    • Vital dependencies
      • Customer codebases are dependent on the choices we make
      • Other areas of GitLab are dependent on Source Code settings 
    • Settings changes are irreversible and additive
      • We need to support every settings decision we make, good or bad, to avoid breaking changes
      • As we continually add more settings without designing for the larger picture, the system grows more complex and difficult to understand

Avoiding unnecessary system complexity

  • To avoid breaking changes, a common iterative solution at Gitlab to introduce system changes to Settings is to add another setting
    • Pros (short-term)
      • Easier/faster to implement 
      • Easier to iterate on
    • Cons (long-term)
      • More complexity for us to maintain/for customers to understand
      • If the foundation is not sound, the system becomes unnecessarily complex and confusing
      • Enterprise customers have expressed increasing frustration with the foundational choices of GitLab Branch rules: #285560 #39115 (closed)

Key design challenges

Rule conflict handling

When a branch matches multiple rules, branch rule conflicts resolve in inconsistent ways, leading to poor predictability and confidence in the settings that protect the repository’s most important code.

Inheritance across groups/projects

Organizations need scalable solutions for branch-level settings. Only a small subset of branch rules are available on the top group level, and settings are not enforceable between groups and projects, leaving enterprise users starved for configuration at scale. 

Limited settings per branch rule

Only a small subset of our available settings are available in Branch rules today. Adding additional settings on a branch-level basis are some of the most frequent requests we receive from enterprise customers.

Visibility of system status

The system today leaves users unconfident in branch-level protections due to poor visibility for:

  • What rules apply to them as an end dev
  • How rule conflicts resolve
  • How inherited rules resolve across groups/projects

📄 Rule conflict handling

See #554196 (comment 2885786324)

If one branch matches multiple branch rules, how does GitLab protect the most important code in my repository?

Context

GitHub vs. GitLab rule conflict handling

Rule conflict handling diagram Notes
GitHub

current-github.png

  • Simple, predictable, protective
  • In the event of a conflict, the system is more restrictive for code protection
  • Docs
GitLab

current-gitlab.png

  • Inconsistent, unpredictable, unprotective
  • In the event of a conflict, the system often takes the most permissive rule = code less protected

Users are not happy about the way we handle rule conflicts

How did we get here?

Developer velocity > compliance

  • In early stages of growth, GitLab prioritized developer freedom and velocity
    • More branch rules = more restrictions = slower development
  • GitLab’s target customer has now shifted to Enterprise organizations with a growing need for: top-down compliance, regulation at scale, and governance without friction

Iterating without a cohesive end goal

  • Breaking changes used to be allowed, so it was easier to reverse decisions
  • Delivering small, iterative changes without assessing the long-term impact to users, the product, and system maintenance

Rule conflict model

Option 1: Most specific name match

In the event of a branch rule conflict, the system chooses the rule with the most specific name match, similar to CSS.

  • If there is not a more specific name match, the system chooses the most restrictive setting
  • Branch rule inheritance between groups > projects still uses Cascading Settings.
Example

Consider this scenario where 1 branch matches multiple rules:


mostspecific-1.png

If multiple branch rules apply to 1 branch, the branch rule with the closest matching name is chosen, similar to the model used in CSS. If there’s not a closest matching name, the most restrictive individual setting is applied. 

mostspecific-2.png

Pros Cons
  • Predictability: Users can easily understand how rules will resolve based on naming rules (like CSS)
  • Control: Users can create structured systems to target specific branches 
  • Security: the most specific name match setting may not always be the most protective setting
  • Reliance on naming: Conflict resolution relies mostly on naming conventions
  • Edge case complexity: In the event that branch rules have the same level of specificity, then another layer of conflict resolution rules must apply

Option 2: Most restrictive

In the event of a branch rule conflict, the system chooses the specific setting that is most restrictive. Branch rule inheritance between groups > projects still uses Cascading Settings.

Example

Consider this scenario where 1 branch matches multiple rules:

mostspecific-1.png

If multiple branch rules apply to 1 branch, each individual setting is evaluated, and the most restrictive setting is applied. Approval rules/status checks are additive, which is essentially more restrictive.

mostrestrictive.png

Pros Cons
  • Security: In the event of a conflict, the system will automatically apply the most restrictive individual setting
  • Predictability: It is not as easy for users to predictably understand how conflicts will resolve, as settings are evaluated on an individual setting-by-setting basis

Predictability vs. security

What do enterprise users value most?

Source Code Branch Rules_ Design vision.jpg

We need to increase our confidence

Which system best serves user needs?

New model introduction method

How do we shift an architectural aspect of Branch rules without breaking changes and unnecessary system complexity?

*Option 1: Create a new system & migrate (Recommended)

Concept screens IA Diagram

Existing user experience - initial announcement:

Existing user experience.jpg

Existing user experience - nudge for migration:

Classic branch rule created.jpg

Newly created project:

First time user experience.jpg

Migration + most specific name match

migration-ia-mostspecific.png

Migration + most restrictive

  • * Note: “Additive” means rules are added together, which is essentially “most restrictive”

migration-ia-mostrestrictive.png

How the system scales

migration-ia-mostrestrictive-potentialfuture.png

Pros Cons
  • Predictability for users: users have 1 system to understand, targeted to enterprise needs.
  • Cleaner maintenance: Allows us to build a clean system targeted for customer needs. Users can still choose to use old branch rules, but will be incentivized to use the new one.
  • Old system will be phased out: Newly created projects will use new system by default. Usage of old system will decline.
  • Migration is painful: Migration is extremely painful, risky, and time consuming for users. Some may never migrate.
  • Maintaining 2 systems potentially forever: Would need to maintain both systems for unknown amount of time, until usage of the new system is at a reasonable majority.

See #554196 (comment 2885841562) for other options.

🌳 Inheritance

See #554196 (comment 2885860278)

Cascading settings

  • GitLab’s recommended framework for settings inheritance
  • Values defined at the instance/group level are enforced down to child groups/projects
  • Users with higher levels of access can enforce compliance down to subgroups/projects
Cascading settings Current GitLab Branch rules inheritance

cascading-ideal.png

  • Settings defined at higher levels are strictly enforced down to lower levels
  • Optimized for compliance

branch-rules-inheritance-1.png

  • Settings defined at higher levels act as “defaults” at lower levels
  • Good for developer velocity/freedom

branch-rules-inheritance-2.png

  • Projects can override settings defined at higher levels
  • Very bad for enterprise compliance

The way our inheritance works is problematic for enterprise

  • The history of our group-level offering
    • Branch rules evolved from our “Protected branches” offering, which only has 4 settings available on the top group level
  • Why it’s an issue
    • Scale/Flexibility: Only 4 settings available on the top group level
    • Scale/Flexibility: Subgroups not supported
    • Compliance: Users at lower levels can override group level settings

Source Code Branch Rules_ Design vision (5).jpg

How we can solve inheritance

How do we balance compliance for system admins, while maintaining flexibility for end developers? We need to give users governance without friction.

Inheritance proposal

A package solution for inheritance with compliance + flexibility

  1. Cascading settings model (compliance)
  2. Include/exclude patterns (compliance, flexibility)
  3. Bypass settings (flexibility)
  4. Enforceability settings (compliance)
  5. Full sub-group support (compliance, flexibility)

1. Cascading settings model

Concept screens Description

cascading-1.png

  • Optimized for compliance
    • Settings defined at higher levels are strictly enforced down to lower levels
    • Enforcement appropriate for level of authentication
  • Alone, this is not flexible enough for the range of enterprise needs:
    • Hotfixes
    • Monorepos
    • Test/training environments
    • Documentation repositories
    • Third-party contractor/vendor work

2. Include/exclude patterns

Concept screens Description

Flexibility Option 1_ Excludes.png

  • Users want more flexibility in the way they define branch rules
  • An include/exclude system with wildcards can satisfy many of the customer use cases enterprise users have shared with us
    • Regex can be something we consider iteratively adding in the future

3. Bypass settings

Concept screens Description

Flexibility Option 2_ Bypasses.png

  • Bypass settings give users flexibility to define which actors can bypass a branch rule for enterprise needs like: 
    • Developers who handle critical incidents
    • Projects for testing, R&D, or documentation
    • Service accounts like agents or bots
  • Bypass settings are already enabled for merge request approval rules

4. Enforceability settings

Research needed on how much granularity users are expecting: Per entire branch rule, or per individual setting?

Concept screens Description

Option 1: Per entire branch rule

Option 2.1_ Enforceability setting - Per entire branch rule.png

Option 2: Per individual setting

Option 2.2_ Enforceability setting - Per individual setting.png

  • Give users the granularity in defining how strictly settings should be enforced down to child groups/projects
  • The level of granularity for enforcement is something we need further research on:
    • Option 1: Per entire branch rule
    • Option 2: Per individual setting
  • While we want to give users optimal flexibility, this comes at a cost of system complexity, which is more difficult for GitLab to maintain/for users to predict.
    • Do users actually need to be able to set enforcement per individual setting?

5. Full sub-group support

Description
  • Users can only define branch protections today in the top-level group
  • This limits flexibility and does not allow users to fully define structures that work best for their teams
  • Allow branch rules to inherit across the instance > top-level group > sub-groups > projects

⚙️ Limited settings per branch rule

See #554196 (comment 2885905276)

Users want configuration per branch for many settings:

  • We get a lot of user feedback to configure settings per branch
  • Our long-term plan is to eventually integrate many settings into branch rules
  • However, we first need to build a robust system that can scale to serve enterprise needs.

Optimizations we could add for enterprise

🎨 Figma

Description Screen Notes
Flexible include/exclude rule targets

targets.png

Give users flexibility in defining how branches are targeted
Configurations for control

Frame 733.png

  • Protection controlled by the user
  • Restrict unwanted bypasses to branch protections by restricting ranch creation / deletion
Granular merge request controls

Frame 733.png

  • More flexibility in defining how code can be merged
Track settings changes

all features.png

  • View history of changes for vital settings that protect code
Configuration as code

config-as-code.png

  • Allow users to seamlessly scale and track settings changes

🔍 Visibility of system status

See #554196 (comment 2885924498)

As a developer, how do I know which restrictions apply to me so I can deliver compliant code?

It's hard for users to know what's going on

See user stories #554195

asdfasdf.png

Visibility of system status issues

  • Poor visibility for end developers
    • Inherited settings are not clearly communicated in the UI
  • Multiple paths for settings create confusion
    • Branch rules
    • Repository settings
    • Merge request settings
    • Compliance policies
    • Security policies
  • The way these settings all interact with each other is not predictable
    • Evaluation happens at runtime when users create a merge request  
    • Low user confidence that code is protected in the way they intended

How can we help users build confidence in the settings that apply to them and protect their code?

Visibility of system status explorations

Description Screen Notes
Make inheritance clear

user DOES have permission to edit group level.jpg

  • Allow users to easily understand the source of inherited rules
Branch rule evaluation tool

eval tool page.jpg

  • Easily understand the rules that apply to any given branch
  • Users can understand how inheritance and rule conflicts resolve for each branch

Branch rule visibility in Branches page #393142 (closed) by @mle

image (22).png

  • End developers have visibility into what rules apply to them

👣 Next steps

See #554196 (comment 2885931147)

User research (Increasing our confidence in unknowns)

  • Increasing our confidence in the unknowns
  • See #554197
  • We need to better understand:
    • Rule conflict model                             
      • Option 1: Most specific name match
      • Option 2: Most restrictive
    • Inheritance proposal: Enforceability setting
      • Option 1: Per entire branch rule
      • Option 2: Per individual setting
    • Contextual inquiry
      • Understand current user workarounds / automations
      • Uncover opportunities

Alignment

Design iteration

  • Integration of user / stakeholder / design team feedback
  • Finalization of screens and workflows

Implementation

  • MVC implementation breakdown
  • Backend & frontend implementation
  • Post-MVC implementation

Completion checklist

After the concepts are created, they will undergo several feedback loops and iteration to increase confidence in the solution, and make sure we are solving the most important user needs.

  • Check design concepts against user stories in #554195
  • Feedback from Source Code Team
  • Feedback from Create Design Team
  • Feedback from other relevant stakeholders
  • Iteration
  • Feedback from customers in #554197
  • Iteration
  • Design handoff with developer documentation
Edited by Alyssa Trinh