# MojoX::Pg::Migrations::Env Mojo::Pg migrations that replace environment placeholders in their sql. A drop-in replacement for [Mojo::Pg::Migrations](https://metacpan.org/pod/Mojo::Pg::Migrations). It is a subclass that loads, selects and applies migrations exactly like its parent, with one difference: placeholders in the migration sql are replaced with values from the environment when the sql is produced. That lets migrations refer to things that differ between environments, for example the name of a role to grant to. The module is sponsored by [Fibia](https://fibia.dk). ```sql -- 3 up grant select on invoices to ${APP_READONLY_ROLE:-readonly}; -- 3 down revoke select on invoices from ${APP_READONLY_ROLE:-readonly}; ``` - `${NAME}` is replaced with the value of `NAME`, and fails when it is unset or empty. - `${NAME:-fallback}` uses the fallback instead. - `$${NAME}` is left as the literal `${NAME}`. Nothing else is touched, so `$1` and dollar quoted function bodies are safe, and migrations without placeholders produce the same sql as they do with `Mojo::Pg::Migrations`. ```perl use Mojo::Pg; use MojoX::Pg::Migrations::Env; my $pg = Mojo::Pg->new('postgresql://app@/app'); $pg->migrations(MojoX::Pg::Migrations::Env->new(pg => $pg, name => 'app')); $pg->migrations->from_file('db/migrations.sql')->migrate; ``` All sql between two versions is produced before any of it runs, so a missing variable aborts `migrate` with nothing applied. See the module documentation for `env`, `placeholders` and `resolve`, which tell what a migration needs and where each value comes from without running it. ## Development procedure - Create a branch - Add a change fragment for each change you make using `changie new` - Add your feature, and create a pull request - Have your feature reviewed by your peers - Merge to main ### Perl toolchain We use `ExtUtils::MakeMaker::CPANfile` to handle the installation of `MojoX::Pg::Migrations::Env`. `ExtUtils::MakeMaker` creates a Makefile that can build and install `MojoX::Pg::Migrations::Env` just like any other perl module on [CPAN](https://metacpan.org/). > [!TIP] > Run `mise run prepare` to build the code, create the `Makefile` > and update the `MANIFEST`. ### Tests `mise run test` runs the tests. The ones that migrate a database are skipped unless `TEST_ONLINE` holds a database url with a `search_path`, which `mise.toml` sets for a local PostgreSQL. The tests create and drop the schema named in `search_path`. ### External dependencies If you have any external dependencies, add them to the `cpanfile` and install them using `mise run install:dependencies` ## Release procedure - Check out `main` - Run `release:preview` to see a preview of the changelog, and what the next version will be. - Run `release:create` to create the actual release, this will do the following - Update the module version in `Env.pm` - Run `changie` to create the changelog - Tag the code with the new version number - If you are satisfied with the release, push `main` and the tag to GitHub together, where a workflow tests the code and uploads the distribution to [PAUSE](https://pause.perl.org/). The workflow needs the repository secrets `PAUSE_USER` and `PAUSE_PASSWORD`, and only releases tags that are on `main`. ```sh git push --atomic --follow-tags origin main ``` > [!NOTE] > If you want to override the next version, you can pass > `--next major` to `mise run release:create` like so: > > ```sh > mise run release:create --next major > ``` > > Any version identifier accepted by `changie next` can be used. > (`major`, `minor`, `patch` and `auto` which is default)