问题描述:

前端仓库的 CI Runner 并行处理两个 job 有概率出现报错内容缺失或出包内容错误。

Untitled

问题分析:

Untitled

​ Gitlab 官方称:当只有一个 runner 在运行并且每个[[runner]] section 都有独立的 build 路径,concurrent 是生效的。若有多个 runner 使用同个 config.toml 文件或共享同个 build 路径,即使设置了 concurrent 为 1,也还是会有概率出现一个 runner 并发处理多个 job 的问题,官方认为这是用户的错误配置。config.toml 文件允许存在多个[[runner]] section,但这个 bug 会导致 concurrent 失效。

​ 根据上次 ci runner 出现打包内容错误的问题推测是当时 config.toml 配置上的失误,即多个 runner 使用同个 config.toml 文件并且没有指定 build_dir(默认对应于宿主机的目录是在宿主机 的 docker volume ),因此有概率出现一个 runner 同时处理两个 job 的情况(curcurrent 设置为 1),再加上一个 runner 映射一个 volume,从 gitlab 上拉下的源代码都存储在同个 volume,后拉的替换先拉的,最终导致必有一个 job 打出的包有问题含有其他分支的内容或直接报错编译失败。

Untitled

​ Branch_3.5.3 出的 sp4 包内容含其他分支的内容也就同样能解释通了,从下图中可以看出两次 job 先后执行并且持续了一段时间,但使用的是同一台 runner、同一个 volume,由于 Branch_3.5.3 的 job(后文称 job1)率先执行,所以 volume 内存储了 Branch_3.5.3 分支的源代码,5 分钟后,Branch_cmcc_sdwan 的 job(后文称 job2)开始执行并且此时 job1 还未结束,runner checkout 到了 job2 的分支并将 job2 的源代码存储到了相同的 volume,即 job1 的源代码被 job2 替换了。不幸的是此次编译过程没有报错,打包成功了,最终导致在无感知的情况下给出了错误的包。

Untitled

解决方案:

一个 runner 独立使用一个 config.toml 文件,这样 config.toml 文件中的 concurrent = 1 配置就会生效,也就规避了 concurrent 配置失效导致一个 runner 同时处理多个 job 触发的 bug。