在我的管道中,我想只有在Merge Requests目标分支是某个分支(例如master或release)时才运行作业。
这可能吗?
我读过https://docs.gitlab.com/ee/ci/variables/,除非我错过了什么,否则我没有看到任何有用的东西。
Gitlab CI与Merge Requests无关(目前为止)。由于管道在原始分支上运行,因此您将无法检索目标。
更新:2019-03-21
自版本11.6起,GitLab具有合并请求信息的变量(https://docs.gitlab.com/ce/ci/variables/看到变量以CI_MERGE_REQUEST_
开头)。但是,这些变量仅在merge request pipelines
中可用。(https://docs.gitlab.com/ce/ci/merge_request_pipelines/index.html)
要为合并请求配置CI作业,我们必须在合并请求的作业上设置only: merge_request
。然后我们可以在这些工作中使用CI_MERGE_REQUEST_*
变量。
这里最大的陷阱是only: merge_request
与正常的only/except
参数有完全不同的行为。
通常的only/except
参数:(https://docs.gitlab.com/ce/ci/yaml/README.html#onlyexcept-basic)
only
定义了作业将运行的分支和标记的名称。except
定义了作业不会运行的分支和标记的名称。
only: merge_request
(https://docs.gitlab.com/ce/ci/merge_request_pipelines/index.html#excluding-certain-jobs)
only: merge_requests
参数的行为是这样的:只有具有该参数的作业才会在合并请求的上下文中运行;没有其他工作可以运行。
我觉得很难重新组织工作,使他们像以前一样工作,任何工作都存在only: merge_request
。因此,我仍然在我的原始答案中使用单行程来获取CI工作中的MR信息。
原始答案:
没有。
但GitLab在2019年第二季度有一个关于此功能的计划:https://gitlab.com/gitlab-org/gitlab-ce/issues/23902#final-assumptions
目前,我们可以使用解决方法来实现此目的。这个方法就像Rekovni的回答所描述的那样,它确实有效。
有一个简单的单行,从当前分支获取MR的目标分支:
script: # in any script section of gitlab-ci.yml
- 'CI_TARGET_BRANCH_NAME=$(curl -LsS -H "PRIVATE-TOKEN: $AWESOME_GITLAB_API_TOKEN" "https://my.gitlab-instance.com/api/v4/projects/$CI_PROJECT_ID/merge_requests?source_branch=$CI_COMMIT_REF_NAME" | jq --raw-output ".[0].target_branch")'
说明:
CI_TARGET_BRANCH_NAME
是一个新定义的变量,用于存储已解析的目标分支名称。各种用法不需要定义变量。
AWESOME_GITLAB_API_TOKEN
是在存储库的CI / CD变量配置中配置的变量。它是一个带有api
范围的GitLab个人访问令牌(在用户设置中创建)。
关于curl
选项:-L
让curl知道HTTP重定向。 -sS
使卷曲沉默(-s
)但显示(-S
)错误。 -H
指定访问GitLab API的权限信息。
使用的API可以在https://docs.gitlab.com/ce/api/merge_requests.html#list-project-merge-requests中创建。我们使用source_branch
属性来确定正在运行的MR当前管道。因此,如果源分支具有多个MR到不同的目标分支,您可能想要在|
之后更改该部分并执行您自己的逻辑。
关于jq
(https://stedolan.github.io/jq/),它是一个简单的CLI工具,用于处理JSON内容(GitLab API返回的内容)。你可以使用node -p
或任何你想要的方法。
由于new env variables在11.6 $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
和$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
工作可以包括或排除基于源或目标分支。
使用only and except (complex)表达式,我们可以构建一个规则来过滤合并请求。举几个例子:
Merge request where the target branch ismaster
:
only:
refs:
- merge_requests
variables:
- $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"
Merge request except if the source branch is master
or release
:
only:
- merge_requests
except:
variables:
- $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "master"
- $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "release"
如果你想使用多个引用(比如merge_requests和tags)和多个变量,引用将是OR'd,the variables will be OR'd和the result will be AND'd:
如果变量中的任何条件仅在使用时评估为真值,则将创建新作业。如果任何表达式在使用except时评估为真值,则不会创建作业。
如果在only或except下使用多个键,则它们充当AND。逻辑是:
(any of refs) AND (any of variables) AND (any of changes) AND (if kubernetes is active)
变量表达式也很原始,只支持相等和(基本)正则表达式。因为变量将是OR,所以你不能同时指定gitlab 11.6中的源分支和目标分支,只是一个或另一个。
如果这是你真正想要的,可能会有一种非常复杂的方式(未经测试)你可以使用merge request API和CI variables实现这一目标。
使用工作流程/构建步骤,例如:
feature/test
到master
的合并请求CI_PROJECT_ID
变量从当前项目获取所有打开的合并请求,并按source_branch
和target_branch
过滤。source_branch
和target_branch
分别是feature/test
和master
,继续构建,否则只是跳过构建的其余部分。对于使用API,我不相信您可以使用CI_JOB_TOKEN
变量进行身份验证,因此您可能需要创建自己的personal access token并将其存储为CI variable以在构建作业中使用。
希望这可以帮助!
从GitLab 11.6开始,有CI_MERGE_REQUEST_TARGET_BRANCH_NAME
。