Problem with __mix_recompile__?/0 and releases

Hey, I run a blog similar as outlined in the Dashbit blog.
But have a misunderstanding (or found a bug?) when using __mix_recompile__?/0 with releases.

Once I release the code below with __mix_recompile__?/0 present,
list_post/0` is always empty within the running release.

defmodule MyApp.Blog do
  @moduledoc false

  alias MyApp.Blog.Post

  blog_data_path = Application.fetch_env!(:my_app, :blog_data_path)
  posts_path_wildcard = "#{blog_data_path}/**/*.md"

  posts_paths = Path.wildcard(posts_path_wildcard)
  posts_path_hash = :erlang.md5(posts_paths)

  posts =
    for post_path <- posts_paths do
      @external_resource Path.relative_to_cwd(post_path)
      Post.parse!(post_path)
    end

  @posts Enum.sort_by(posts, & &1.date, {:desc, Date})

  def list_posts, do: @posts

  def __mix_recompile__?() do
    blog_data_path = Application.fetch_env!(:my_app, :blog_data_path)
    posts_path_wildcard = "#{blog_data_path}/**/*.md"

    Path.wildcard(posts_path_wildcard) |> :erlang.md5() != unquote(posts_path_hash)
  end
end

Could anybody help me?

__mix_recompiled__? has no effect in a release. To be clear, in the approach mentioned in our blog, the only way to publish a new post is by recompiling the code and doing a whole new release. Everything is done at compile time.

Also note we have released a library called nimble_publisher that encapsulates most of the blog post for you. :slight_smile:

1 Like

Hi Jose, the approach is clear (compile time).
I do run mix compile & mix release each time for post updates.
And it works perfectly fine as long as I don’t add __mix_recompiled__? to my module.
It then still works locally (dev) but really not anymore remote on my server (prod).

So is there anything different for e.g. Application.fetch_env! when __mix_recompile__?/0 is present?
If I inspect my blog_data_path it always seems to be set correctly…


By the way - nimble_publisher is cool, wasn’t aware of it.
But I have built a shop system with this approach, not just the blog example above.

1 Like

Aha moment.
My mix release is encapsulated (nix-build) and has no access to my blog_data_path.
So during mix release my module gets recompiled again…

That’s the missing step I wasn’t aware of.
Tanks.


Adding --no-compile to mix release should do it!

1 Like

Oh, awesome find. So __mix_recompile__? was actually working as expected and, because of it, it was recompiling which uncovered the bug of blog_data_path pointing to the wrong directory?

Something else you can do is to check if posts is empty and if so, you raise, as they never should be empty from now on.

Yeah, it definitely works as expected!

Check & raise if empty is really a good idea.