Current section

Files

Jump to
mandrag lib mix tasks mandrag.deploy.ex
Raw

lib/mix/tasks/mandrag.deploy.ex

defmodule Mix.Tasks.Mandrag do
defmodule Deploy do
use Mix.Task
@shortdoc "Deploys an exrm release."
def run(_) do
case initial_deploy? do
true -> prepare; build; start
false -> build; upgrade
end
end
defp prepare, do: _prepare(location)
defp build, do: _build(location)
defp _prepare(:local) do
ssh "mkdir -p #{name}/run"
end
defp _prepare(:remote) do
ssh "git clone #{repo} #{name}"
ssh "mkdir #{name}/priv/static"
ssh "mkdir #{name}/run"
end
defp _build(:local) do
Mix.Task.run "compile"
Mix.Shell.IO.cmd "npm install"
Mix.Shell.IO.cmd "node_modules/brunch/bin/brunch build --production"
Mix.Task.run "phoenix.digest", []
Mix.Task.run "release", []
end
defp _build(:remote) 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 --production"
ssh "cd #{name} && MIX_ENV=#{Mix.env} mix phoenix.digest"
ssh "cd #{name} && MIX_ENV=#{Mix.env} mix release"
end
defp start do
case location do
:local ->
if Code.ensure_loaded?(Ecto) do
Mix.Task.run "ecto.create", []
Mix.Task.run "ecto.migrate", []
Mix.Task.run "run", ["priv/repo/seeds.exs"]
end
scp "rel/#{name}/releases/#{version}/#{name}.tar.gz", "#{name}/run/#{name}.tar.gz"
:remote ->
if Code.ensure_loaded?(Ecto), do: ssh "cd #{name} && MIX_ENV=#{Mix.env} mix do ecto.create, ecto.migrate, run priv/repo/seeds.exs"
ssh "cp #{name}/rel/#{name}/releases/#{version}/#{name}.tar.gz #{name}/run"
end
ssh "cd #{name}/run && tar xf #{name}.tar.gz && rm #{name}.tar.gz"
_run("start")
end
defp upgrade do
case location do
:local ->
ssh "mkdir #{name}/releases/#{version}"
scp "rel/#{name}/releases/#{version}/#{name}.tar.gz", "#{name}/releases/#{version}/#{name}.tar.gz"
if Code.ensure_loaded?(Ecto), do: Mix.Task.run "ecto.migrate", []
:remote ->
ssh "mkdir #{name}/run/releases/#{version}"
ssh "cp #{name}/rel/#{name}/releases/#{version}/#{name}.tar.gz #{name}/run/releases/#{version}/"
if Code.ensure_loaded?(Ecto), do: ssh "cd #{name} && MIX_ENV=#{Mix.env} mix ecto.migrate"
scp "config/prod.secret.exs", "#{name}/config/prod.secret.exs"
end
# If we don't have an existing rel directory, we can't do hot upgrades :(
case rel_dir?(location) do
true -> _run("upgrade '#{version}'")
false -> _run("stop"); _run("start")
end
end
defp _run(command), do: ssh("#{name}/run/bin/#{name} #{command}")
defp initial_deploy?, do: ssh("ls #{name} &>/dev/null") != 0
defp rel_dir?(:local), do: File.ls("rel") |> elem(1) |> Enm.any?
defp rel_dir?(:remote), 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