diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 07a7b5ce9de..214e87052da 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -33,8 +33,6 @@ = render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form -= render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form - = render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form = render 'shared/issuable/form/merge_params', issuable: issuable diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 1e03440a5dc..90a6a98235d 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -23,6 +23,7 @@ = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label" = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form + = render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form - if has_due_date .col-lg-6 diff --git a/doc/user/project/merge_requests/blocking_merge_requests.md b/doc/user/project/merge_requests/blocking_merge_requests.md deleted file mode 100644 index 0506a7cb4a5..00000000000 --- a/doc/user/project/merge_requests/blocking_merge_requests.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -type: reference, concepts ---- - -# Blocking merge requests **(PREMIUM)** - -> Introduced in GitLab Premium 12.2 - -Blocking merge requests allow dependencies between MRs to be expressed. If a -merge request is blocked by another MR, it cannot be merged until that blocking -MR is itself merged. - -NOTE: **Note:** -Blocking merge requests are a **PREMIUM** feature, but this restriction is only -enforced for the blocked merge request. A merge request in a **CORE** or -**STARTER** project can block a **PREMIUM** merge request, but not vice-versa. - -## Use cases - -* Ensure changes to a library are merged before changes to a project that - imports the library -* Prevent a documentation-only merge request from being merged before the MR - implementing the feature to be documented -* Require an MR updating a permissions matrix to be merged before merging an - MR from someone who hasn't yet been granted permissions - -It is common for a single logical change to span several merge requests. These -MRs may all be in a single project, or they may be spread out across multiple -projects, and the order in which they are merged can be significant. - -For example, given a project `mycorp/awesome-project` that imports a library -at `myfriend/awesome-lib`, adding a feature in `awesome-project` may **also** -require changes to `awesome-lib`, and so necessitate two merge requests. Merging -the `awesome-project` MR before the `awesome-lib` one would break the `master` -branch. - -The `awesome-project` MR could be [marked as WIP](work_in_progress_merge_requests.md), -and the reason for the WIP stated included in the comments. However, this -requires the state of the `awesome-lib` MR to be manually tracked, and doesn't -scale well if the `awesome-project` MR depends on changes to **several** other -projects. - -By marking the `awesome-project` MR as blocked on the `awesome-lib` MR instead, -the status of the dependency is automatically tracked by GitLab, and the WIP -state can be used to communicate the readiness of the code in each individual -MR instead. - -## Configuration - -To continue the above example, you can configure a block when creating the -new MR in `awesome-project` (or by editing it, if it already exists). The block -needs to be configured on the MR that will be **blocked**, rather than on the -**blocking** MR. There is a "Blocking merge requests" section in the form: - -![Blocking merge requests form control](img/edit_blocking_merge_requests.png) - -Anyone who can edit a merge request can change the list of blocking merge -requests. - -New blocks can be added by reference, by URL, or by using autcompletion. To -remove a block, press the "X" by its reference. - -As blocks can be specified across projects, it's possible that someone else has -added a block for a merge request in a project you don't have access to. These -are shown as a simple count: - -![Blocking merge requests form control with inaccessible MRs](img/edit_blocking_merge_requests_inaccessible.png) - -If necessary, you can remove all the blocks like this by pressing the "X", just -as you would for a single, visible block. - -Once you're finished, press the "Save changes" button to submit the request, or -"Cancel" to return without making any changes. - -The list of configured blocks, and the status of each one, is shown in the merge -request widget: - -![Blocking merge requests in merge request widget](img/show_blocking_merge_requests_in_mr_widget.png) - -Until all blocking merge requests have, themselves, been merged, the "Merge" -button will be disabled. In particular, note that **closed** merge requests -still block their dependents - it is impossible to automatically determine if -merge requests that were blocked by that MR when it was open, are still blocked -when it is closed. - -If a merge request has been closed **and** the block is no longer relevant, it -must be removed as a blocking MR, following the instructions above, before -merge. - -## Limitations - -* API support: [gitlab-ee#12551](https://gitlab.com/gitlab-org/gitlab-ee/issues/12551) -* Blocking relationships are not preserved across project export/import: [gitlab-ee#12549](https://gitlab.com/gitlab-org/gitlab-ee/issues/12549) -* Complex merge order dependencies are not supported: [gitlab-ee#11393](https://gitlab.com/gitlab-org/gitlab-ee/issues/11393) - -The last item merits a little more explanation. Blocking merge requests can be -described as a graph of dependencies. The simplest possible graph has one -merge request blocking another: - -```mermaid -graph LR; - myfriend/awesome-lib!10-->mycorp/awesome-project!100; -``` - -A more complex (and still supported) graph might have several MRs blocking -another from being merged: - -```mermaid -graph LR; - myfriend/awesome-lib!10-->mycorp/awesome-project!100; - herfriend/another-lib!1-->mycorp/awesome-project!100; -``` - -We also support one MR blocking several others from being merged: - -```mermaid -graph LR; - herfriend/another-lib!1-->myfriend/awesome-lib!10; - herfriend/another-lib!1-->mycorp/awesome-project!100; -``` - -What is **not** supported is a "deep", or "nested" graph of dependencies, e.g.: - -```mermaid -graph LR; - herfriend/another-lib!1-->myfriend/awesome-lib!10; - myfriend/awesome-lib!10-->mycorp/awesome-project!100; -``` - -In this example, `myfriend/awesome-lib!10` would be blocked from being merged by -`herfriend/another-lib!1`, and would also block `mycorp/awesome-project!100` -from being merged. This is **not** yet supported. - diff --git a/doc/user/project/merge_requests/img/cross-project-dependencies-edit-inaccessible.png b/doc/user/project/merge_requests/img/cross-project-dependencies-edit-inaccessible.png new file mode 100644 index 00000000000..2dc02634fd8 Binary files /dev/null and b/doc/user/project/merge_requests/img/cross-project-dependencies-edit-inaccessible.png differ diff --git a/doc/user/project/merge_requests/img/cross-project-dependencies-edit.png b/doc/user/project/merge_requests/img/cross-project-dependencies-edit.png new file mode 100644 index 00000000000..362e7e0ead2 Binary files /dev/null and b/doc/user/project/merge_requests/img/cross-project-dependencies-edit.png differ diff --git a/doc/user/project/merge_requests/img/cross-project-dependencies-view.png b/doc/user/project/merge_requests/img/cross-project-dependencies-view.png new file mode 100644 index 00000000000..e00231c839b Binary files /dev/null and b/doc/user/project/merge_requests/img/cross-project-dependencies-view.png differ diff --git a/doc/user/project/merge_requests/img/edit_blocking_merge_requests.png b/doc/user/project/merge_requests/img/edit_blocking_merge_requests.png deleted file mode 100644 index 98345f2f0d1..00000000000 Binary files a/doc/user/project/merge_requests/img/edit_blocking_merge_requests.png and /dev/null differ diff --git a/doc/user/project/merge_requests/img/edit_blocking_merge_requests_inaccessible.png b/doc/user/project/merge_requests/img/edit_blocking_merge_requests_inaccessible.png deleted file mode 100644 index b19cf1db94b..00000000000 Binary files a/doc/user/project/merge_requests/img/edit_blocking_merge_requests_inaccessible.png and /dev/null differ diff --git a/doc/user/project/merge_requests/img/show_blocking_merge_requests_in_mr_widget.png b/doc/user/project/merge_requests/img/show_blocking_merge_requests_in_mr_widget.png deleted file mode 100644 index 3f4fcc5781d..00000000000 Binary files a/doc/user/project/merge_requests/img/show_blocking_merge_requests_in_mr_widget.png and /dev/null differ diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index f78ec9d96e6..7ff30d1b813 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -47,7 +47,7 @@ With **[GitLab Enterprise Edition][ee]**, you can also: - Analyze your dependencies for vulnerabilities with [Dependency Scanning](../../application_security/dependency_scanning/index.md) **(ULTIMATE)** - Analyze your Docker images for vulnerabilities with [Container Scanning](../../application_security/container_scanning/index.md) **(ULTIMATE)** - Determine the performance impact of changes with [Browser Performance Testing](#browser-performance-testing-premium) **(PREMIUM)** -- Specify merge order dependencies with [Blocking Merge Requests](#blocking-merge-requests-premium) **(PREMIUM)** +- Specify merge order dependencies with [Cross-project Merge Request Dependencies](#cross-project-merge-request-dependencies-premium) **(PREMIUM)** ## Use cases @@ -451,20 +451,20 @@ GitLab runs the [Sitespeed.io container][sitespeed-container] and displays the d [Read more about Browser Performance Testing.](browser_performance_testing.md) -## Blocking Merge Requests **(PREMIUM)** +## Cross-project Merge Request Dependencies **(PREMIUM)** > Introduced in [GitLab Premium][products] 12.2. -A single logical change may be split across several merge requests, and perhaps -even across several projects. When this happens, the order in which MRs are -merged is important. +A single logical change may be split across several merge requests, across +several projects. When this happens, the order in which MRs are merged is +important. -GitLab allows you to specify that a merge request is blocked by other MRs. With +GitLab allows you to specify that a merge request depends on other MRs. With this relationship in place, the merge request cannot be merged until all of its -blockers have also been merged, helping to maintain the consistency of a single -logical change. +dependencies have also been merged, helping to maintain the consistency of a +single logical change. -[Read more about Blocking Merge Requests.](blocking_merge_requests.md) +[Read more about cross-project merge request dependencies.](merge_request_dependencies.md) ## Security reports **(ULTIMATE)** diff --git a/doc/user/project/merge_requests/merge_request_dependencies.md b/doc/user/project/merge_requests/merge_request_dependencies.md new file mode 100644 index 00000000000..45cb56dfb6b --- /dev/null +++ b/doc/user/project/merge_requests/merge_request_dependencies.md @@ -0,0 +1,143 @@ +--- +type: reference, concepts +--- + +# Cross-project merge request dependencies **(PREMIUM)** + +> Introduced in GitLab Premium 12.2 + +Cross-project merge request dependencies allows a required order of merging +between merge requests in different projects to be expressed. If a +merge request "depends on" another, then it cannot be merged until its +dependency is itself merged. + +NOTE: **Note:** +Merge requests dependencies are a **PREMIUM** feature, but this restriction is +only enforced for the dependent merge request. A merge request in a **CORE** or +**STARTER** project can be a dependency of a **PREMIUM** merge request, but not +vice-versa. + +NOTE: **Note:** +A merge request can only depend on merge requests in a different project. Two +merge requests in the same project cannot depend on each other. + +## Use cases + +* Ensure changes to a library are merged before changes to a project that + imports the library +* Prevent a documentation-only merge request from being merged before the merge request + implementing the feature to be documented +* Require an merge request updating a permissions matrix to be merged before merging an + merge request from someone who hasn't yet been granted permissions + +It is common for a single logical change to span several merge requests, spread +out across multiple projects, and the order in which they are merged can be +significant. + +For example, given a project `mycorp/awesome-project` that imports a library +at `myfriend/awesome-lib`, adding a feature in `awesome-project` may **also** +require changes to `awesome-lib`, and so necessitate two merge requests. Merging +the `awesome-project` merge request before the `awesome-lib` one would +break the `master`branch. + +The `awesome-project` merge request could be [marked as +WIP](work_in_progress_merge_requests.md), +and the reason for the WIP stated included in the comments. However, this +requires the state of the `awesome-lib` merge request to be manually +tracked, and doesn't scale well if the `awesome-project` merge request +depends on changes to **several** other projects. + +By making the `awesome-project` merge request depend on the +`awesome-lib` merge request instead, this relationship is +automatically tracked by GitLab, and the WIP state can be used to +communicate the readiness of the code in each individual merge request +instead. + +## Configuration + +To continue the above example, you can configure a dependency when creating the +new merge request in `awesome-project` (or by editing it, if it already exists). +The dependency needs to be configured on the **dependent** merge +request. There is a "Cross-project dependencies" section in the form: + +![Cross-project dependencies form control](img/cross-project-dependencies-edit.png) + +Anyone who can edit a merge request can change the list of dependencies. + +New dependencies can be added by reference, or by URL. To remove a dependency, +press the "X" by its reference. + +As dependencies are specified across projects, it's possible that someone else +has added a dependency for a merge request in a project you don't have access to. +These are shown as a simple count: + +![Cross-project dependencies form control with inaccessible merge requests](img/cross-project-dependencies-edit-inaccessible.png) + +If necessary, you can remove all the dependencies like this by pressing the "X", +just as you would for a single, visible dependency. + +Once you're finished, press the "Save changes" button to submit the request, or +"Cancel" to return without making any changes. + +The list of configured dependencies, and the status of each one, is shown in the +merge request widget: + +![Cross-project dependencies in merge request widget](img/cross-project-dependencies-view.png) + +Until all dependencies have, themselves, been merged, the "Merge" +button will be disabled for the dependent merge request. In +particular, note that **closed** merge request still prevent their +dependents from being merged - it is impossible to automatically +determine whether the dependency expressed by a closed merge request +has been satisfied in some other way or not. + +If a merge request has been closed **and** the dependency is no longer relevant, +it must be removed as a dependency, following the instructions above, before +merge. + +## Limitations + +* API support: [gitlab-ee#12551](https://gitlab.com/gitlab-org/gitlab-ee/issues/12551) +* Dependencies are not preserved across project export/import: [gitlab-ee#12549](https://gitlab.com/gitlab-org/gitlab-ee/issues/12549) +* Complex merge order dependencies are not supported: [gitlab-ee#11393](https://gitlab.com/gitlab-org/gitlab-ee/issues/11393) + +The last item merits a little more explanation. Dependencies between merge +requests can be described as a graph of relationships. The simplest possible +graph has one merge request that depends upon another: + +```mermaid +graph LR; + myfriend/awesome-lib!10-->mycorp/awesome-project!100; +``` + +A more complex (and still supported) graph might have one merge request that +directly depends upon several others: + +```mermaid +graph LR; + myfriend/awesome-lib!10-->mycorp/awesome-project!100; + herfriend/another-lib!1-->mycorp/awesome-project!100; +``` + +Several different merge requests can also directly depend upon the +same merge request: + + +```mermaid +graph LR; + herfriend/another-lib!1-->myfriend/awesome-lib!10; + herfriend/another-lib!1-->mycorp/awesome-project!100; +``` + +What is **not** supported is a "deep", or "nested" graph of dependencies, e.g.: + +```mermaid +graph LR; + herfriend/another-lib!1-->myfriend/awesome-lib!10; + myfriend/awesome-lib!10-->mycorp/awesome-project!100; +``` + +In this example, `myfriend/awesome-lib!10` depends on `herfriend/another-lib!1`, +and is itself a dependent of `mycorp/awesome-project!100`. This means that +`myfriend/awesome-lib!10` becomes an **indirect** dependency of +`mycorp/awesome-project!100`, which is not yet supported.