defmodule Mix.Tasks.Mandrag do defmodule Deploy do use Mix.Task @shortdoc "Deploys an exrm release." def run(_) do initial = initial_deploy? case initial do true -> prepare; build(initial); start false -> build(initial); upgrade end end defp prepare, do: _prepare(location) defp build(initial), do: _build(location, initial) defp _prepare(:local) do Mix.Task.run "ecto.setup" ssh "mkdir -p #{name}" scp "rel/#{name}/releases/#{version}/#{name}.tar.gz", "#{name}/#{name}.tar.gz" ssh "cd #{name} && tar xf #{name}.tar.gz && rm #{name}.tar.gz" end defp _prepare(:remote) do Mix.Task.run "ecto.setup" ssh "git clone #{repo} #{name}" ssh "mkdir #{name}/priv/static" ssh "mkdir #{name}/run" end defp _build(:local, initial) do scp "config/prod.secret.exs", "#{name}/config/prod.secret.exs" Mix.Task.run "deps.get" Mix.Task.run "compile" Mix.Shell.IO.cmd "npm install" Mix.Shell.IO.cmd "brunch build" Mix.Task.run "phoenix.digest", [] Mix.Task.run "release", [] end defp _build(:remote, initial) do ssh "cd #{name} && git pull" scp "config/prod.secret.exs", "#{name}/config/prod.secret.exs" ssh "cd #{name} && MIX_ENV=#{Mix.env} mix deps.get" ssh "cd #{name} && MIX_ENV=#{Mix.env} mix compile" ssh "cd #{name} && npm install" ssh "cd #{name} && node_modules/brunch/bin/brunch build" ssh "cd #{name} && MIX_ENV=#{Mix.env} mix phoenix.digest" ssh "cd #{name} && MIX_ENV=#{Mix.env} mix release" if initial do ssh "cp #{name}/rel/#{name}/releases/#{version}/#{name}.tar.gz #{name}/run" ssh "cd #{name}/run && tar xf #{name}.tar.gz && rm #{name}.tar.gz" end end defp start do case location do :local -> Mix.Task.run "ecto.setup", [] :remote -> ssh "cd #{name} && MIX_ENV=#{Mix.env} mix ecto.setup" end _run("start") end defp upgrade do case location do :local -> scp "rel/#{name}/releases/#{version}/#{name}.tar.gz", "#{user}@#{host}:#{name}/releases/#{version}/" Mix.Task.run "ecto.migrate", [] :remote -> ssh "cp #{name}/rel/#{name}/releases/#{version}/#{name}.tag.gz #{name}/run/releases/#{version}/" ssh "cd #{name} && MIX_ENV=#{Mix.env} mix ecto.migrate" scp "config/prod.secret.exs", "#{name}/config/prod.secret.exs" end _run("upgrade '#{version}'") end defp _run(command) do path = (location == :local) && "#{name}/bin/#{name}" || "#{name}/run/bin/#{name}" ssh("#{path} #{command}") end defp initial_deploy?, do: ssh("ls #{name} &>/dev/null") != 0 # ssh helpers defp ssh_options, do: "-i#{key} -oStrictHostKeyChecking=no" defp ssh(command), do: Mix.Shell.IO.cmd "ssh #{user}@#{host} #{ssh_options} '#{command}'" defp scp(source, destination), do: Mix.Shell.IO.cmd "scp #{ssh_options} #{source} #{user}@#{host}:#{destination}" # config helpers defp location, do: Application.get_env(:mandrag, :build_location) defp user, do: Application.get_env(:mandrag, :user) defp host, do: Application.get_env(:mandrag, :host) defp key, do: Application.get_env(:mandrag, :key) defp name, do: Application.get_env(:mandrag, :name) defp version, do: Application.get_env(:mandrag, :version) defp repo, do: Application.get_env(:mandrag, :repo) end end