-
-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is GitHub Actions example correct? #497
Comments
The cache key name includes the OTP version and the Elixir version, so the cache will be updated when those versions change. Still, I agree this is probably not quite correct, the key name should probably also include a hash of mix.lock. Otherwise some extra work will be done on each subsequent build after dependencies are changed. It looks like all the CI examples have this same issue. In practice it may not slow down the jobs too much but I agree it does not seem ideal to offer an example like this. I'm curious for @Nezteb's take just in case I'm missing something here as he added the Gitlab example relatively recently and it uses |
@jeremyjh yes the chache name includes OTP and Elixir version and it works well for core PLTs, but project specific PLT need extra work at every run. I've just configured my repo in this way and it seems to work:
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
...
dialyzer: [plt_core_path: "priv/plts"],
...
]
end
...
end
name: Elixir build
...
jobs:
checks:
name: Analyze and test
steps:
- name: Git clone the repository
uses: actions/checkout@v3
- name: Set up Elixir
id: beam
uses: erlef/setup-beam@v1
with:
elixir-version: "1.14.4"
otp-version: "25"
- name: Build cache
uses: actions/cache@v3
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- 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
restore-keys: ${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
path: priv/plts
- name: Create PLTs
if: steps.plt_cache.outputs.cache-hit != 'true'
run: mix dialyzer --plt
- name: Save PLT cache
id: plt_cache_save
uses: actions/cache/save@v3
if: steps.plt_cache.outputs.cache-hit != 'true'
with:
key: ${{ runner.os }}-${{ steps.beam.outputs.elixir-version }}-${{ steps.beam.outputs.otp-version }}-plt
path: priv/plts
- name: Compile code
run: mix compile
- name: Check code format
run: mix format --check-formatted
- name: Run credo
run: mix credo --strict --all
- name: Run dialyzer
run: mix dialyzer --format github
- name: Run tests
run: mix test
... Now, my dialyzer setp last 4s and it outputs |
Yeahhh, there aren't really any better keys that I can think of unless you use every single source file in a project as part of the key. At first glance I think that'd be slow and not a good use of a build cache. 😅 In an ideal world, these build artifacts (including the PLTs) aren't changing that much between branches, so that shouldn't be necessary. EDIT: Removed the stuff I got wrong. I'll also ping @akasprzok to verify since he wrote the original blog post that led to me to update the GitHub Actions example and create a new one for GitLab CI. 😄 EDIT: I'm wrong, because dialyzer: [
plt_core_path: "priv/plts/core.plt",
plt_local_path: "priv/plts/local.plt"
] Instead of: dialyzer: [
plt_file: {:no_warn, "priv/plts/dialyzer.plt"}
] I'm currently traveling but I'll take another look at this when I'm back! |
@Nezteb I'm thinking just adding |
@jeremyjh Ah that makes sense. Would it also be worth getting rid of the I can start a PR later today. 😄 |
|
Thanks for the ping! The problem I kept running into was that I'd push a change, and dialyzer would fail 9 minutes later (bigish code base). Then I'd push the fix, and have to wait another 9 minutes for all green. Simply getting rid of that second 9 minutes was pretty big for me. Adding mix.lock to the key does make sense I think. |
Simply adding the @Nezteb I made some test and Furthermore, it's better to store the cache at the end too, in order to cache project-level PLT. My proposal is to use the cache mechanism described in the current github action example to handle only the core PLT files (the ones generated by |
@luigi-discoup I tested this, and... it depends. 😅 1.
|
@Nezteb great job! Thank you. I've only tested configuration For the configuration
but it seems that there actually are PLTs in I think that configuration With the configuration ...
- name: Build cache
uses: actions/cache@v3
with:
path: |
deps
_build
priv/plts/local
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
... maybe the Anyway, I vote for the |
Whoops yeah that was just a bad copy-paste on my part. I edited the comment. 😅
I'm inclined to agree! I'll update my docs PR to reflect that. 😄 |
👋 It might be safer to rebuild PLTs for the application on each run, otherwise Dialyzer might not catch the errors. That is, if someone uses a workflow like the following: static:
env:
MIX_ENV: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: erlef/setup-beam@v1
with:
elixir-version: [1.17]
otp-version: [27]
# in mix.exs under project.dialyzer: `plt_file: {:no_warn, "priv/plts/dialyzer.plt"},`
- uses: actions/cache@v4
with:
path: |
deps
_build
priv/plts
key: static-${{ github.head_ref || github.ref }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
static-${{ github.head_ref || github.ref }}-
static-refs/heads/master-
- run: mix deps.get
- run: mix dialyzer Then Dialyzer only checks the files that have been modified in the PR. This might have something to do with the new Elixir/Erlang versions as I don't remember this being the case in the past. |
Precheck
Environment
Elixir & Erlang/OTP versions (elixir --version):
Elixir 1.14.4 (compiled with Erlang/OTP 25)
Which version of Dialyxir are you using? (cat mix.lock | grep dialyxir):
"dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"},
Question
From the Continuous Integration documentation page, I see that I have to put
plt_file: {:no_warn, "priv/plts/dialyzer.plt"}
in thedialyzer
project property and configure the GitHub Actions cache as described here, but I'm not sure about this configuration.Using the GitHub Actions cache configuration provided, the PLT cache will be stored only once, and every subsequent changes in source code or dependencies will be analyzed again and never stored in cache so the project specific PLT wil be generated every time. Am I right?
As far as I understand, reading the PLT section, a better configuration would be to put
plt_core_path: "priv/plts"
indialyzer
configuration instead ofplt_file
, leaving the local PLT file in its default location_build/env/dialyze_erlang-[OTP Version]_elixir-[Elixir Version]_deps-dev.plt
and caching the_build
folder separatly.The text was updated successfully, but these errors were encountered: