lib/mix/tasks/altworx.scenario_release.ex

defmodule Mix.Tasks.Altworx.ScenarioRelease do
  use Mix.Task

  @shortdoc "Assembles an Altworx scenario release for production usage"

  @moduledoc """
  Assembles an Altworx scenario release for the current project. It is done in
  a docker container based on an image which ensures correct erlang and Elixir
  versions, so they are compatible with Altworx.

      $ mix altworx.scenario_release

  """

  @builder_image_name "altworx/builder-elixir"

  @impl true
  def run(_args) do
    unless docker_build() == 0 do
      raise RuntimeError, "Error building the docker image"
    end

    unless docker_run() == 0 do
      raise RuntimeError, "Error building the scenario release in the docker container"
    end
  end

  defp docker_build do
    priv_dir = :code.priv_dir(:runbox)

    {_, ret} =
      System.cmd("docker", ["build", "--tag", @builder_image_name, to_string(priv_dir)],
        into: IO.stream()
      )

    ret
  end

  defp docker_run do
    cwd = File.cwd!()
    {user, 0} = System.cmd("id", ["-u"])
    user = String.trim(user)
    {group, 0} = System.cmd("id", ["-g"])
    group = String.trim(group)

    {_, ret} =
      System.cmd(
        "docker",
        [
          "run",
          "--user",
          "#{user}:#{group}",
          "--volume",
          "#{cwd}:/mnt/source",
          "--workdir",
          "/mnt/source",
          "--init",
          "--rm",
          @builder_image_name,
          "/usr/local/bin/build-scenarios",
          "/mnt/source"
        ],
        into: IO.stream()
      )

    ret
  end
end