Gitlab管道启动,即使在合并请求批准后应该启动
我已经在gitlab中创建了一个项目,并且在gitlab.yaml文件中有以下条目。在我推动项目中的任何更改之后,管道就开始了。是否可以更改此设置,以便管道仅在用户提交合并请求并获得批准后才进行统计 这是我的Gitlab管道启动,即使在合并请求批准后应该启动,gitlab,Gitlab,我已经在gitlab中创建了一个项目,并且在gitlab.yaml文件中有以下条目。在我推动项目中的任何更改之后,管道就开始了。是否可以更改此设置,以便管道仅在用户提交合并请求并获得批准后才进行统计 这是我的.gitlab ci.yaml文件: 阶段: -试验 -登台 -刺激 测试: 阶段:测试 标签: -试验 脚本: -cd应用程序目录 -cd试验 -git签出 -吉特拉力 除: -主人 时间:总是 仅: -试验 仅: -合并请求 允许失败:false 登台: 阶段:阶段 标签: -登台 脚本
.gitlab ci.yaml
文件:
阶段:
-试验
-登台
-刺激
测试:
阶段:测试
标签:
-试验
脚本:
-cd应用程序目录
-cd试验
-git签出
-吉特拉力
除:
-主人
时间:总是
仅:
-试验
仅:
-合并请求
允许失败:false
登台:
阶段:阶段
标签:
-登台
脚本:
脚本:
-cd应用程序目录
-cd分期
-git签出
-吉特拉力
除:
-主人
时间:总是
仅:
-试验
仅:
-合并请求
允许失败:false
产品:
阶段:Prod
标签:
-刺激
脚本:
-cd应用程序目录
-光盘产品
-git签出
-吉特拉力
除:
-主人
时间:总是
仅:
-试验
仅:
-合并请求
允许失败:false
变量:
GIT_战略:克隆
有一种方法可以仅在合并请求获得批准时运行作业,但由于必须与Approvals API交互,因此该方法更为复杂。但是,只有付费客户才能访问ApprovalsAPI,可以访问gitlab.com,也可以访问自托管gitlab实例
ApprovalsAPI有一个操作,用于获取合并请求的批准状态(文档位于此处:)。您可以使用以下命令调用它:curl--header“PRIVATE-TOKEN:${PRIVATE\u TOKEN}”https://your.gitlab.instance.com/api/v4/projects/:project_id:/merge_requests/:merge_request_id:/approval_state“
其中,$PRIVATE_TOKEN
是至少具有api
作用域的个人访问令牌
:project\u id
字段是项目的id,您可以从Gitlab CI提供的一个预定义变量获取该id:$CI\u project\u id
。:merge\u request\u id:
是管道的特定合并请求的id,如果存在:$CI\u merge\u request\u IID
。有了这两个变量,curl命令现在是:curl--header“PRIVATE-TOKEN:${PRIVATE_-TOKEN}”https://your.gitlab.instance.com/api/v4/projects/${CI_项目_ID}/merge_请求/${CI_merge_请求_IID}/approval_state”。注意:合并请求ID有两个预定义变量。一个是
$CI\u MERGE\u REQUEST\u ID,它是gitlab实例范围的ID,另一个是
$CI\u MERGE\u REQUEST\u IID',它是特定于项目的ID。对于此操作,我们需要特定于项目的IID变量
“获取批准状态”操作的结果包含诸如所需批准者的数量(如果适用)、符合条件的批准者以及迄今为止已批准的人等信息。看起来是这样的:
{
"approval_rules_overwritten": true,
"rules": [
{
"id": 1,
"name": "Ruby",
"rule_type": "regular",
"eligible_approvers": [
{
"id": 4,
"name": "John Doe",
"username": "jdoe",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
"web_url": "http://localhost/jdoe"
}
],
"approvals_required": 2,
"users": [
{
"id": 4,
"name": "John Doe",
"username": "jdoe",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
"web_url": "http://localhost/jdoe"
}
],
"groups": [],
"contains_hidden_groups": false,
"approved_by": [
{
"id": 4,
"name": "John Doe",
"username": "jdoe",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
"web_url": "http://localhost/jdoe"
}
],
"source_rule": null,
"approved": true,
"overridden": false
}
]
}
一旦得到结果,就必须对其进行解析,以便使用这些信息确定哪些作业将运行或不运行。这是一个很好的选择。首先,将ApprovalsAPI的输出保存到一个文件中,然后我们可以使用jq
。如果为合并请求启用了必需的批准,则可以使用cat output | jq.[“规则”][“必需的批准”].
获取所需的编号。要获得批准合并请求的人数,我们可以使用以下内容解析该文件:cat output | jq.[“rules”][“approved_by”]| length'
您可以在中阅读有关jq
的更多信息
一旦有了这些值,就由您决定合并请求何时被视为“已批准”或“未批准”。也许您需要所有必需的批准,或者只有一个批准人,或者由特定人员批准
根据您只希望为已批准的合并请求运行的作业数,您可以在作业本身中运行所有这些作业,但如果有许多作业未经批准不应运行,则将每个作业都放入会令人沮丧。幸运的是,还有另一个Gitlab CI特性可以帮助我们。从Gitlab 12.9版开始,您可以将文件作为工件上传
,它将把内容作为环境变量,供后续管道中使用
例如,让我们添加一个在管道中所有其他作业之前运行的作业,以达到ApprovalsAPI,使用jq
解析输出,并决定是否应该运行作业
stages:
- check_approvals
...
Check Merge Request Approvals:
stage: check_approvals
when:never
rules:
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
when: always
script:
- curl --header "PRIVATE-TOKEN: ${API_ACCESS_TOKEN}" "https://your.gitlab.instance.com/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/approval_state > approvals_output
- REQUIRED_APPROVALS = $(cat approvals_output | jq '.["rules"][]["approvals_required"]')
- APPROVALS_COUNT = $(cat approvals_output | jq '.["rules"][]["approved_by"] | length')
- RUN_PIPELINE=false; if ["$APPROVALS_COUNT" -ge "$REQUIRED_APPROVALS"] then
RUN_PIPELINE=true
fi
- echo "RUN_PIPELINE=${RUN_PIPELINE}" >> variables
artifacts:
reports:
dotenv: variables
dotenv
报告类型允许我们在一个作业阶段中定义变量,并在以后的所有阶段中共享它们。通过将此作业置于第一阶段,管道中的所有其他阶段都可以访问$RUN\u pipeline
变量。对于上面的示例,从API获得批准值后,我们将批准数量与所需数量进行比较。如果批准数大于或等于所需的批准数,我们将变量设置为true。否则就是假的
默认情况下,我们将此作业设置为从不运行,然后检查包含启动管道的事件的$CI\u PIPELINE\u SOURCE
变量是否为合并请求\u事件。如果是,我们将运行作业。这确保将设置$CI\u MERGE\u REQUEST\u IID
变量
现在,在所有其他只有在合并请求获得批准时才应运行的作业中,我们可以检查变量的值:
Deploy to Prod:
stage: deploy
when: never
rules:
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event' && $RUN_PIPELINE"
when: always
script:
- ...
首先,我们再次检查管道源,因为如果变量不存在,$RUN\u pipeline
将不存在,然后我们检查$RUN\u pipeline
是否为真。如果是,则运行作业,否则默认为从不运行
资源: