# \[CI Caching\] Downloading project dependencies without building the app?

**URL:** https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140
**Category:** Learn
**Created:** [February 6, 2020, 4:26pm UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140 "2020-02-06T16:26:39Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Janiczek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/janiczek/32/4516_2.png) [@Janiczek](https://discourse.elm-lang.org/u/Janiczek)
#### Post date: [February 6, 2020, 4:26pm UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140/1 "2020-02-06T16:26:39Z")

</div>

Hello! After the recent [package.elm-lang.org](http://package.elm-lang.org) situation we’re trying to cache the ELM\_HOME directory in Docker/Drone CI, to be more resilient to zipballs HTTP request outages and also to not do needless work in each CI build.

The problem we’re dealing with is: _we don’t want to trigger downloading packages on every application code change_ (`source_directories`).

The way Dockerfiles work makes us do:

- ADD elm.json
- ADD all the various source\_directories (we have a lot of them)
- RUN elm make some/File.elm --output /dev/null

which has the disadvantage mentioned above.

A workaround I can see is making temporary Elm files which the Dockerfile will then try to compile. Thus skipping the “ADD source directories” step.

But it seems to me something like `elm make --install-only` or `elm-json download` (cc @ilias) would be more correct solution.

Do you see a different solution?

---

<div class="post-metadata">

### Author: ![ilias](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ilias/32/6_2.png) [@ilias](https://discourse.elm-lang.org/u/ilias)
#### Post date: [February 6, 2020, 5:04pm UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140/2 "2020-02-06T17:04:26Z")

</div>

Running `elm make` without arguments is basically an `--install-only` command.

Caveats:

- the source-directories must exists, however, they don’t have to have anything in them. So if you can get away with something like `mkdir -p foo bar/baz`, that would be an easy solution!
- it exits with `1` so it’s hard to distinguish from “actual” failure

---

<div class="post-metadata">

### Author: ![Janiczek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/janiczek/32/4516_2.png) [@Janiczek](https://discourse.elm-lang.org/u/Janiczek)
#### Post date: [February 7, 2020, 9:43am UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140/3 "2020-02-07T09:43:12Z")

</div>

At the moment, until a better solution arrives, we went with the hack:

```auto
# A hack to be able to download dependencies without compiling our source code
# ------
# We want to avoid `COPY ./client /pro/client` before the `elm make` above all costs.
# That would download the dependencies on every code change...
# ------
# Plan:
# * `mkdir -p` the source directories
# * create a dummy Elm module in one of them
# * compile that one

COPY elm.json /pro/elm.json

RUN mkdir -p \
    client/_factories \
    client/_share/src \
    client/app-monolithic/src \
    client/audience-builder \
    client/chart-builder/src \
    client/crosstab-builder/src \
    client/dashboards/src \
    client/elm-dashboards/src \
    client/fullscreen-search \
    client/products/src \
    client/settings/src \
    client/tv-study/src

RUN echo "module DummyMain exposing (..)\nx = 1" >client/app-monolithic/src/DummyMain.elm

RUN elm make ./client/app-monolithic/src/DummyMain.elm --output /dev/null
# ^ Now we have downloaded the dependencies in a layer that's before adding the source code!
# That means dependencies will only download when elm.json changes, not when the source directories change.

RUN rm -rf ./client/app-monolithic/src/DummyMain.elm

# Sometime later: COPY ./client /pro/client

```

---

<div class="post-metadata">

### Author: ![choonkeat](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/choonkeat/32/1555_2.png) [@choonkeat](https://discourse.elm-lang.org/u/choonkeat)
#### Post date: [February 12, 2020, 4:44am UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140/4 "2020-02-12T04:44:00Z")

</div>

Adapted from your code, I made [a pair of `Dockerfile` and `Makefile`](https://gist.github.com/choonkeat/d40462479dce88182a7ac8c5bd87f2c4) that is cache friendly (only injecting `elm.json` and `Dockerfile` itself for the build) and can be applied to individual projects. As long as it’s run against the same docker server, the layers should cache automatically.

```auto
make elm-stuff/.elm

```

then subsequently, CI commands just need to have env `ELM_HOME=elm-stuff/.elm` set

e.g.

```auto
export ELM_HOME=elm-stuff/.elm
elm-test
elm make src/Main.elm

```

---

<div class="post-metadata">

### Author: ![turboMaCk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/turbomack/32/355_2.png) [@turboMaCk](https://discourse.elm-lang.org/u/turboMaCk)
#### Post date: [February 12, 2020, 10:17am UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140/5 "2020-02-12T10:17:13Z")

</div>

While I think work around like this can work for most of the people there are some additional things you might be interested in.

- `ELM_HOME` environment variable can be used to define location of elm cache

- Elm uses `registry.dat` binary which is a snapshot of packages.

- [This is how you can download package data without elm](https://github.com/NixOS/nixpkgs/blob/99f2e88123192fea040c46681d7497f1d0933db4/pkgs/development/compilers/elm/makeDotElm.nix)

- [This is how binary file is generated](https://github.com/cachix/elm2nix/blob/38b61e45a860d7512f2ec2e458cf01c688835ddf/src/Elm2Nix/PackagesSnapshot.hs)

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [February 22, 2020, 10:17am UTC](https://discourse.elm-lang.org/t/ci-caching-downloading-project-dependencies-without-building-the-app/5140/6 "2020-02-22T10:17:18Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
