I’m working my way through Engineering Elixir Applications and I’m running into an issue that I hope is something easy. I’m on page 103 if anyone else has the book. Workstation used for running through the examples: M1 Mac.
When running the Github Action it fails with the following:
Run mix dialyzer --format github
mix dialyzer --format github
shell: /usr/bin/bash -e {0}
env:
MIX_ENV: test
INSTALL_DIR_FOR_OTP: /home/runner/work/_temp/.setup-beam/otp
INSTALL_DIR_FOR_ELIXIR: /home/runner/work/_temp/.setup-beam/elixir
Finding suitable PLTs
Checking PLT...
[:asn1, :bandit, :castore, :compiler, :crypto, :dns_cluster, :eex, :elixir, :ex_unit, :expo, :finch, :floki, :gettext, :hpax, :jason, :kanban, :kernel, :logger, :mime, :mint, :nimble_options, :nimble_pool, :phoenix, :phoenix_html, :phoenix_live_dashboard, :phoenix_live_view, :phoenix_pubsub, :phoenix_template, :plug, :plug_crypto, :public_key, :runtime_tools, :ssl, :stdlib, :swoosh, :telemetry, :telemetry_metrics, :telemetry_poller, :thousand_island, :websock, :websock_adapter, :xmerl]
Looking up modules in project.plt
Finding applications for project.plt
Finding modules for project.plt
Removing 1374 modules from project.plt
:dialyzer.run error: File not found: /opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/dialyzer-5.1.3/ebin/erl_bif_types.beam
Adding 1338 modules to project.plt
:dialyzer.run error: File not found: /opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/dialyzer-5.1.3/ebin/erl_bif_types.beam
done in 0m3.53s
No :ignore_warnings opt specified in mix.exs and default does not exist.
Starting Dialyzer
[
check_plt: false,
init_plt: ~c"/home/runner/work/kanban/kanban/priv/plts/project.plt",
files: [~c"/home/runner/work/kanban/kanban/_build/test/lib/kanban/ebin/Elixir.Kanban.Application.beam",
~c"/home/runner/work/kanban/kanban/_build/test/lib/kanban/ebin/Elixir.Kanban.Mailer.beam",
~c"/home/runner/work/kanban/kanban/_build/test/lib/kanban/ebin/Elixir.Kanban.beam",
~c"/home/runner/work/kanban/kanban/_build/test/lib/kanban/ebin/Elixir.KanbanWeb.ConnCase.beam",
~c"/home/runner/work/kanban/kanban/_build/test/lib/kanban/ebin/Elixir.KanbanWeb.CoreComponents.beam",
...],
warnings: [:unknown]
]
:dialyzer.run error: File not found: /opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/dialyzer-5.1.3/ebin/erl_bif_types.beam
Halting VM with exit status 1
From the book I’ve setup the following workflow (ci_cd.yaml below, as of page 103 for those that have it).
# in ci_cd.yaml
name: CI/CD Elixir
on:
push:
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-latest
name: Compile with mix test, format, dialyzer & unused deps check
env:
MIX_ENV: test
steps:
- uses: actions/checkout@v4
- name: Setup Elixir
uses: erlef/setup-beam@v1.17.3
with:
version-file: .tool-versions
version-type: strict
- name: Cache deps directory
uses: actions/cache@v4
id: cache-deps
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-
- name: Cache plt files
uses: actions/cache@v4
env:
EX_OTP_VERSIONS: ${{ steps.setup-beam.outputs.elixir-version }}
KEY_BASE: plt-${{ runner.os }}-${{ env.EX_OTP_VERSIONS }}
with:
path: |
priv/plts
key: |
${{ env.KEY_BASE }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ env.KEY_BASE }}-
- name: Get dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
run: mix deps.get
- run: mix compile
- name: Run tests
run: mix test --max-failures 1 --trace
- name: Check code is formatted
run: mix format --check-formatted
- name: Dialyzer static analysis
run: MIX_ENV=dev mix dialyzer --format github
- name: Check unused dependencies
run: mix deps.unlock --check-unused
As seen above this Workflow runs-on: ubuntu-latest. From the Workflow errors we’re calling for a file in the path of /opt/homebrew/Cellar/ and failing, because this isn’t macOS (I’m unaware of another homebrew tool)
In my .gitignore I have the following:
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Typical Elixir ignore files
/_build
/cover
/deps
/doc
/.fetch
erl_crash.dump
*.ez
*.beam
/config/*.secret.exs
.elixir_ls/
/priv/plts/*.plt
/priv/plts/*.plt.hash
So - I’d expect deps and _build cache to not be present (and they aren’t in my repo). When I search for Cellar in my local (macOS) working directory grep -Rnw ‘.’ -e ‘Cellar’ I see:
Binary file ./_build/test/lib/floki/ebin/floki_selector_lexer.beam matches
Binary file ./_build/test/lib/erlex/ebin/erlex_parser.beam matches
Binary file ./_build/test/lib/erlex/ebin/erlex_lexer.beam matches
Binary file ./_build/dev/lib/erlex/ebin/erlex_parser.beam matches
Binary file ./_build/dev/lib/erlex/ebin/erlex_lexer.beam matches
./deps/floki/src/floki_selector_lexer.erl:1:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/leexinc.hrl", 0).
./deps/floki/src/floki_selector_lexer.erl:30:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/leexinc.hrl", 14).
./deps/floki/src/floki_selector_lexer.erl:1340:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/leexinc.hrl", 344).
./deps/erlex/src/erlex_parser.erl:7:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/yeccpre.hrl", 0).
./deps/erlex/src/erlex_lexer.erl:1:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/leexinc.hrl", 0).
./deps/erlex/src/erlex_lexer.erl:17:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/leexinc.hrl", 14).
./deps/erlex/src/erlex_lexer.erl:851:-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/leexinc.hrl", 344).
Spot checking ./deps/erlex/src/erlex_parser.erl:7 I see:
-module(erlex_parser).
-export([parse/1, parse_and_scan/1, format_error/1]).
-file("src/erlex_parser.yrl", 137).
unwrap({_,_,V}) -> V.
-file("/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/lib/parsetools-2.5/include/yeccpre.hrl", 0).
I’m a little lost on how my dialyzer.run via Github action is failing with the missing file error. If the ubuntu-latest is downloading / building the dependancies on that virtual machine then how is it failing / looking for Cellar/homebrew file locations? As shown above when I search from the root of my project I’m only seeing the matching results in my _build and deps folders - which are excluded.
Happy to add snippets of other files or anything to help me track this down. Thanks for the time if you’ve made it this far.