- Data Model
- Controllers and Services
This document explains the backend design and flow of all related functionality about merge request approval rules.
This should help contributors to understand the code design easier and to also help see if there are parts to improve as the feature and its implementation evolves.
It’s intentional that it doesn’t contain too much implementation detail as they can change often. The code should explain those things better. The components mentioned here are the major parts of the application for the approval rules feature to work.
MergeRequest models are defined in
ee/app/models/ee/merge_request.rb. They extend the non-EE versions, because
approval rules are an EE-only feature. Associations and other related stuff to
merge request approvals are defined here.
ApprovalState class is defined in
ee/app/models/approval_state.rb. It’s not
ActiveRecord model. This class encapsulates all logic related to the
state of the approvals for a certain merge request like:
- Knowing the approval rules that are applicable to the merge request based on its target branch.
- Knowing the approval rules that are applicable to a certain target branch.
- Checking if all rules were approved.
- Checking if approval is required.
- Knowing how many approvals were given or still required.
It gets the approval rules data from the project (
ApprovalProjectRule) or the
merge request (
ApprovalMergeRequestRule) and wrap it as
ApprovalProjectRule model is defined in
A record is created/updated/deleted when an approval rule is added/edited/removed
via project settings or the project level approvals API.
ApprovalState model get these records when approval rules are not
protected_branches attribute is set and used when a rule is scoped to
protected branches. See Scoped to Protected Branch doc
for more information about the feature.
ApprovalMergeRequestRule model is defined in
A record is created/updated/deleted when a rule is added/edited/removed via merge request create/edit form or the merge request level approvals API.
approval_project_rule is set when it is based from an existing
ApprovalMergeRequestRule doesn’t have
protected_branches as it inherits
them from the
approval_project_rule if not overridden.
ApprovalWrappedRule is defined in
is not an
ActiveRecord model. It’s used to wrap an
ApprovalMergeRequestRule for common interface. It also has the following sub
ApprovalWrappedAnyApprovalRule- for wrapping an
ApprovalWrappedCodeOwnerRule- for wrapping a
This class delegates most of the responsibilities to the approval rule it wraps but it’s also responsible for:
- Checking if the approval rule is approved.
- Knowing how many approvals were given or still required for the approval rule.
It gets this information from the approval rule and the
Approval records from
the merge request.
Approval model is defined in
ee/app/models/approval.rb. This model is
responsible for storing information about an approval made on a merge request.
Whenever an approval is given/revoked, a record is created/deleted.
The following controllers and services below are being used for the approval rules feature to work.
This private API is defined in
This is used for the following:
- Listing the approval rules in project settings.
- Creating/updating/deleting rules in project settings.
- Listing the approval rules on create merge request form.
This controller is defined in
create action of this controller is used when create merge request form is
submitted. It accepts the
approval_rules_attributes parameter for creating/updating/deleting
ApprovalMergeRequestRule records. It passes the parameter along when it executes
This controller is defined in
update action of this controller is used when edit merge request form is
submitted. It’s like
Projects::MergeRequests::CreationsController but it executes
This API is defined in
The Approvals API endpoint is requested when merge request page loads.
/projects/:id/merge_requests/:merge_request_iid/approval_settings is a
private API endpoint used for the following:
- Listing the approval rules on edit merge request form.
- Listing the approval rules on the merge request page.
When approving/unapproving MR via UI and API, the Approve Merge Request
API endpoint and the Unapprove Merge Request
API endpoint are requested. They execute
These APIs are defined in
Used to list/create/update/delete project and merge request level rules via Merge request approvals API.
This service is defined in
It is called only when
MergeRequests::UpdateService are executed.
It is responsible for parsing
approval_rules_attributes parameter to:
- Remove it when user can’t update approval rules.
- Filter the user IDs whether they are members of the project or not.
- Filter the group IDs whether they are visible to user.
- Identify the
- Append hidden groups to it when specified.
- Append user defined inapplicable (rules that does not apply to MR’s target branch) approval rules.
These flowcharts should help explain the flow from the controllers down to the models for different functionalities.
Some CRUD API endpoints are intentionally skipped because they are pretty straightforward.
When updating, same flow is followed but it starts at
This flow gets initiated by the frontend component. The data returned is used to display information on the MR widget.
When unapproving, same flow is followed but the
is executed instead.
- Add information related to other rule types, such as
- Add information about side effects of approving/unapproving merge request.