Complex merge order dependencies
### Problem to solve In https://gitlab.com/gitlab-org/gitlab-ee/issues/9688 , we're adding the first iteration of merge ordering - this forms a directed acyclical graph of dependencies between merge requests, which *happens* to be only 2 members deep, for simplicity and ease of understanding for the user. That maximum depth will be enforced in the backend. Some examples of valid trees with this restriction: ```mermaid graph TD; gitlab-ee-->gitlab-ce; ``` ```mermaid graph TD; gitlab-proto-->gitlab-ce; gitlab-workhorse-->gitlab-ce; ``` ```mermaid graph TD; labkit-->gitaly; labkit-->gitlab-pages; labkit-->gitlab-workhorse; ``` ```mermaid graph TD; labkit-->gitlab-pages; labkit-->gitlab-workhorse; labkit-->gitaly; gitaly-proto-->gitaly; gitaly-proto-->gitlab-workhorse; ``` However, this is insufficient to solve all our merge request ordering dependency cases. 3, 4, 5, or more levels may be needed in the future. The only reason we have the 2-level restriction at present is because it's simple to display complete information about it to the user. ### Intended users Developers, Reviewers ### Further details In GitLab, it's easy to construct a proposed tree of dependencies for a merge that is deeper than two levels. For instance, we could end up with this (suitably hideous) scenario if something went *really* wrong: ```mermaid graph TD; labkit-->gitaly; labkit-->gitlab-pages; labkit-->gitlab-workhorse; gitaly-proto-->gitaly; gitaly-proto-->gitlab-workhorse; gitaly-proto-->gitlab-shell; gitaly-->gitlab-ee; gitaly-proto-->gitlab-ee; gitlab-pages-->gitlab-ee; gitlab-workhorse-->gitlab-ee; gitlab-shell-->gitlab-ee; gitlab-ee-->gitlab-ce; ``` ### Proposal Support setting up and respecting merge order dependencies like those listed above. This can be done in one of two ways: * Support branchy trees like the above natively * Flatten the trees into *lists* by verticalizing each level in the DAG For the second example, assuming a left-to-right ordering, that means we eventually end up with this list: ```mermaid graph TD; labkit-->gitaly-proto; gitaly-proto-->gitlab-pages; gitlab-pages-->gitaly gitaly-->gitlab-workhorse; gitlab-workhorse-->gitlab-shell; gitlab-shell-->gitlab-ee; gitlab-ee-->gitlab-ce; ``` This is simpler, and easier to display/manipulate, but we *do* lose some efficiency and obviousness in the flattening. Why does `gitlab-shell` depend on `gitlab-workhorse` in this model? It's completely unobvious. When rearranging, what happens if you move an intermediate node? How do we ensure that the *actual* dependency (`gitaly-proto` in this case) is retained if we're moving `gitlab-shell` earlier in the list? The difficulty of answering these kinds of questions means my preference is for at least *storing* the tree natively. Moving nodes around in it can then correctly calculate actual dependencies. What we **display** is still an open question - the lists are simpler to display, but if moving one items moves a bunch of others too, they're not simpler to *understand*. So perhaps supporting the tree from the start is the right option? ### Permissions and Security <!-- What permissions are required to perform the described actions? Are they consistent with the existing permissions as documented for users, groups, and projects as appropriate? Is the proposed behavior consistent between the UI, API, and other access methods (e.g. email replies)? --> ### Documentation <!-- See the Feature Change Documentation Workflow https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html Add all known Documentation Requirements here, per https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html#documentation-requirements --> ### Testing <!-- What risks does this change pose? How might it affect the quality of the product? What additional test coverage or changes to tests will be needed? Will it require cross-browser testing? See the test engineering process for further guidelines: https://about.gitlab.com/handbook/engineering/quality/guidelines/test-engineering/ --> ### What does success look like, and how can we measure that? <!-- Define both the success metrics and acceptance criteria. Note that success metrics indicate the desired business outcomes, while acceptance criteria indicate when the solution is working correctly. If there is no way to measure success, link to an issue that will implement a way to measure this. --> ### What is the type of buyer? ~"GitLab Premium" ### Solution Following on from the spike https://gitlab.com/gitlab-org/gitlab/-/issues/367266, we need to do the following: * Remove validations 2,3 of the blocking dependencies * Check again to see if no traversing of the blocking tree takes place * Add feature specs/unit tests for multiple blocking
issue