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

Dar*_*ar1 11 git gitlab gitlab-ci-runner

我对 gitlab 和 gitlab CI 很陌生,我已经建立了一个成功完成的管道。我的主分支和开发分支受到保护,因此需要合并请求,以便组中的另一个开发人员可以在合并之前查看代码和注释。我想知道是否可以在此管道的末尾生成此合并请求。gitlab 存储库中是否有此设置,或者我是否必须创建脚本来实现此目的?
旁注:
就在发布这篇文章之前,我遇到了 gitlab 文档的这一部分,
我在 ubuntu 18.04 上使用了 gitlab-runner 11.0.0

Dar*_*ar1 7

为了满足我的简单需求,我只是在我的管道中添加了最后一个阶段,它基本上执行了一个改编自这篇文章的 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

Run Code Online (Sandbox Code Playgroud)

并在 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"

Run Code Online (Sandbox Code Playgroud)

  • 没问题,谢谢,我可以使用 git api 命令“git push origin HEAD:dev -o merge_request.create -o merge_request.target=master -o merge_when_pipeline_succeeds”来完成此操作。请参阅此处 Murali 的解决方案:https:// /stackoverflow.com/questions/58322235/gitlab-ci-yml-to-create-merge-reqeust/58327480#58327480 (2认同)

Rak*_*aim 6

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

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

  1. 有人针对存储库创建了ISSUE也许是一个功能请求,也许是一个实际问题,不管怎样——有人想要改变一些东西,所以这是一个“问题”
  2. 开发者打开问题并点击CREATE MERGE REQUEST
    • 这会生成一个合并请求 (MR),一个匹配的分支,并将其与问题联系起来
  3. 开发人员在分支上工作,随时推动更改
  4. 当开发人员准备好让客户预览工作和/或其他开发人员进行代码审查时,他们会获得一个传递管道并在该合并请求页面上点击“解决 WIP ”。
  5. 从这里开始,让该审阅者在完成审阅后单击“合并”,或者甚至更好,在存储库设置中打开“批准”设置您想要审阅的人或人组。
  6. 在合并按钮旁边,一定要删除源分支(为了理智),合并后的代码将自动关闭问题 - 并将所有 3 个元素链接在一起。

这是从根本上向后从GitHub的工作方式(这是我从来到),你不要告诉你在什么地方努力的人。

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

编辑:听起来您对利用 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()
Run Code Online (Sandbox Code Playgroud)

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