为 GitLab 编写脚本以自动合并合并请求

Posted

技术标签:

【中文标题】为 GitLab 编写脚本以自动合并合并请求【英文标题】:Write script for GitLab for automatic merge of Merge Request 【发布时间】:2021-12-19 16:26:41 【问题描述】:

我正在尝试编写一个脚本来合并打开的并符合合并请求标准(通过设置实现)的合并请求。

所以我唯一想做的是,我想编写一个 CI yaml 文件,我将安排它每 30 分钟左右运行一次,以检查打开的合并请求,如果可以合并则合并它们。

困惑一:

我可以通过编写多个 curl 请求来实现这一点,但我不确定如何在执行后一个接一个地使用它们。

所以,要检查打开的合并请求,我需要一个组的项目 ID,以获得我有一个 curl 命令,它将为我提供项目 ID,我将它们保存在一个文件中 projectid.txt .

curl -s --location --request GET --header 'PRIVATE-TOKEN:<PRIVATE_TOKEN>' '$CI_API_V4_URL/groups/'$GROUPID'/projects'  | sed 's/,/\n/g' | grep -w "id" | awk -F ':' 'print $2' | sed -s 's/"id"//g' 

现在,一旦我有了所有的项目 ID, 我想将它们流入另一个 curl 命令,即:

curl -s --location --request GET '$CI_API_V4_URL/projects/3/merge_requests?state=opened' --header 'PRIVATE-TOKEN:<PRIVATE_TOKEN>' | sed 's/,/\n/g' | grep -w "iid" | awk -F ':' 'print $2' 

但是如果您看到上面的 curl 请求,我将手动提供3 以获得所需的输出。

但我希望这个 curl 命令自动获取 projectid.txt 每一行中存在的每个 projectid 并将其执行到第二个 curl 命令。这样我想要一个文件,它将明智地显示打开的合并请求项目。

一旦我得到所有这些信息,我想合并开放的合并请求,这些请求有效并且准备好合并(GitLab 负责检查它们是否准备好合并)

所以,我现在唯一需要的是,在另一个 curl 命令中输入 projectidmerge request id,这是一个 PUT 请求。

curl --location --request PUT '$CI_API_V4_URL/projects/3/merge_requests/26/merge' \
--header 'PRIVATE-TOKEN: <PRIVATE_TOKEN>'

来源:https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr

如果您看到上述合并请求,我需要提供项目明智的合并请求。我对如何实现自动化有点困惑。

另外,你能告诉我这是否是利用我的gitlab-ci.yml 文件中的这些许多 curl 请求来自动执行此操作的正确方法吗?还有其他方法可以通过Python 或shell 脚本来实现吗?

另外,有没有什么简单的方法可以在 REST API 文档的帮助下编写 python 脚本?我能够生成 curl 请求以使用 REST API,但不确定如何使用 Python 来实现。

欢迎任何帮助或建议。

到目前为止,我的 gitlab-ci.yml 文件看起来像这样,因为在此之后我无法思考太多:

variables:
  GROUPID: 6
stages:
  - cleanup

cleanup-code-job:
  stage: cleanup
  tags:
    - build
  script:
    - echo "$GROUPID"
    ##Below curl command can be used to identify projects in group
    - curl -s --location --request GET --header 'PRIVATE-TOKEN:<PRIVATE_TOKEN>' '$CI_API_V4_URL/groups/'$GROUPID'/projects'  | sed 's/,/\n/g' | grep -w "id" | awk -F ':' 'print $2' | sed -s 's/"id"//g' > projects.txt
    - cat projects.txt

谢谢

【问题讨论】:

