在 GitLab CI 中,合并请求的目标分支是不是有变量?
Posted
技术标签:
【中文标题】在 GitLab CI 中,合并请求的目标分支是不是有变量?【英文标题】:In GitLab CI, is there a variable for a Merge Request's target branch?在 GitLab CI 中,合并请求的目标分支是否有变量? 【发布时间】:2019-03-15 17:25:32 【问题描述】:在我的管道中,我希望仅当合并请求目标分支是某个分支(例如 master 或 release)时才运行作业。
这可能吗?
我已经阅读了https://docs.gitlab.com/ee/ci/variables/,除非我遗漏了什么,否则我看不到任何有用的东西。
【问题讨论】:
【参考方案1】:更新:2019-03-21
GitLab 从 11.6 版开始就有用于合并请求信息的变量(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_requests
然后我们可以在这些作业中使用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 年 Q2 有此功能的计划: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 变量配置中配置的变量。这是一个 GitLab 个人访问令牌(在用户设置中创建),具有api
范围。
关于curl
选项:-L
使 curl 了解 HTTP 重定向。 -sS
使 curl 静默(-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
或任何您想要的方法。
【讨论】:
【参考方案2】:Gitlab CI 与合并请求无关(目前)。由于管道在源分支上运行,您将无法检索目标。
【讨论】:
【参考方案3】:由于 11.6 中的 new env variables $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
和 $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
作业可以根据源或目标分支包含或排除。
使用only and except (complex) 表达式,我们可以构建一个规则来过滤合并请求。举几个例子:
目标分支为master
的合并请求:
only:
refs:
- merge_requests
variables:
- $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"
合并请求除非源分支是master
或 release
:
only:
- merge_requests
except:
variables:
- $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "master"
- $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "release"
如果你想使用多个引用(比如 merge_requests 和标签)和多个变量,引用将是 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'd,所以从 gitlab 11.6 开始,您不能同时指定源分支和目标分支,只能指定一个。
【讨论】:
【参考方案4】:从 GitLab 11.6 开始,有 CI_MERGE_REQUEST_TARGET_BRANCH_NAME
。
【讨论】:
【参考方案5】:如果这是您真正想要的,可能有一种极其复杂的方式(未经测试),您可以使用merge request API 和CI variables 实现此目的。
使用类似的工作流/构建步骤:
-
创建从
feature/test
到master
的合并请求
开始构建
使用 API(在脚本中),使用 CI_PROJECT_ID
变量从当前项目中获取所有打开的合并请求,并按 source_branch
和 target_branch
过滤。
如果有一个合并请求打开,source_branch
和 target_branch
分别是 feature/test
和 master
,请继续构建,否则跳过其余的构建。
对于使用 API,我不相信您可以使用 CI_JOB_TOKEN
变量进行身份验证,因此您可能需要创建自己的 personal access token 并将其存储为 CI variable 以在构建中使用工作。
希望这会有所帮助!
【讨论】:
以上是关于在 GitLab CI 中,合并请求的目标分支是不是有变量?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Gitlab CI 管道始终运行一些作业,而其他作业仅在合并请求上运行?
在 GitLab Pipelines 中,有没有办法在分离合并请求时运行管道?
来自 gitlab-ci 的状态不再显示在 gitlab 合并请求中