Single version number for umbrella application?

I’m sure there must be an easy and/or idiomatic way to do this, but I haven’t managed to find it.

If I have an umbrella application with several applications inside it, is it possible to define an overall version number somewhere and have it picked up by the individual apps, the umbrella app (now that exdoc seems to require a version for that too) and by distillery for releases? I’m currently having to bump versions in three separate mix.exs files, plus rel/config.exs, every time I want to make a release, which is tedious and error prone.

I think I can use set version: current_version(:some_app_name) to configure the release version, so that’s one off the list, but any hints to combine the individual app versions would be appreciated.

1 Like

A VERSION.txt file (containing the version) in the root directory and the appropriate String.trim(File.read!("[path]/VERSION.txt")) where version is needed can do the job if that works for you.

Thanks! That’s the kind of thing I would automatically have done in Ruby, but for some reason I expected the “right” answer in Elixir to be something fancier. Sometimes (usually?) the simple solutions are the best.

You might be able to grab the overall umbrella’s version from the Mix build system somehow?

Sorry to resurrect a very old topic,

It is still this the only way to set a version for the whole umbrella app?
There is still no way to get the version from main mix.exs in the umbrella app folder?

I just ran into this problem too. Here’s something I came up with. It’s still clunky, but slightly less clunky IMO since it stores the version number in the project config, where I think it belongs.

  • Define the version number in the project config:

config/config.exs

config :your_project, version: "0.1.0"
  • To retrieve the version number in the parent project’s mix.exs:

mix.exs

defmodule YourProject.Umbrella.MixProject do
  use Mix.Project

  @version Config.Reader.read!("config/config.exs", env: Mix.env())[:your_project][:version]

  def project do
    [
      apps_path: "apps",
      version: @version,
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      aliases: aliases(),
    ]
  end

  # ...
end
  • To retrieve the version number in a child project’s mix.exs:

apps/your_project/mix.exs

defmodule YourProject.MixProject do
  use Mix.Project

  @version Config.Reader.read!("../../config/config.exs", env: Mix.env())[:your_project][:version]

  def project do
    [
      app: :your_project,
      version: @version,
      build_path: "../../_build",
      config_path: "../../config/config.exs",
      # ...
    ]
  end

  # ...
end
  • To retrieve the version number in your application code:

apps/your_project/lib/your_project/some_module.ex

defmodule YourProject.SomeModule do
  # Get the value as a compile-time module attribute
  @project_version Application.compile_env!(:your_project, :version)

  # Get the value in a function
  def get_project_version do
    Application.fetch_env!(:your_project, :version)
  end
end