Skip to content

Commit

Permalink
Merge pull request #499 from Nezteb/ci-docs-cache-changes
Browse files Browse the repository at this point in the history
Update CI caching docs/examples
  • Loading branch information
jeremyjh committed May 22, 2023
2 parents 3008741 + ef92a9d commit e955646
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 22 deletions.
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,25 @@ If invoked without arguments, `mix dialyzer.explain` will list all the known war

To use Dialyzer in CI, you must be aware of several things:

1. Building the PLT file may take a while if a project has many dependencies
2. The PLT should be cached using the CI caching system
3. The PLT will need to be rebuilt whenever adding a new Erlang or Elixir version to your build matrix
1. Building the project-level PLT file may take a while if a project has many dependencies.
2. The project-level PLT should be cached using the CI caching system.
1. Optional: The core Erlang/Elixir PLT could also be cached in CI.
3. The PLT will need to be rebuilt whenever adding a new Erlang or Elixir version to your build.

```elixir
# mix.exs
def project do
[
...
dialyzer: [
plt_file: {:no_warn, "priv/plts/dialyzer.plt"}
# Put the project-level PLT in the priv/ directory (instead of the default _build/ location)
plt_file: {:no_warn, "priv/plts/project.plt"}

# The above is equivalent to:
# plt_local_path: "priv/plts/project.plt"

# You could also put the core Erlang/Elixir PLT into the priv/ directory like so:
# plt_core_path: "priv/plts/core.plt"
]
]
end
Expand Down Expand Up @@ -107,15 +115,15 @@ The Persistent Lookup Table (PLT) is basically a cached output of the analysis.
a fork if you had to wait for Dialyzer to analyze all the standard library and OTP modules you are using every time you ran it.
Running the mix task `dialyzer` by default builds several PLT files:

* A core Erlang file in `$MIX_HOME/dialyxir_erlang-[OTP Version].plt`
* A core Elixir file in `$MIX_HOME/dialyxir_erlang-[OTP Version]_elixir-[Elixir Version].plt`
* A project environment specific file in `_build/env/dialyze_erlang-[OTP Version]_elixir-[Elixir Version]_deps-dev.plt`
* A core Erlang file in `$MIX_HOME/dialyxir_erlang-$OTP_VERSION.plt`
* A core Elixir file in `$MIX_HOME/dialyxir_erlang-$OTP_VERSION-$ELIXIR_VERSION.plt`
* A project environment specific file in `_build/$MIX_ENV/dialyze_erlang-$OTP_VERSION_elixir-$ELIXIR_VERSION_deps-$MIX_ENV.plt`

The core files are simply copied to your project folder when you run `dialyxir` for the first time with a given version of Erlang and Elixir. By default, all the modules in the project PLT are checked against your dependencies to be sure they are up to date. If you do not want to use MIX_HOME to store your core Erlang and Elixir files, you can provide a `:plt_core_path` key with a file path. You can specify a different directory for the project PLT file with the `:plt_local_path` keyword.

The core files are simply copied to your project folder when you run `dialyxir` for the first time with a given version of Erlang and Elixir. By default, all
the modules in the project PLT are checked against your dependencies to be sure they are up to date. If you do not want to use MIX_HOME to store your core Erlang and Elixir files, you can provide a `:plt_core_path` key with a file path. You can specify a different directory for the project PLT file with the `:plt_local_path keyword`. You can specify a different filename for the project PLT file with the `:plt_file keyword` - this is deprecated because people were using it with the old `dialyxir` to have project-specific PLTs, which are now the default. To silence the deprecation warning, specify this value as `plt_file: {:no_warn, "/myproject/mypltfile"}`.
You can also specify a different filename for the project PLT file with the `:plt_file` keyword option. This is deprecated for local use, but fine to use in CI. The reason for the local deprecation is that people were using it with older versions of `dialyxir` to have project-specific PLTs, which are now the default. To silence the deprecation warning in CI, specify this value as `plt_file: {:no_warn, "/myproject/mypltfile"}`.

The core PLTs include a basic set of OTP applications, as well as all of the Elixir standard libraries.
The apps included by default are `[:erts, :kernel, :stdlib, :crypto]`.
The core PLTs include a basic set of OTP applications, as well as all of the Elixir standard libraries. The apps included by default are `[:erts, :kernel, :stdlib, :crypto]`.

If you don't want to include the default apps you can specify a `:plt_apps` key and list there only the apps you want in the PLT. Using this option will mean dependencies are not added automatically (see below). If you want to just add an application to the list of defaults and dependencies you can use the `:plt_add_apps` key.

Expand Down
7 changes: 3 additions & 4 deletions docs/circleci.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,23 @@ jobs:

# Compile steps omitted for simplicity

# Don't cache PLTs based on mix.lock hash, as Dialyzer can incrementally update even old ones
# Cache key based on Elixir & Erlang version (also useful when running in matrix)
# Cache key based on Erlang/Elixir version and the mix.lock hash
- run:
name: "Save Elixir and Erlang version for PLT caching"
command: echo "$ELIXIR_VERSION $ERLANG_VERSION" > .elixir_otp_version

- restore_cache:
name: "Restore PLT cache"
keys:
- {{ arch }}-{{ checksum ".elixir_otp_version" }}-plt
- plt-{{ arch }}-{{ checksum ".elixir_otp_version" }}-{{ checksum "mix.lock" }}

- run:
name: "Create PLTs"
command: mix dialyzer --plt

- save_cache:
name: "Save PLT cache"
key: {{ arch }}-{{ checksum ".elixir_otp_version" }}-plt
key: plt-{{ arch }}-{{ checksum ".elixir_otp_version" }}-{{ checksum "mix.lock" }}
paths: "priv/plts"

- run:
Expand Down
11 changes: 5 additions & 6 deletions docs/github_actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ steps:
id: beam
uses: erlef/setup-beam@v1
with:
elixir-version: "1.12.3" # Define the Elixir version
otp-version: "24.1" # Define the OTP version
elixir-version: "1.12.3" # Define the Elixir version

# Don't cache PLTs based on mix.lock hash, as Dialyzer can incrementally update even old ones
# Cache key based on Elixir & Erlang version (also useful when running in matrix)
# Cache key based on Erlang/Elixir version and the mix.lock hash
- name: Restore PLT cache
id: plt_cache
uses: actions/cache/restore@v3
with:
key: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-
path: |
priv/plts
Expand All @@ -38,7 +37,7 @@ steps:
if: steps.plt_cache.outputs.cache-hit != 'true'
with:
key: |
${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
plt-${{ runner.os }}-${{ steps.beam.outputs.otp-version }}-${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}
path: |
priv/plts
Expand Down
4 changes: 3 additions & 1 deletion docs/gitlab_ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ build-dev:
cache:
- key:
files:
- mix.lock
- .tool-versions
- mix.lock
paths:
- deps/
- _build/dev
Expand All @@ -41,6 +41,7 @@ dialyzer-plt:
- key:
files:
- .tool-versions
- mix.lock
paths:
- priv/plts
# Pull cache at start, push updated cache after completion
Expand All @@ -56,6 +57,7 @@ dialyzer-check:
- key:
files:
- .tool-versions
- mix.lock
paths:
- priv/plts
# Pull cache at start, don't push cache after completion
Expand Down

0 comments on commit e955646

Please sign in to comment.