Skip to content

Refactor and abstract Auto Merge Processes

Shinya Maeda requested to merge abstract-auto-merge into master

What does this MR do?

Issued from https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/12966#note_173322701

GitLab has the MWPS feature (Merge When Pipeline Succeeds). This feature allows users to schedule a merge, which happens after the latest pipeline in a merge request succeeded. This feature is complete, however, it's hard to reuse shared functionalities (e.g. UI, System note, endpoints) because the business logic is scattered everywhere. This is a crucial problem when it comes to add a new auto merge strategy, such as Merge Train.

This MR refactors and abstracts the MWPS feature and let us easily reuse the existing functions for merge train. Here is the details of the approach:

Backend specific

  • The system sends messages to AutoMergeService which proxy the auto-merge logic according to the merge request state.
  • Gather scattered auto-merge-related business logic under AutoMerge domain
  • Today we have AutoMerge::MergeWhenPipelineSucceeds only. Tomorrow, we have AutoMerge::AddToMergeTrainWhenPipelineSucceeds and AutoMerge::MergeTrain

Frontend and Backend communication: General

  • When user activates auto-merge, Frontend requests to POST merge_requests/:iid/merge endpoint. You can specify auto_merge_strategy parameter (The detail is explained below)
  • When user cancels auto-merge, Frontend requests to POST merge_requests/:iid/cancel_auto_merge endpoint.
  • When user updates auto-merge options (e.g. add an option to remove source branch), Frontend requests to POST merge_requests/:iid/merge endpoint.

Frontend and Backend communication: MR widget Json

MR widget JSON payload includes the following parameters:

  • auto_merge_enabled ... The boolean flag if any auto merge strategy is enabled in the merge request. Previously, this flag was named merge_when_pipeline_succeeds
  • auto_merge_strategy ... The chosen strategy if auto-merge is enabled. This is a new parameter. It could be one of these:
    • 1 merge_when_pipeline_succeeds ... Trigger merge when the latest pipeline in the merge request succeeds (CE/EE)
    • 2 add_to_merge_train_when_pipeline_succeeds ... Add to train when the latest pipeline in the merge request succeeds (EE Only)
    • 3 merge_train ... Enqueue the merge request to a merge train (EE Only)
  • available_auto_merge_strategies ... The available auto merge strategies for the merge request. This takes into account of the current MR state and automatically deduce the available auto merge strategies. For example, if the latest pipeline is running, then merge_when_pipeline_succeeds strategy is included in the array, but if the latest pipeline is finished, then merge_when_pipeline_succeeds is not included. This is a new parameter.
  • merge_user ... The user who triggered the auto-merge. This parameter already exists today.
  • cancel_auto_merge_path ... The endpoint to cancel auto-merge. Previously, this parameter was named cancel_merge_when_pipeline_succeeds_path. This value is present in any auto-merge strategies and you can just call the endpoint when user wants to stop whatever auto merge strategy.

JSON sample (When activating MWPS)

Endpoint: POST http://local.gitlab.test:8181/root/abstract-auto-merge/merge_requests/5/merge

Request payload:

{
auto_merge_strategy: "merge_when_pipeline_succeeds"
commit_message: "Merge branch 'patch-12' into 'master'↵↵Update README.md↵↵See merge request root/abstract-auto-merge!5"
sha: "0cd8aea96a5af4c8bcc9d47e967b2fc09bb4bb9b"
should_remove_source_branch: false
squash: false
squash_commit_message: "Update README.md"
}

Response:

{"status":"merge_when_pipeline_succeeds"}

Widget Response:

{
  "merge_params": {
    "force_remove_source_branch": "0",
    "squash": false,
    "should_remove_source_branch": false,
    "commit_message": "Merge branch 'patch-12' into 'master'\n\nUpdate README.md\n\nSee merge request root/abstract-auto-merge!5",
    "squash_commit_message": "Update README.md",
    "auto_merge_strategy": "merge_when_pipeline_succeeds"
  },
  "merge_status": "can_be_merged",
  "merge_user_id": 1,
  "auto_merge_enabled": true,
  "auto_merge_strategy": "merge_when_pipeline_succeeds",
  "available_auto_merge_strategies": ["merge_when_pipeline_succeeds"],
  "cancel_auto_merge_path": "/root/abstract-auto-merge/merge_requests/5/cancel_auto_merge",
  ...
}

JSON sample (When canceling MWPS)

Endpoint: POST: http://local.gitlab.test:8181/root/abstract-auto-merge/merge_requests/5/cancel_auto_merge

Response:

{
  "merge_params": { "force_remove_source_branch": "0", "squash": false },
  "merge_status": "can_be_merged",
  "merge_user_id": null,
  "auto_merge_enabled": false,
  "auto_merge_strategy": null,
  "available_auto_merge_strategies": ["merge_when_pipeline_succeeds"],
  "cancel_auto_merge_path": null,
   ...
}

JSON sample (When updating merge option e.g. clicked "Delete Source Branch" button)

Endpoint: http://local.gitlab.test:8181/root/abstract-auto-merge/merge_requests/5/merge

Request Payload:

{
auto_merge_strategy: "merge_when_pipeline_succeeds"
sha: "0cd8aea96a5af4c8bcc9d47e967b2fc09bb4bb9b"
should_remove_source_branch: true
}

Response:

{"status":"merge_when_pipeline_succeeds"}

Widget Response:

{
  "merge_params": {
    "force_remove_source_branch": "0",
    "squash": false,
    "should_remove_source_branch": true,
    "commit_message": "Merge branch 'patch-12' into 'master'\n\nUpdate README.md\n\nSee merge request root/abstract-auto-merge!5",
    "squash_commit_message": "Update README.md",
    "auto_merge_strategy": "merge_when_pipeline_succeeds"
  },
  "merge_status": "can_be_merged",
  "merge_user_id": 1,
  "auto_merge_enabled": true,
  "auto_merge_strategy": "merge_when_pipeline_succeeds",
  "available_auto_merge_strategies": ["merge_when_pipeline_succeeds"],
  "cancel_auto_merge_path": "/root/abstract-auto-merge/merge_requests/5/cancel_auto_merge",
   ...
}

Does this MR meet the acceptance criteria?

Conformity

Performance and testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • [-] Label as security and @ mention @gitlab-com/gl-security/appsec
  • [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • [-] Security reports checked/validated by a reviewer from the AppSec team
Edited by Shinya Maeda

Merge request reports