你看过marge-bot吗? 没有@Phillip-ZyanKlee-Stockmann!让我检查一下,你能不能也给我一些关于它的背景信息。? Marge 可以 - 除了实现 not rocket science rule of software development 等其他不错的功能之外 - 在 MR 为绿色并经过审核时合并它们。 github.com/smarkets/marge-bot 阅读完文档后,看起来我需要创建一个占用座位的用户。 :( 为了玛吉?是的,这是真的。如果您自己编写脚本,答案将取决于您是否被允许使用自己的用户凭据运行此脚本或需要分离权限。 (老实说,我更喜欢。) 【参考方案1】:

使用python-gitlab library,python 脚本使这个任务的脚本编写变得更加简单,尤其是在涉及到分页时。

此外,您可以使用Group merge requests API 作为快捷方式,而不是列出组中的所有项目,然后列出每个项目中的所有合并请求。

使用 Python 脚本,它可能看起来像这样:

import gitlab
from gitlab.v4.objects import GroupMergeRequest
TOKEN = "your API key"
GITLAB_HOST = 'https://gitlab.com' # or your instance
gl = gitlab.Gitlab(GITLAB_HOST, private_token=TOKEN)

GROUP_ID = 123

def mr_meets_merge_criteria(mr: GroupMergeRequest) -> bool:
    """
    A function to check if it meets criteria to
    be merged automatically by this script
    """
    print(mr.project_id)
    print(mr.merge_status)  # e.g. 'can_be_merged'
    # check something
    ...
    return True | False

group = gl.groups.get(GROUP_ID)

# loop over all merge requests in the group
for mr in group.mergerequests.list(as_list=False):
    if mr_meets_merge_criteria(mr):
        project = gl.projects.get(mr.project_id, lazy=True)
        project_mr = project.mergerequests.get(mr.iid)
        project_mr.merge()

所以,如果你输入了正确的常量并完成了mr_meets_merge_criteria函数的实现,那么这就是你所需要的:-)

【讨论】:

嗨@sytech,这是非常有用的东西。我将探索这个包并利用它。此外,我在尝试执行您提供的脚本时发现了一个错误。看起来他们在def mr_meets_merge_criteria(mr: GroupMergeRequest) -&gt; bool: 行中有一些错误,正如-&gt;上的SyntaxError: invalid syntax 所说,你确定它对你有用吗? 确保您使用的是最新版本的 Python3——或者您可以删除旧版本 Python3 的类型提示语法,例如 def mr_meets_merge_criteria(mr):@SameerAtharkar 好的,现在可以了。另一个小查询@sytech 我现在正在探索不同的东西。我实际上从未使用过它。所以我正在尝试不同的事情,比如显示项目ID、项目中的用户......以及项目中的分支。你能告诉我如何传递分支机构的详细信息吗?我使用了users = gl.users.list()print(users) 并且它正在工作,但是当我尝试显示branches = project.branches.list() 时它说name 'project' is not defined 你能告诉我如何在这里传递项目ID? 听起来像一个一般性的编程错误,如果您仍然需要帮助,也许更适合单独的问题@SameerAtharkar - 听起来您未能定义project 变量。但总的来说,您可以检索像project = gl.projects.get("&lt;Project path or ID number&gt;") 这样的项目。另外,作为一个重要提示:要在 python-gitlab API 中对列表进行完全分页,您需要将 as_list=False 传递给 .list 方法!否则,您只会得到第一个结果列表。如果我的回答回答了您最初的问题,请考虑接受它:-) 好的,谢谢@sytech。我想知道是否可以找到一些从 0 开始的基本文档或一些视频来解释这一切。你知道吗?我发现文档实际上并不难。您的回答对完成工作非常有帮助,但我无法理解。

以上是关于为 GitLab 编写脚本以自动合并合并请求的主要内容,如果未能解决你的问题,请参考以下文章

在 Gitlab 中合并请求后运行 Jenkins 作业

使用 Jenkins 构建 GitLab 合并请求

为合并请求触发的管道运行应用 GitLab CI/CD 管道更改

将 GitLab 合并请求中的所有提交添加到 Upsource 审查

使用 Gitlab API 命令合并合并请求

python gitlab api 合并请求失败,出现 gitlab.execeptions.GitlabMRClosedError 405