# Pipelines for Merge Requests

> 原文：[https://docs.gitlab.com/ee/ci/merge_request_pipelines/](https://docs.gitlab.com/ee/ci/merge_request_pipelines/)

*   [Prerequisites](#prerequisites)
*   [Configuring pipelines for merge requests](#configuring-pipelines-for-merge-requests)
    *   [Use `rules` to run pipelines for merge requests](#use-rules-to-run-pipelines-for-merge-requests)
    *   [Use `only` or `except` to run pipelines for merge requests](#use-only-or-except-to-run-pipelines-for-merge-requests)
        *   [Excluding certain jobs](#excluding-certain-jobs)
        *   [Excluding certain branches](#excluding-certain-branches)
*   [Pipelines for Merged Results](#pipelines-for-merged-results-premium)
    *   [Merge Trains](#merge-trains-premium)
*   [Important notes about merge requests from forked projects](#important-notes-about-merge-requests-from-forked-projects)
*   [Additional predefined variables](#additional-predefined-variables)
*   [Troubleshooting](#troubleshooting)
    *   [Two pipelines created when pushing to a merge request](#two-pipelines-created-when-pushing-to-a-merge-request)
    *   [Two pipelines created when pushing an invalid CI configuration file](#two-pipelines-created-when-pushing-an-invalid-ci-configuration-file)

# Pipelines for Merge Requests[](#pipelines-for-merge-requests "Permalink")

在 GitLab 11.6 中[引入](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/15310) .

在[基本配置中](../pipelines/pipeline_architectures.html#basic-pipelines) ，每次更改被推送到分支时，GitLab 都会运行管道.

如果希望管道**仅**在创建或更新合并请求时运行作业，则可以将*管道用于合并请求* .

在用户界面中，这些管道被标记为`detached` . 否则，这些管道看起来与其他管道相同.

具有开发者[权限的](../../user/permissions.html)任何用户都可以为合并请求运行管道.

[![Merge request page](img/d5a5a91fe5e2b490b9388b43801b6a39.png)](img/merge_request.png)

**Note:** If you use this feature with [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.html), pipelines for merge requests take precedence over the other regular pipelines.

## Prerequisites[](#prerequisites "Permalink")

要为合并请求启用管道：

*   您的存储库必须是 GitLab 存储库，而不是[外部存储库](../ci_cd_for_external_repos/index.html) .
*   [在 GitLab 11.10 和更高版本中](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25504) ，您必须使用 GitLab Runner 11.9.

## Configuring pipelines for merge requests[](#configuring-pipelines-for-merge-requests "Permalink")

要为合并请求配置管道，您需要配置[CI / CD 配置文件](../yaml/README.html) . 有几种不同的方法可以做到这一点：

### Use `rules` to run pipelines for merge requests[](#use-rules-to-run-pipelines-for-merge-requests "Permalink")

当使用`rules` ，这是首选方法，我们建议从[`workflow:rules`模板开始，](../yaml/README.html#workflowrules-templates)以确保基本配置正确. 该链接提供了有关如何执行此操作以及如何进行自定义的说明.

### Use `only` or `except` to run pipelines for merge requests[](#use-only-or-except-to-run-pipelines-for-merge-requests "Permalink")

If you want to continue using `only/except`, this is possible but please review the drawbacks below.

使用此方法时，只需指定`only: - merge_requests`每个作业的`only: - merge_requests` . 在此示例中，管道包含配置为在合并请求上运行的`test`作业.

`build`和`deploy`作业没有`only: - merge_requests`参数，因此它们将不会在合并请求上运行.

```
build:
  stage: build
  script: ./build
  only:
    - master

test:
  stage: test
  script: ./test
  only:
    - merge_requests

deploy:
  stage: deploy
  script: ./deploy
  only:
    - master 
```

#### Excluding certain jobs[](#excluding-certain-jobs "Permalink")

`only: [merge_requests]`参数的行为是， *只有*具有该参数的作业*才*在合并请求的上下文中运行； 没有其他作业将运行.

但是，您可以反转此行为，并运行*除*一两个*之外的*所有作业.

考虑下面的管道，作业`A` ， `B`和`C` 假设您要：

*   所有管道始终运行`A`和`B`
*   `C`仅针对合并请求运行.

为此，可以如下配置`.gitlab-ci.yml`文件：

```
.only-default: &only-default
  only:
    - master
    - merge_requests
    - tags

A:
  <<: *only-default
  script:
    - ...

B:
  <<: *only-default
  script:
    - ...

C:
  script:
    - ...
  only:
    - merge_requests 
```

Therefore:

*   由于`A`和`B`在所有情况下都具有`only:`执行规则，因此它们将始终运行.
*   由于`C`指定仅针对合并请求运行，因此它将不会针对除合并请求管道之外的任何管道运行.

这可以帮助您避免为所有作业添加`only:`规则，以使其始终运行. 您可以使用这种格式来设置评论应用，以帮助节省资源.

#### Excluding certain branches[](#excluding-certain-branches "Permalink")

[`only`](../yaml/README.html#onlyexcept-basic)使用[/ `except`](../yaml/README.html#onlyexcept-basic)时，合并请求的管道需要特殊处理. 与普通的分支引用（例如`refs/heads/my-feature-branch` ）不同，合并请求引用使用特殊的 Git 引用，看起来像`refs/merge-requests/:iid/head` . 因此，以下配置将**无法**正常工作：

```
# Does not exclude a branch named "docs-my-fix"!
test:
  only: [merge_requests]
  except: [/^docs-/] 
```

相反，可以将[`$CI_COMMIT_REF_NAME`预定义环境变量](../variables/predefined_variables.html)与[`only:variables`](../yaml/README.html#onlyvariablesexceptvariables)结合使用以完成此行为：

```
test:
  only: [merge_requests]
  except:
    variables:
      - $CI_COMMIT_REF_NAME =~ /^docs-/ 
```

## Pipelines for Merged Results[](#pipelines-for-merged-results-premium "Permalink")

阅读[有关合并结果的管道](pipelines_for_merged_results/index.html)的[文档](pipelines_for_merged_results/index.html) .

### Merge Trains[](#merge-trains-premium "Permalink")

阅读[有关合并火车](pipelines_for_merged_results/merge_trains/index.html)的[文档](pipelines_for_merged_results/merge_trains/index.html) .

## Important notes about merge requests from forked projects[](#important-notes-about-merge-requests-from-forked-projects "Permalink")

请注意，当前行为可能会更改. 在通常的贡献流程中，外部贡献者遵循以下步骤：

1.  分叉一个父项目.
2.  从分支项目中创建一个以父项目中的`master`分支为目标的合并请求.
3.  管道在合并请求上运行.
4.  父项目的维护者检查管道结果，如果最新的管道通过，则合并到目标分支.

当前，这些管道是在**派生**项目中创建的，而不是在父项目中创建的. 这意味着您不能完全信任管道结果，因为从技术上讲，外部贡献者可以通过在派生项目中调整其 GitLab Runner 来掩盖其管道结果.

GitLab 不允许在父项目中创建这些管道有多种原因，但是最大的原因之一是安全性问题. 外部用户可以通过修改`.gitlab-ci.yml` （可能是某种凭据）从父项目中窃取秘密变量. 这不应该发生.

我们正在讨论一种安全的解决方案，该解决方案针对从分支项目提交的合并请求运行管道，请参阅[有关权限扩展的问题](https://gitlab.com/gitlab-org/gitlab/-/issues/11934) .

## Additional predefined variables[](#additional-predefined-variables "Permalink")

通过将管道用于合并请求，GitLab 将其他预定义变量公开给管道作业. 这些变量包含关联的合并请求的信息，因此将您的作业与[GitLab 合并请求 API](../../api/merge_requests.html)集成非常有用.

您可以在[参考表中](../variables/predefined_variables.html)找到可用变量的列表. 变量名称以`CI_MERGE_REQUEST_`前缀开头.

## Troubleshooting[](#troubleshooting "Permalink")

### Two pipelines created when pushing to a merge request[](#two-pipelines-created-when-pushing-to-a-merge-request "Permalink")

如果使用`rules`时遇到重复的管道，请查看[`rules`和`only` / `except`之间](../yaml/README.html#differences-between-rules-and-onlyexcept)的[重要区别](../yaml/README.html#differences-between-rules-and-onlyexcept) ，这将帮助您正确设置起始配置.

如果您在使用`only/except`时看到两个管道，请参见上述与`only/except`一起使用的注意事项（或者，考虑使用`rules` ）.

### Two pipelines created when pushing an invalid CI configuration file[](#two-pipelines-created-when-pushing-an-invalid-ci-configuration-file "Permalink")

推送到具有无效 CI 配置文件的分支会触发两种类型的失败管道的创建. 一个管道是失败的合并请求管道，另一个管道是失败的分支管道，但两者都是由相同的无效配置引起的.

在极少数情况下，会创建重复的管道.

有关详细信息，请参[见此问题](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) .