Instantly share code, notes, and snippets.

Embed
What would you like to do?
Migration script when release a Phoenix/OTP app by Distillery
# apps/myapp/lib/migration.ex
defmodule MyApp.ReleaseTasks do
@start_apps [
:postgrex,
:ecto
]
@app :myapp
def repos, do: Application.get_env(@app, :ecto_repos, [])
def seed do
prepare()
# Run seed script
Enum.each(repos(), &run_seeds_for/1)
# Signal shutdown
IO.puts("Success!")
end
defp run_seeds_for(repo) do
# Run the seed script if it exists
seed_script = seeds_path(repo)
if File.exists?(seed_script) do
IO.puts("Running seed script..")
Code.eval_file(seed_script)
end
end
def migrate do
prepare()
Enum.each(repos(), &run_migrations_for/1)
IO.puts("Migrations successful!")
end
defp run_migrations_for(repo) do
app = Keyword.get(repo.config, :otp_app)
IO.puts("Running migrations for #{app}")
Ecto.Migrator.run(repo, migrations_path(repo), :up, all: true)
end
def rollback do
prepare()
get_step =
IO.gets("Enter the number of steps: ")
|> String.trim()
|> Integer.parse()
case get_step do
{int, _trailing} ->
Enum.each(repos(), fn repo -> run_rollbacks_for(repo, int) end)
IO.puts("Rollback successful!")
:error ->
IO.puts("Invalid integer")
end
end
defp run_rollbacks_for(repo, step) do
app = Keyword.get(repo.config, :otp_app)
IO.puts("Running rollbacks for #{app} (STEP=#{step})")
Ecto.Migrator.run(repo, migrations_path(repo), :down, all: false, step: step)
end
defp prepare do
IO.puts("Loading #{@app}..")
# Load the code for myapp, but don't start it
:ok = Application.load(@app)
IO.puts("Starting dependencies..")
# Start apps necessary for executing migrations
Enum.each(@start_apps, &Application.ensure_all_started/1)
# Start the Repo(s) for myapp
IO.puts("Starting repos..")
Enum.each(repos(), & &1.start_link(pool_size: 1))
end
defp migrations_path(repo), do: priv_path_for(repo, "migrations")
defp seeds_path(repo), do: priv_path_for(repo, "seeds.exs")
defp priv_path_for(repo, filename) do
app = Keyword.get(repo.config, :otp_app)
IO.puts("App: #{app}")
repo_underscore = repo |> Module.split() |> List.last() |> Macro.underscore()
Path.join([priv_dir(app), repo_underscore, filename])
end
defp priv_dir(app), do: "#{:code.priv_dir(app)}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment