I gave a try to cache-based approach inspired by @hellwolf here.
TL;DR: it is surely possible, but it is far more complicated compared to the artifact-based approach (at least with GitHub cache alone).
The basic strategy is to include commit hash in the final cache key and requires exact matching in Testing Phase.
However, there are several points to be carefully considered to get everything as expected:
- If you include hash of files into the cache keys to share the common cache across the builds (e.g. to share the cache of
~/.cache/storebased on the contents ofcabal.project.freezeandpackage.yamls), , we must consistently use the one computed at appropriate point.- For example, if you use
hashFiles('**/*.hs')in cache key, this hash must be computed right after checking-out because some new.hsfiles can be generated underdist-newstyleand/or somesource-repository-packagecan introduce extra hs-files. - We also must be pay attention to use exactly the same key in Testing and Building Phases - I used workflow output mechanism to ensure Testing Phase to use the same key.
- For example, if you use
- We must call
cabalwith the same configuration both in Testing and Building phase - otherwise,cabal testwill recompile some parts needlessly.- Indeed, I am not successful in this regard. I decided to use custom project file
cabal-ci.projectfor CI, but, alas, cabal test seems recompiling local modules…
- Indeed, I am not successful in this regard. I decided to use custom project file
That being said, as we must keep the consistency between Building and Testing Phases, it is far more lightweight to use artifacts mechanism than caches. This story is of course about GitHub Caching mechanism, though. Perhaps Nix can offer more clever caching or haskell-ci could do this more well. So please let me know if anyone is doing this kinda thing with caching mechanism.