ecto-release-migrations
Ecto Release Migrations Setup
Overview
In Elixir releases, Mix is not available. This skill creates a Release module that handles database creation, migration, and rollback via bin/app_name eval commands.
Workflow
-
Detect app name and repos
- Check
mix.exsfor app name - Check
config/config.exsorconfig/runtime.exsfor Ecto repos
- Check
-
Create Release module
- Location:
lib/<app_name>/release.ex - Must handle multiple repos if present
- Location:
-
Verify config
- Ensure
config/runtime.exshas production database config - Check for
DATABASE_URLor explicit config
- Ensure
Implementation
Release Module Template
defmodule <AppName>.Release do
@moduledoc """
Release tasks for database management.
Usage in production:
bin/<app_name> eval "<AppName>.Release.migrate()"
bin/<app_name> eval "<AppName>.Release.rollback(<AppName>.Repo, 20240101000000)"
"""
@app :<app_name>
def migrate do
load_app()
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
end
def rollback(repo, version) do
load_app()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
def create do
load_app()
for repo <- repos() do
case repo.__adapter__().storage_up(repo.config()) do
:ok -> IO.puts("Database created for #{inspect(repo)}")
{:error, :already_up} -> IO.puts("Database already exists for #{inspect(repo)}")
{:error, term} -> raise "Failed to create database: #{inspect(term)}"
end
end
end
def seed do
load_app()
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, fn _repo ->
seed_file = Application.app_dir(@app, "priv/repo/seeds.exs")
if File.exists?(seed_file) do
Code.eval_file(seed_file)
end
end)
end
end
defp repos do
Application.fetch_env!(@app, :ecto_repos)
end
defp load_app do
Application.ensure_all_started(:ssl)
Application.load(@app)
end
end
For Phoenix Projects with Multiple Repos
If multiple repos exist (e.g., Repo and ReadRepo), ensure config.exs has:
config :<app_name>, ecto_repos: [<AppName>.Repo, <AppName>.ReadRepo]
Verification Steps
After creating the module:
- Compile:
mix compile - Test locally:
mix run -e "<AppName>.Release.migrate()" - Build release:
MIX_ENV=prod mix release - Test release:
_build/prod/rel/<app_name>/bin/<app_name> eval "<AppName>.Release.migrate()"
Usage Documentation
Add to project README or deployment docs:
# Create database (first deploy only)
bin/<app_name> eval "<AppName>.Release.migrate()"
# Run migrations
bin/<app_name> eval "<AppName>.Release.migrate()"
# Rollback to specific version
bin/<app_name> eval "<AppName>.Release.rollback(<AppName>.Repo, 20240101000000)"
# Seed database
bin/<app_name> eval "<AppName>.Release.seed()"
Common Issues
- SSL not started: Ensure
Application.ensure_all_started(:ssl)is called before repo operations - App not loaded: Always call
Application.load(@app)first - Missing ecto_repos config: Verify
config :app_name, ecto_repos: [...]exists
More from gsmlg-dev/code-agent
elixir-architect
Use when designing or architecting Elixir/Phoenix applications, creating comprehensive project documentation, planning OTP supervision trees, defining domain models with Ash Framework, structuring multi-app projects with path-based dependencies, or preparing handoff documentation for Director/Implementor AI collaboration
17flutter-reducing-app-size
Measures and optimizes the size of Flutter application bundles for deployment. Use when minimizing download size or meeting app store package constraints.
17flutter-animating-apps
Implements animated effects, transitions, and motion in a Flutter app. Use when adding visual feedback, shared element transitions, or physics-based animations.
17flutter-handling-concurrency
Executes long-running tasks in background isolates to keep the UI responsive. Use when performing heavy computations or parsing large datasets.
16flutter-caching-data
Implements caching strategies for Flutter apps to improve performance and offline support. Use when retaining app data locally to reduce network requests or speed up startup.
16flutter-embedding-native-views
Embeds native Android, iOS, or macOS views into a Flutter app. Use when integrating complex native components like maps or web views.
16