Gitlab管道启动,即使在合并请求批准后应该启动

Gitlab管道启动,即使在合并请求批准后应该启动,gitlab,Gitlab,我已经在gitlab中创建了一个项目,并且在gitlab.yaml文件中有以下条目。在我推动项目中的任何更改之后,管道就开始了。是否可以更改此设置,以便管道仅在用户提交合并请求并获得批准后才进行统计 这是我的.gitlab ci.yaml文件: 阶段: -试验 -登台 -刺激 测试: 阶段:测试 标签: -试验 脚本: -cd应用程序目录 -cd试验 -git签出 -吉特拉力 除: -主人 时间:总是 仅: -试验 仅: -合并请求 允许失败:false 登台: 阶段:阶段 标签: -登台 脚本

我已经在gitlab中创建了一个项目,并且在gitlab.yaml文件中有以下条目。在我推动项目中的任何更改之后,管道就开始了。是否可以更改此设置,以便管道仅在用户提交合并请求并获得批准后才进行统计

这是我的
.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
是否为真。如果是,则运行作业,否则默认为从不运行

资源: