Skip to content

Unnecessary umbrella recompilation when a path dependency's manifest is newer but unchanged #15454

Description

@fuelen

Existing issue

  • I have searched existing issues and could not find a duplicate.

Elixir and Erlang/OTP versions

Elixir 1.20.1 (compiled with Erlang/OTP 29). Also reproduced on current main (fcf47f3)

Operating system

macos, also reproduced inside hexpm/elixir:1.20.1-erlang-29.0.1-alpine-3.22.4

Current behavior

We cache _build between CI jobs of a 40-app umbrella. Despite the cache being warm and sources unchanged, every job recompiles hundreds of files (every %Events.X{} pattern match across the umbrella), and the recompilation set shrinks from one mix compile invocation to the next 169 files, then 67, then 23, then clean. This behaviour forced us into a "compile several times and touch _build in between" hack in CI.

Script that reproduces the behaviour:

#!/bin/sh
set -e

mix new repro --umbrella --app repro > /dev/null
cd repro/apps
mix new app_a > /dev/null
mix new app_b > /dev/null
perl -pi -e 's/# \{:sibling_app_in_umbrella, in_umbrella: true\}/{:app_a, in_umbrella: true}/' app_b/mix.exs

echo 'defmodule AppA.Event, do: defstruct [:id]' > app_a/lib/event.ex
cat > app_b/lib/handler.ex <<'EOF'
defmodule AppB.Handler do
  def handle(%AppA.Event{id: id}), do: id
end
EOF
cd ..

mix compile

sleep 2
echo "# comment" >> apps/app_a/lib/event.ex
echo "--- edit that does not change exports: only app_a should recompile"
mix compile

sleep 2
touch mix.exs apps/*/mix.exs config/config.exs
echo "--- after touching mix project files: app_b recompiles handler.ex"
mix compile --verbose

echo "--- and finaly, no recompilation"
mix compile --verbose

Expected behavior

No recompilation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions