在使用gitlab runner的过程中,发现由于git存储限制,不允许在a/b分支后创建a/b/c的分支。所以移除云端a/b分支后创建a/b/c分支。
但是由于gitlab runner出于拉取代码的速度考虑,将本地代码路径做了持久化缓存。
在上述场景中,新建的a/b/c分支触发的pipeline,如果被调度到已经缓存过a/b分支的runner上时,会发生由于本地.git路径中的a/b路径 已经存在,导致a/b/c分支不能创建的问题。
排查方案如下:
1. 经调研,gitlab runner在fetch code的场景下默认会增加--prune --quite的参数。同时可以通过GIT_FETCH_EXTRA_FLAGS参数覆盖原本的--prune --quite参数。
gitlab-runner 相关代码
2. 使用默认参数和指定GIT_FETCH_EXTRA_FLAGS=--prune -v两种方式均无法清理runner代码缓存中历史a/b分支
3. 使用CI_DEBUG_TRACE=true环境变量,打印更多debug日志发现,git fetch实际执行指令为:
git -c 'http.userAgent=gitlab-runner ${runner version} linux/amd64' fetch origin +refs/heads/${CI_REF_NAME}:refs/remotes/origin/${CI_REF_NAME} +refs/heads/${CI_PIPELINE_ID}:refs/remotes/origin/${CI_PIPELINE_ID} --depth 300 --prune --quiet
经过排查,在fetch指定特定特殊分支和pipeline的情况下,不会再使用默认fetch的src:dst,
4. 尝试在GIT_FETCH_EXTRA_FLAGS参数中追加所有分支的ref配置:
+refs/heads/*:refs/remotes/origin/*
Git - git-fetch Documentation
GIT_FETCH_EXTRA_FLAGS='
+refs/heads/*:refs/remotes/origin/* --prune --prune-tags -v'
5. 使用CI_DEBUG_TRACE=true的环境变量,发现runner中fetch code的命令行已经符合预期使用GIT_FETCH_EXTRA_FLAGS替换原本的--prune --quiet,成功删除runner cach呃中历史的a/b分支,并成功fetch成功a/b/c分支
6. 验证是否由于gitlab runner版本原因,默认--prune --quiet已经扩展新指令。但从最新release的gitlab runner中,还移除了原本已经上线的prune tag when fetching code的功能。
Revert "Prune tags when fetching" (!4300) · Merge requests · GitLab.org / gitlab-runner · GitLab
考虑到4300的mr中提到的大repo的性能损耗的问题,暂时不开启第5条操作