alwaystest / Blog

24 stars 2 forks source link

GitLab-CI的Cache #45

Open alwaystest opened 7 years ago

alwaystest commented 7 years ago

GitLab-CI的Cache

标签(空格分隔): CI


https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/280

I had this problem too but I think it stems from a fundamental misunderstanding of the cache feature. What I (and, I think @mohamnag) want it to do is cache files between jobs of the same build. But what it does is cache files between builds of the same job. In this example, AssembleCode, RunTests and PreserveArtifacts each have their own completely independent caches which are restored before each run. Whats more each branch has its own set of caches meaning if you tend to only push to each branch once when creating a merge request, your cache will almost always be empty.

Android单元测试的运行需要依赖编译APK阶段生成的一些文件,但是我把编译和单元测试放到了GitLab-CI的不同stage中,导致单元测试一直报错。

本来一直想通过cache来解决这个问题,调试了很长时间依然发现cache好像并没有起作用。结果发现原来GitLab-CI的cache是作用于每个Build之间的相同job上的。看官方文档根本看不出来好吧。。。

stages stages is used to define build stages that can be used by jobs. The specification of stages allows for having flexible multi stage pipelines. The ordering of elements in stages defines the ordering of builds' execution:

  1. Builds of the same stage are run in parallel.
  2. Builds of the next stage are run after the jobs from the previous stage complete successfully.

cache Introduced in GitLab Runner v0.7.0. cache is used to specify a list of files and directories which should be cached between builds. By default the caching is enabled per-job and per-branch. If cache is defined outside the scope of the jobs, it means it is set globally and all jobs will use its definition.

stage里面定义的_Builds of the same stage_我的理解是stage影响了Builds,那么Builds就指的是jobs。那下面再说_files and directories which should be cached between builds._那意思不就是jobs之间会有cache么。。。

我想安静地做一会阅读理解。

既然cache不能胜任这项工作,https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/merge_requests/80 又给了使用artifacts传递的办法,每次编译anroid,build文件夹太大了,不合适,除非我自己手动识别哪些文件是被单元测试依赖的,然后定制规则。

那么就先用笨办法顶着吧,单元测试也跑一次编译好了。

启用cache之后,每次build显示Removing xxx是正常的,GitLab的Issue中提到那是git clean执行的效果,执行完毕后会从cache读取,还原要保留的文件。


经过Debug,原来是Application中读取了字体文件。路径是build/intermediates/xxxx,没有运行编译的情况下,字体文件是不会存放在这里的。导致单元测试报错。

实际上,Presenter层的单元测试不应该依赖于编译期间产生的文件,出现这种情况,是之前在电脑上调试APK的时候已经执行过编译,运行单元测试是没有问题的。但是放到了隔离编译APK和单元测试的环境中,运行结果就不一样了,主要还是因为Application类没有解耦完全。

MockApplication重写掉加载字体的方法,在单元测试中使用空实现即可。不用每次单元测试都得跑编译啦!