logo

鱼肚的博客

Don't Repeat Yourself

Gitlab CI的精细化控制

当CI复杂到一定程度之后,就会衍生出各种各样的细致的控制需求。Gitlab CI默认的控制器能实现一定程度的控制。

失败时继续执行后续任务

Gitlab CI中默认情况下,如果上个阶段中有任务未成功执行,则下个阶段会被取消。这是因为它默认配置了 when: on_success 的条件,只有当前面的任务完成时,才会执行后续任务。

如果想接受一个任务失败,不阻塞后续任务,有两个方式能实现:

  1. 设置此任务的属性,allow_failure: true 参考allow_failure说明
  2. 设置此任务后续任务的属性,when: always 参考when的说明

类似地,还可以设置任务失败后的后续处理等。

自动取消过时的pipeline

当提交比较频繁时,可能会产生多个pipeline排队的情况。如果每次pipeline都是可以替代之前的pipeline的,那只有最新的commit需要执行pipeline,其余的已经没有意义了。

这种情况下,可以设置Gitlab自动取消过时的pipeline。

在"Settings->CI/CD"中,找到"Auto-cancel redundant, pending pipelines",勾选上它就可以了。

失败后自动重试

Gitlab 中提供了retry选项,可以设置任务失败后自动重试,最多重试两次,即总共3次。

且失败的时候,可以限制重试的原因。示例:

1test:
2  script: rspec
3  retry:
4    max: 2
5    when:
6      - runner_system_failure
7      - stuck_or_timeout_failure

具体的用法可参考官方文档:retry

自动取消过时的Job

Gitlab v12.3之后提供了新的控制选项:interruptible,相较于Gitlab仓库中设置的"Auto-cancel redundant, pending pipelines",它的控制维度更细,细化到了一个Job的级别。

可惜的就是依赖的版本比较高,目前还没用上过。

如果想要在旧版Gitlab中实现类似的效果,可利用webhook技术,在本文的最后部分会提到。

跳过pipeline

如果在CI中涉及到自动修改代码的场景,有可能会希望修改之后的代码不再触发CI。

这种情况下,可以在提交信息中加上[skip ci][ci skip],就可以自动跳过了。

Webhook

最后,假如有Gitlab中暂不支持的功能需求,或者用的是Gitlab旧版本,没有某个需求。可以考虑使用webhook机制,自定义控制。

关于Webhook相关的介绍,可参考Gitlab官方文档:Webhooks

它的原理,简要地说就是在Gitlab仓库的各项事件发生时,Gitlab服务器可以调用一个外部服务,将相关信息发送给它。在这个服务中,配置上Gitlab Token就可以通过API或者一些封装SDK,如nodejs中的gitbeaker,来操作Git仓库,控制它的各项内容了。