如何在 Gitlab 中成功的管道结束时创建合并请求?

How to create a merge request at the end of a successful pipeline in Gitlab?

我是 gitlab 和 gitlab 的新手 CI 我已经建立了一个成功完成的管道。 我的主分支和开发分支受到保护,因此需要合并请求,以便组中的另一个开发人员可以在合并前审查代码和评论。 我想知道是否可以在此管道的末尾生成此合并请求。 gitlab 存储库中是否有此设置,或者我是否必须创建一个脚本来实现此目的?
旁注:
就在发布之前,我遇到了 this section of the gitlab docs
我在 ubuntu 18.04

上使用 gitlab-runner 11.0.0

简短回答:当然 - 一切皆有可能。 GitLab 有一个很棒的 API (including creating an MR)。但我认为走那条路是不好的形式。您应该按设计使用 GitLab。您开始合并请求的时间太晚了。在开始任何工作之前启动它,您的合并请求将在分支的 整个持续时间 期间保持打开状态。

长答案: 这是理想的 GitLab 工作流程:

  1. 有人针对存储库创建了 ISSUE也许是一个功能请求,也许是一个实际问题,无论如何 - 有人想要改变一些东西,所以它是 'issue'
  2. 开发人员打开问题并单击 创建合并请求
    • 生成 一个合并请求 (MR),一个匹配的分支,并将其与问题联系起来
  3. 开发人员在分支机构工作,随时推动更改
  4. 开发人员获得一个通过的管道,并在他们准备好让客户预览作品时在该合并请求页面上点击“解决 WIP”and/or另一个开发人员进行代码审查。
  5. 在这里,让审阅者在完成审阅后单击 MERGE 或者更好,在存储库设置中打开 APPROVALS设置您希望评论的人员或人员组。
  6. 在合并按钮旁边,一定要删除源代码分支(为了理智),合并的代码将自动关闭问题 - link 全部 3元素在一起。

这从根本上落后于 GitHub 的工作方式(我来自),您 没有 告诉人们您在做什么。

  • GitHub 上的拉取请求 是在工作完成 时创建的并且你想合并到 master.
  • 当工作开始并且你想告诉全世界您即将着手开发一项功能。这允许人们在不需要时快速关闭或防止多个开发人员重复工作。

编辑: 听起来您有兴趣利用 API。有一个名为 'python-gitlab' 的 python 包实际上可以正常工作 http://python-gitlab.readthedocs.io/en/stable/gl_objects/mrs.html

import gitlab
import os

origin = "https://gitlab.example.com"
# Private token is set as an env var
gl = gitlab.Gitlab(origin, private_token, api_version='4')
gl.auth()

def create_merge_request(origin, private_token):
    mr = project.mergerequests.create({'source_branch': 'cool_feature',
                               'target_branch': 'master',
                               'title': 'merge cool feature',
                               'labels': ['label1', 'label2']})
    mr.assignee_id = gl.users.get(2).id # Assign it to coworker

def lookup_last_pipeline(origin, private_token):
    current_pipeline_id = os.environ['CI_PIPELINE_ID']
    pipelines = gl.projects.get(os.environ['CI_PROJECT_ID']).pipelines.list()
    for pipeline in pipelines:
        if pipeline.status == 'success' and pipeline.id == current_pipeline_id:
            create_merge_request()

这当然是一个示例,您必须根据自己的具体需要对其进行调整。

为了实现我的简单需求,我只是在我的管道中添加了最后一个阶段,它基本上执行了一个改编自 this post 的 bash 脚本。

编辑: 根据@Yuva

的要求
# Create a pull request on pipeline success
create_merge_request:
  stage: createMR
  tags:
    - autoMR
  script:
    - 'echo Merge request opened by $GITLAB_USER_NAME '
    - ~/commit.sh

并在 commit.sh

#!/bin/bash
# This script was adapted from:
# https://about.gitlab.com/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/

# TODO determine URL from git repository URL
[[ $HOST =~ ^https?://[^/]+ ]] && HOST="${BASH_REMATCH[0]}/api/v4/projects/"

# The branch which we wish to merge into
TARGET_BRANCH=develop;

# The user's token name so that we can open the merge request as the user
TOKEN_NAME=`echo ${GITLAB_USER_LOGIN}_COMMIT_TOKEN | tr "[a-z]" "[A-Z]"`

# See: http://www.tldp.org/LDP/abs/html/parameter-substitution.html search ${!varprefix*}, ${!varprefix@} section
PRIVATE_TOKEN=`echo ${!TOKEN_NAME}`

# The description of our new MR, we want to remove the branch after the MR has
# been closed
BODY="{
\"project_id\": ${CI_PROJECT_ID},
\"source_branch\": \"${CI_COMMIT_REF_NAME}\",
\"target_branch\": \"${TARGET_BRANCH}\",
\"remove_source_branch\": false,
\"force_remove_source_branch\": false,
\"allow_collaboration\": true,
\"subscribed\" : true,
\"title\": \"${GITLAB_USER_NAME} merge request for: ${CI_COMMIT_REF_SLUG}\"
}";

# Require a list of all the merge request and take a look if there is already
# one with the same source branch
 LISTMR=`curl --silent "${HOST}${CI_PROJECT_ID}/merge_requests?state=opened" --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}"`;
 COUNTBRANCHES=`echo ${LISTMR} | grep -o "\"source_branch\":\"${CI_COMMIT_REF_NAME}\"" | wc -l`;

# No MR found, let's create a new one
if [ ${COUNTBRANCHES} -eq "0" ]; then
    curl -X POST "${HOST}${CI_PROJECT_ID}/merge_requests" \
    --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "${BODY}";

    echo "Opened a new merge request: WIP: ${CI_COMMIT_REF_SLUG} for user ${GITLAB_USER_LOGIN}";
    exit;
fi
    echo "No new merge request opened"

另一种方法:

  • 不使用 GitLab API
  • 获取管道签出的代码所代表的补丁
  • 自 GitLab 11.5(2018 年 11 月)起使用电子邮件 (!)

Open a merge request with a patch via email

GitLab has supported opening a merge request via email for a long time, but before sending the email the branch must already exist on the server. Now you can open a merge request with only an email by attaching one or more patch files (.patch).

Patch files are the standard for sharing and transmitting changes between systems. In future releases of GitLab we will build on this foundation for distributed merge requests, which will allow merge requests between GitLab instances, and other Git hosting tools too.

参见documentation and issue