How to find the release name during compile time?

My system has two different releases, I want to change compile time configurations and enable/disable code at compile time depending on which release I’m building.

I know I can use the env variable RELEASE_NAME during runtime to find which release was generated, but I can’t figure out how to find that during compilation time.

Is there some way to achieve that?

I don’t think you can. Compiling a release does mix compile internally, so it’s literally no different to any other time your mix project is compiled.

I’ve used MIX_TARGET to do stuff like this before. If you have:

# mix.exs

def project do
  [
    releases: [
      demo: [
        include_executables_for: [:unix],
        applications: [runtime_tools: :permanent]
      ],
      staging: [
        # ...
      ]
    ]
  ]
end

Instead of just doing

$ MIX_ENV=prod mix release demo

You could do

$ MIX_ENV=prod MIX_TARGET=demo mix release demo

Just like MIX_ENV, Config is target-aware, so you can set some compile-time config there based on config_target, and then code can reference those values with Application.compile_env to enable/disable what you want.


Example:

# config/config.exs

# Something specific configured for the demo release
case config_target() do
  :demo -> config Ecto.Repo, :special, :case
  :staging -> config Ecto.Repo, :other, :case
end

# Dedicated files containing configuration for each release
import_config "#{config_target()}.exs"

# Something generally available for reference when compiling your code
config :my_app, :release_mode, config_target()
# lib/my_app.ex

case Application.compile_env!(:my_app, :release_mode) do
  :demo -> def release_variant, do: :whatever
  :staging -> def release_variant, do: :whatever_else
end

MIX_TARGET defaults to :host, so you can cover that case to assume local development or raise an error in config/config.exs if you want to force folk to be explicit.

4 Likes