diff --git a/documentation/topics/development/migrations-and-tasks.md b/documentation/topics/development/migrations-and-tasks.md index 694a2dd..815e335 100644 --- a/documentation/topics/development/migrations-and-tasks.md +++ b/documentation/topics/development/migrations-and-tasks.md @@ -6,32 +6,19 @@ ## Tasks -The available tasks are: - -- `mix ash_postgres.generate_migrations` -- `mix ash_postgres.create` -- `mix ash_postgres.drop` -- `mix ash_postgres.migrate` (use `mix ash_postgres.migrate --tenants` to run tenant migrations) - -AshPostgres is built on top of ecto, so much of its behavior is pass-through/orchestration of that tooling. +Ash comes with its own tasks, and AshPostgres exposes lower level tasks that you can use if necessary. This guide shows the process using `ash.*` tasks, and the `ash_postgres.*` tasks are illustrated at the bottom. ## Basic Workflow - Make resource changes -- Run `mix ash_postgres.generate_migrations` to generate migrations and resource snapshots -- Run `mix ash_postgres.migrate` to run those migrations -- Run `mix ash_postgres.migrate --tenants` _as well_ if you have multi-tenant resources. +- Run `mix ash.codegen --name add_a_combobulator` to generate migrations and resource snapshots +- Run `mix ash.migrate` to run those migrations -For more information on generating migrations, see the module documentation here: -`Mix.Tasks.AshPostgres.GenerateMigrations`, or run `mix help ash_postgres.generate_migrations` +For more information on generating migrations, run `mix help ash_postgres.generate_migrations` (the underlying task that is called by `mix ash.migrate`) -For running your migrations, there is a mix task that will find all of the repos configured in your domains and run their -migrations. It is a thin wrapper around `mix ecto.migrate`. Ours is called `mix ash_postgres.migrate` - -If you want to run or rollback individual migrations, use the corresponding - -For tenant migrations (see the multitenancy guides for more) generated by multitenant resources, make sure you are using -`mix ash_postgres.generate_migrations`. It is not sufficient to run `mix ash_postgres.migrate --migrations_path tenant_migrations_path`. You will also need to define a `list_tenants/0` function in your repo module. See `AshPostgres.Repo` for more. +> ### list_tenants/0 {: .info} +> +> If you have are using schema-based multitenancy, you will also need to define a `list_tenants/0` function in your repo module. See `AshPostgres.Repo` for more. ### Regenerating Migrations @@ -44,28 +31,23 @@ Often, you will run into a situation where you want to make a slight change to a N_MIGRATIONS=$(git ls-files --others priv/repo/migrations | wc -l) # Rollback untracked migrations -mix ecto.rollback -n $N_MIGRATIONS +mix ash_postgres.rollback -n $N_MIGRATIONS # Delete untracked migrations and snapshots git ls-files --others priv/repo/migrations | xargs rm git ls-files --others priv/resource_snapshots | xargs rm # Regenerate migrations -mix ash_postgres.generate_migrations +mix ash.codegen --name $1 # Run migrations if flag if echo $* | grep -e "-m" -q then - mix ecto.migrate + mix ash.migrate fi ``` -After saving this file to something like `regen.sh`, make it executable with `chmod +x regen.sh`. Now you can run it with `./regen.sh`. If you would like the migrations to automatically run after regeneration, add the `-m` flag: `./regen.sh -m`. - -## Multiple Repos - -If you are using multiple repos, you will likely need to use `mix ecto.migrate` and manage it separately for each repo, as the options would -be applied to both repo, which wouldn't make sense. +After saving this file to something like `regen.sh`, make it executable with `chmod +x regen.sh`. Now you can run it with `./regen.sh name_of_operation`. If you would like the migrations to automatically run after regeneration, add the `-m` flag: `./regen.sh name_of_operation -m`. ## Running Migrations in Production @@ -164,3 +146,11 @@ Tasks that need to be executed in the released application (because mix is not p end end ``` + +### AshPostgres-specific mix tasks + +- `mix ash_postgres.generate_migrations` +- `mix ash_postgres.create` +- `mix ash_postgres.drop` +- `mix ash_postgres.migrate` (use `mix ash_postgres.migrate --tenants` to run tenant migrations) +- `mix ash_postgres.rollback` (use `mix ash_postgres.rollback --tenants` to rollback tenant migrations) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index bf4f1f3..d4e51f0 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -420,15 +420,18 @@ defmodule AshPostgres.DataLayer do |> Enum.map(fn {file, index} -> "#{index + 1}: #{file}" end) n = - Mix.shell().prompt(""" - How many migrations should be rolled back#{for_repo}? (default: 0) + Mix.shell().prompt( + """ + How many migrations should be rolled back#{for_repo}? (default: 0) - Last 20 migration names, with the input you must provide to - rollback up to *and including* that migration: + Last 20 migration names, with the input you must provide to + rollback up to *and including* that migration: - #{Enum.join(files, "\n")} - Rollback to: - """ |> String.trim_trailing()) + #{Enum.join(files, "\n")} + Rollback to: + """ + |> String.trim_trailing() + ) |> String.trim() |> case do "" -> @@ -484,7 +487,11 @@ defmodule AshPostgres.DataLayer do end end - Mix.Task.run("ash_postgres.rollback", args ++ ["--tenants", "-r", inspect(repo), "-n", to_string(n)]) + Mix.Task.run( + "ash_postgres.rollback", + args ++ ["--tenants", "-r", inspect(repo), "-n", to_string(n)] + ) + Mix.Task.reenable("ash_postgres.rollback") end end @@ -507,7 +514,23 @@ defmodule AshPostgres.DataLayer do # TODO: take args that we care about Mix.Task.run("ash_postgres.create", args) Mix.Task.run("ash_postgres.migrate", args) - Mix.Task.run("ash_postgres.migrate", ["--tenant" | args]) + + [] + |> AshPostgres.Mix.Helpers.repos!(args) + |> Enum.all?(fn repo -> + [] + |> AshPostgres.Mix.Helpers.tenant_migrations_path(repo) + |> Path.join("**/*.exs") + |> Path.wildcard() + |> Enum.empty?() + end) + |> case do + true -> + :ok + + _ -> + Mix.Task.run("ash_postgres.migrate", ["--tenant" | args]) + end end def tear_down(args) do