|
| 1 | +# Integration and Deployment |
| 2 | + |
| 3 | +This guide covers test integration, plugin usage, programmatic execution, and |
| 4 | +deployment-related operational concerns. |
| 5 | + |
| 6 | +## Using Migrations for Tests |
| 7 | + |
| 8 | +If you are using migrations for your application schema, you can also use those |
| 9 | +same migrations to build schema in your tests. In your application's |
| 10 | +`tests/bootstrap.php` file you can use the `Migrator` class to build schema |
| 11 | +when tests are run. The `Migrator` will use existing schema if it is current, |
| 12 | +and if the migration history in the database differs from what is in the |
| 13 | +filesystem, all tables will be dropped and migrations will be rerun from the |
| 14 | +beginning: |
| 15 | + |
| 16 | +```php |
| 17 | +// in tests/bootstrap.php |
| 18 | +use Migrations\TestSuite\Migrator; |
| 19 | + |
| 20 | +$migrator = new Migrator(); |
| 21 | + |
| 22 | +// Simple setup with no plugins |
| 23 | +$migrator->run(); |
| 24 | + |
| 25 | +// Run a non-test database |
| 26 | +$migrator->run(['connection' => 'test_other']); |
| 27 | + |
| 28 | +// Run migrations for plugins |
| 29 | +$migrator->run(['plugin' => 'Contacts']); |
| 30 | + |
| 31 | +// Run the Documents migrations on the test_docs connection |
| 32 | +$migrator->run(['plugin' => 'Documents', 'connection' => 'test_docs']); |
| 33 | +``` |
| 34 | + |
| 35 | +If you need to run multiple sets of migrations, use `runMany()`: |
| 36 | + |
| 37 | +```php |
| 38 | +$migrator->runMany([ |
| 39 | + ['plugin' => 'Contacts'], |
| 40 | + ['plugin' => 'Documents', 'connection' => 'test_docs'], |
| 41 | +]); |
| 42 | +``` |
| 43 | + |
| 44 | +If your database also contains tables that are not managed by your application, |
| 45 | +such as those created by PostGIS, you can exclude those tables from drop and |
| 46 | +truncate behavior using the `skip` option: |
| 47 | + |
| 48 | +```php |
| 49 | +$migrator->run(['connection' => 'test', 'skip' => ['postgis*']]); |
| 50 | +``` |
| 51 | + |
| 52 | +The `skip` option accepts an `fnmatch()` compatible pattern. |
| 53 | + |
| 54 | +## Using Migrations in Plugins |
| 55 | + |
| 56 | +Plugins can also provide migration files. All commands in the Migrations plugin |
| 57 | +support the `--plugin` or `-p` option to scope execution to the migrations |
| 58 | +relative to that plugin: |
| 59 | + |
| 60 | +```bash |
| 61 | +bin/cake migrations status -p PluginName |
| 62 | +bin/cake migrations migrate -p PluginName |
| 63 | +``` |
| 64 | + |
| 65 | +## Running Migrations in a Non-shell Environment |
| 66 | + |
| 67 | +While typical usage of migrations is from the command line, you can also run |
| 68 | +migrations from a non-shell environment by using the `Migrations\Migrations` |
| 69 | +class. This can be handy when you are developing a plugin installer for a CMS, |
| 70 | +for instance. |
| 71 | + |
| 72 | +The `Migrations` class allows you to run the following commands: |
| 73 | + |
| 74 | +- `migrate` |
| 75 | +- `rollback` |
| 76 | +- `markMigrated` |
| 77 | +- `status` |
| 78 | +- `seed` |
| 79 | + |
| 80 | +Each of these commands has a corresponding method defined in the |
| 81 | +`Migrations\Migrations` class. |
| 82 | + |
| 83 | +```php |
| 84 | +use Migrations\Migrations; |
| 85 | + |
| 86 | +$migrations = new Migrations(); |
| 87 | + |
| 88 | +$status = $migrations->status(); |
| 89 | +$migrate = $migrations->migrate(); |
| 90 | +$rollback = $migrations->rollback(); |
| 91 | +$markMigrated = $migrations->markMigrated(20150804222900); |
| 92 | +$seeded = $migrations->seed(); |
| 93 | +``` |
| 94 | + |
| 95 | +The methods can accept an array of parameters that match the shell command |
| 96 | +options: |
| 97 | + |
| 98 | +```php |
| 99 | +use Migrations\Migrations; |
| 100 | + |
| 101 | +$migrations = new Migrations(); |
| 102 | +$status = $migrations->status([ |
| 103 | + 'connection' => 'custom', |
| 104 | + 'source' => 'MyMigrationsFolder', |
| 105 | +]); |
| 106 | +``` |
| 107 | + |
| 108 | +The only exception is `markMigrated()`, which expects the version number as the |
| 109 | +first argument and the options array as the second. |
| 110 | + |
| 111 | +Optionally, you can pass default parameters in the constructor: |
| 112 | + |
| 113 | +```php |
| 114 | +use Migrations\Migrations; |
| 115 | + |
| 116 | +$migrations = new Migrations([ |
| 117 | + 'connection' => 'custom', |
| 118 | + 'source' => 'MyMigrationsFolder', |
| 119 | +]); |
| 120 | + |
| 121 | +$status = $migrations->status(); |
| 122 | +$migrate = $migrations->migrate(); |
| 123 | +``` |
| 124 | + |
| 125 | +If you need to override one or more default parameters for one call, pass them |
| 126 | +to the method: |
| 127 | + |
| 128 | +```php |
| 129 | +use Migrations\Migrations; |
| 130 | + |
| 131 | +$migrations = new Migrations([ |
| 132 | + 'connection' => 'custom', |
| 133 | + 'source' => 'MyMigrationsFolder', |
| 134 | +]); |
| 135 | + |
| 136 | +$status = $migrations->status(); |
| 137 | +$migrate = $migrations->migrate(['connection' => 'default']); |
| 138 | +``` |
| 139 | + |
| 140 | +## Feature Flags |
| 141 | + |
| 142 | +Migrations offers a few feature flags for compatibility. These features are |
| 143 | +disabled by default but can be enabled if required: |
| 144 | + |
| 145 | +- `unsigned_primary_keys`: Should Migrations create primary keys as unsigned |
| 146 | + integers? Default: `false` |
| 147 | +- `unsigned_ints`: Should Migrations create all integer columns as unsigned? |
| 148 | + Default: `false` |
| 149 | +- `column_null_default`: Should Migrations create columns as nullable by |
| 150 | + default? Default: `false` |
| 151 | +- `add_timestamps_use_datetime`: Should Migrations use `DATETIME` type columns |
| 152 | + for the columns added by `addTimestamps()`? |
| 153 | + |
| 154 | +Set them via `Configure`, for example in `config/app.php`: |
| 155 | + |
| 156 | +```text |
| 157 | +'Migrations' => [ |
| 158 | + 'unsigned_primary_keys' => true, |
| 159 | + 'unsigned_ints' => true, |
| 160 | + 'column_null_default' => true, |
| 161 | +], |
| 162 | +``` |
| 163 | + |
| 164 | +> [!NOTE] |
| 165 | +> The `unsigned_primary_keys` and `unsigned_ints` options only affect MySQL |
| 166 | +> databases. When generating migrations with `bake migration_snapshot` or |
| 167 | +> `bake migration_diff`, the `signed` attribute will only be included in the |
| 168 | +> output for unsigned columns as `'signed' => false`. |
| 169 | +
|
| 170 | +## Skipping the `schema.lock` File Generation |
| 171 | + |
| 172 | +In order for the diff feature to work, a `.lock` file is generated every time |
| 173 | +you migrate, roll back, or bake a snapshot, to keep track of the state of your |
| 174 | +database schema at any given point in time. You can skip this file generation, |
| 175 | +for instance when deploying to production, by using the `--no-lock` option: |
| 176 | + |
| 177 | +```bash |
| 178 | +bin/cake migrations migrate --no-lock |
| 179 | +bin/cake migrations rollback --no-lock |
| 180 | +bin/cake bake migration_snapshot MyMigration --no-lock |
| 181 | +``` |
| 182 | + |
| 183 | +## Deployment |
| 184 | + |
| 185 | +You should update your deployment scripts to run migrations when new code is |
| 186 | +deployed. Ideally, run migrations after the code is on your servers, but before |
| 187 | +the application code becomes active. |
| 188 | + |
| 189 | +After running migrations, remember to clear the ORM cache so it renews the |
| 190 | +column metadata of your tables. Otherwise, you might end up with errors about |
| 191 | +columns not existing when performing operations on those new columns. The |
| 192 | +CakePHP core includes a [Schema Cache Shell](https://book.cakephp.org/5/en/console-and-shells/schema-cache.html) that you can use: |
| 193 | + |
| 194 | +```bash |
| 195 | +bin/cake migration migrate |
| 196 | +bin/cake schema_cache clear |
| 197 | +``` |
| 198 | + |
| 199 | +## Alert of Missing Migrations |
| 200 | + |
| 201 | +You can use the `Migrations.PendingMigrations` middleware in local development |
| 202 | +to alert developers about new migrations that have not been applied: |
| 203 | + |
| 204 | +```php |
| 205 | +use Migrations\Middleware\PendingMigrationsMiddleware; |
| 206 | + |
| 207 | +$config = [ |
| 208 | + 'plugins' => [ |
| 209 | + // Optionally include a list of plugins with migrations to check. |
| 210 | + ], |
| 211 | +]; |
| 212 | + |
| 213 | +$middlewareQueue |
| 214 | + // ErrorHandler middleware |
| 215 | + ->add(new PendingMigrationsMiddleware($config)); |
| 216 | +``` |
| 217 | + |
| 218 | +You can add the `'app'` config key set to `false` if you are only interested in |
| 219 | +checking plugin migrations. |
| 220 | + |
| 221 | +You can temporarily disable the migration check by adding |
| 222 | +`skip-migration-check=1` to the URL query string. |
| 223 | + |
| 224 | +## IDE Autocomplete Support |
| 225 | + |
| 226 | +The [IdeHelper plugin](https://github.com/dereuromark/cakephp-ide-helper) can |
| 227 | +help you get more IDE support for tables, their column names, and possible |
| 228 | +column types. Specifically, PHPStorm understands the meta information and can |
| 229 | +help you autocomplete those. |
0 commit comments