Travis CI Cache 与 Git 的冲突问题
和很多持续集成服务一样,Travis CI 也支持将安装的依赖缓存起来加快每次构建的速度,但是 Travis CI 的缓存在一些情况下会和外部 Git Repo 引起冲突导致构建失败。把问题和解决方法记录下来。
准确说大部分 CI 的缓存机制都存在这个问题。
hexo-theme-suka 的之中有用到 Travis CI 进行测试,包括使用一个 Hexo 站点工程文件构建一个 Demo 站点,而 Hexo 工程文件和 Hexo 主题的 Repo 是分开的。由于 Travis CI 是配置在 hexo-theme-suka 的 Repo 下进行持续集成,所以构建过程中需要把 Hexo 工程文件中的 Repo 给 clone 下来。
在 Travis CI 的配置文件中设置缓存 node_modules
目录以后,邮箱就收到 Travis CI 构建失败的提示邮件。查看 Travis CI 的日志可以发现 Travis CI 弹出了报错:
明明这个目录是在构建中使用 git clone
命令创建的,为什么还会提示非空目录?
开个新 branch 打个断点,在 Travis CI 的构建流程 git clone
外部 Repo 之前,加一个 ls
指令把目录列出来。然后再看构建日志,发现目录下面有 node_modules
——目录非空的原因就是 Travis CI 会在构建一开始就把缓存的目录下载导入。
解决方案就是,设法让构建中需要 git clone
到的目录和最后被缓存的目录不相同。实现的具体思路就是:
- 构建时先进行
git clone
,这时相关的文件会放在目录 A cd
到 clone 下来的 Repo 里删掉.git
文件夹- 将整个目录
mv
到新的位置目录 B - 在目录 B 中安装依赖(如执行
yarn
或者npm i
)并进行构建 - 最后缓存在目录 B 中安装的依赖
这样,在下一次构建的时候,Travis CI 就会先把缓存的依赖储存到目录 B 中,目录 A 尚未创建,就不影响 git clone
。而安装依赖是在将目录 A 中的文件移动到目录 B(合并)以后再执行的。