|
1 | 1 | Kaliop eZ-Migration Bundle |
2 | 2 | ========================== |
3 | 3 |
|
4 | | -This bundle makes it easy to programmatically deploy changes to eZPlatform / eZPublish 5 database structure and contents. |
5 | | - |
6 | | -It is inspired by the [DoctrineMigrationsBundle](http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html) |
7 | | - |
8 | | -You can think of it as the grandson of the legacy [ezxmlinstaller](https://github.com/ezsystems/ezxmlinstaller) extension. |
9 | | - |
10 | | - |
11 | | -## Requirements |
12 | | - |
13 | | -* PHP 5.6 or later. |
14 | | - |
15 | | -* eZPublish Enterprise 5.4 or Community 2014.11 or later. |
16 | | - |
17 | | - |
18 | | -## Installation |
19 | | - |
20 | | -In either `require` or `require-dev` at the end of the bundle list in the composer.json file add: |
21 | | - |
22 | | - "kaliop/ezmigrationbundle": "^3.0" |
23 | | - |
24 | | -Save it and run |
25 | | - |
26 | | - composer update --dev kaliop/ezmigrationbundle |
27 | | - |
28 | | -This will install the bundle and all its dependencies. |
29 | | - |
30 | | -Please make sure that you have the bundle registered in the kernel as well. Check `ezpublish/EzPublishKernel.php` |
31 | | - |
32 | | -The `registerBundles` method should look similar to: |
33 | | - |
34 | | - public function registerBundles() |
35 | | - { |
36 | | - $bundles = array( |
37 | | - ... more stuff here ... |
38 | | - new \Kaliop\eZMigrationBundle\EzMigrationBundle() |
39 | | - ); |
40 | | - } |
41 | | - |
42 | | -### Checking that the bundle is installed correctly |
43 | | - |
44 | | -If you run `php ezpublish/console` you should see the following new commands in the list: |
45 | | - |
46 | | - kaliop |
47 | | - kaliop:migration:generate |
48 | | - kaliop:migration:status |
49 | | - kaliop:migration:migrate |
50 | | - kaliop:migration:migration |
51 | | - |
52 | | -This indicates that the bundle has been installed and registered correctly. |
53 | | - |
54 | | -Note: the command `kaliop:migration:update` is kept around for compatibility, and will be removed in future versions. |
55 | | - |
56 | | -### Updating the bundle |
57 | | - |
58 | | -To get the latest version, you can update the bundle to the latest available version by using `composer` |
59 | | - |
60 | | - composer update kaliop/ezmigrationbundle |
61 | | - |
62 | | -### Upgrading from version 2.x to version 3 |
63 | | - |
64 | | -* Make sure you read carefully all the BC notes in the [release notes](WHATSNEW.md) |
65 | | - |
66 | | -* Nothing else is required, unless you have one of the following: |
67 | | - |
68 | | - - migrations definitions generated using extension versions 1.x or 2.x, yet to be applied |
69 | | - - code which extends the migration bundle code/apis |
70 | | - |
71 | | - For both cases, the fix is to apply manual changes to your code/migrations. |
72 | | - |
73 | | -### Upgrading from version 1.x to version 2 |
74 | | - |
75 | | -Please read the [dedicated documentation page](Resources/doc/Upgrading/1.x_to_2.0.md) |
76 | | - |
77 | | - |
78 | | -## Getting started |
79 | | - |
80 | | -All commands accept the standard Symfony/eZPublish 5 options, although some of them might not have any effect on the |
81 | | -command's execution. |
82 | | - |
83 | | -### Generating a new, empty migration definition file |
84 | | - |
85 | | -The bundle provides a command to easily generate a new blank migration definition file, stored in a specific bundle. |
86 | | - |
87 | | -For example: |
88 | | - |
89 | | - php ezpublish/console kaliop:migration:generate --format=yml MyProjectBundle |
90 | | - |
91 | | -The above command will place a new yml skeleton file in the `MigrationVersions` directory of the MyProjectBundle bundle. |
92 | | - |
93 | | -If the directory does not exists then the command will create it for you, as long as the bundle does exist and is registered. |
94 | | -If the command is successful it will create a new yml file named with the following pattern: `YYYYMMDDHHMMSS_placeholder.yml`. |
95 | | -You are encouraged to rename the file and change the `placeholder` part to something more meaningful, but please keep |
96 | | -the timestamp part and underscore, as well as the extension. |
97 | | - |
98 | | -_(the contents of the skeleton Yaml file are stored as twig template)_ |
99 | | - |
100 | | -### Listing all migrations and their status |
101 | | - |
102 | | -To see all the migrations definitions available in the system and whether they have been applied or not simply run the |
103 | | -status command in your eZPublish 5 root directory: |
104 | | - |
105 | | - php ezpublish/console kaliop:migration:status |
106 | | - |
107 | | -The list of migrations which have been already applied is stored in the database, in a table named `kaliop_migrations`. |
108 | | -The bundle will automatically create the table if needed. |
109 | | -In case you need to use a different name for that table, you can change the Symfony parameter `ez_migration_bundle.table_name`. |
110 | | - |
111 | | -### Applying migrations |
112 | | - |
113 | | -To apply all available migrations run the migrate command in your eZPublish 5 root directory: |
114 | | - |
115 | | - php ezpublish/console kaliop:migration:migrate |
116 | | - |
117 | | -NB: if you just executed the above command and got an error message because the migration definition file that you had |
118 | | -just generated is invalid, do not worry - that is by design. Head on to the next paragraph... |
119 | | - |
120 | | -#### Applying a single migration file |
121 | | - |
122 | | -To apply a single migration run the migrate command passing it the path to its definition, as follows: |
123 | | - |
124 | | - php ezpublish/console kaliop:migration:migrate --path=src/MyNamespace/MyBundle/MigrationsVersions/20160803193400_a_migration.yml |
125 | | - |
126 | | -### Editing migration files |
127 | | - |
128 | | -So far so good, but what kind of actions can be actually done using a migration? |
129 | | - |
130 | | -Each migration definition consists of a series of steps, where each step defines an action. |
131 | | - |
132 | | -A simple example of a migration to create a 'folder' content is: |
133 | | - |
134 | | - - |
135 | | - mode: create |
136 | | - type: content |
137 | | - content_type: folder |
138 | | - parent_location: 2 |
139 | | - attributes: |
140 | | - name: hello world |
141 | | - |
142 | | -In a Yaml migration, you can define the following types of actions: |
143 | | -- creation, update and deletion of Contents |
144 | | -- creation, update and deletion of Locations |
145 | | -- creation, update and deletion of Users |
146 | | -- creation, update and deletion of UserGroups |
147 | | -- creation, update and deletion of Roles |
148 | | -- creation, update and deletion of ContentTypes |
149 | | -- creation and deletion of ContentTypeGroups |
150 | | -- creation, update and deletion of ObjectStates |
151 | | -- creation, update and deletion of ObjectStateGroups |
152 | | -- creation, update and deletion of Sections |
153 | | -- creation and deletion of Languages |
154 | | -- creation and deletion of of Tags (from the Netgen Tags Bundle) |
155 | | - |
156 | | -The docs describing all supported parameters are in the [DSL Language description](Resources/doc/DSL/README.md) |
157 | | - |
158 | | -### Custom migrations |
159 | | - |
160 | | -For more specific needs, you can also use 2 other types of migrations: |
161 | | -- SQL migrations |
162 | | -- PHP migrations |
163 | | - |
164 | | -#### SQL migrations |
165 | | - |
166 | | -Example command to generate an SQL migration definition: |
167 | | - |
168 | | - php ezpublish/console kaliop:migration:generate MyBundle create-new-table --format=sql |
169 | | - |
170 | | -This will create the following file, which you are free to edit: |
171 | | - |
172 | | - .../MyBundle/Migrations/2016XXYYHHMMSS_mysql_create-new-table.sql |
173 | | - |
174 | | -*NB* if you rename the sql file, keep in mind that the type of database to which it is supposed to apply is the part |
175 | | -of the filename between the first and second underscore characters. |
176 | | -If you later try to execute that migration on an eZPublish installation running on, say, PostgreSQL, the migration |
177 | | -will fail. You are of course free to create a specific SQL migration for a different database type. |
178 | | - |
179 | | -The Migration bundle itself imposes no limitations on the type of databases supported, but as it is based on the |
180 | | -Doctrine DBAL, it will only work on the databases that Doctrine supports. |
181 | | - |
182 | | -#### PHP migrations |
183 | | - |
184 | | -If the type of manipulation that you need to do is too complex for either YML or SQL, you can use a php class as |
185 | | -migration definition. To generate a PHP migration definition, execute: |
186 | | - |
187 | | - php ezpublish/console kaliop:migration:generate MyBundle AMigrationClass --format=php |
188 | | - |
189 | | -This will create the following file, which you are free to edit: |
190 | | - |
191 | | - .../MyBundle/Migrations/2016XXYYHHMMSS_AMigrationClass.php |
192 | | - |
193 | | -As you can see in the generated definition, the php class to be used for a migration needs to implement a specific |
194 | | -interface. The Symfony DIC container is passed to the migration class so that it can access from it all the services, |
195 | | -parameters and other thing that it needs. |
196 | | - |
197 | | -For a more detailed example of a migration definition done in PHP, look in the MigrationVersions folder of this very bundle. |
198 | | - |
199 | | -*NB* if you rename the php file, keep in mind that the filename and the name of the class it contains are tied - the |
200 | | -standard autoloading mechanism of the application does not apply when loading the migration definition. This is also |
201 | | -the reason why the php classes used as migrations should not use namespaces. |
202 | | - |
203 | | -### Re-executing failed migrations |
204 | | - |
205 | | -The easiest way to re-execute a migration in 'failed' status, is to remove it from the migrations table: |
206 | | - |
207 | | - php ezpublish/console kaliop:migration:migration migration_name --delete |
208 | | - |
209 | | -After removing the information about the migration form the migrations table, running the `migrate` command will execute it again. |
210 | | - |
211 | | - |
212 | | -## Usage of transactions / rolling back changes |
213 | | - |
214 | | -By default the bundle runs each migration in a database transaction. |
215 | | -This means that if a step fails, all of the previous steps get rolled back, and the database is left in its original state. |
216 | | -This is a safety feature built in by design; |
217 | | -* if you prefer the migration steps to be executed in separate transactions the easiest way is to create a separate |
218 | | - migration file for each step |
219 | | -* you can use the command-line flag `-u` to disable usage of transactions by the migrate command |
220 | | - |
221 | | -Note also that by default the `migrate` command stops on the 1st failed migration, but it can be executed with a flag |
222 | | -to allow it to continue and execute all available migrations even in case of failures. |
223 | | - |
224 | | -As for rolling back changes: given the nature of the eZPublish API, rolling back changes to Content is not an easy feat. |
225 | | -As such, the bundle does not provide built-in support for rolling back the database to the version it had before |
226 | | -applying a given migration. We recommend always taking a database snapshot before applying migrations, and use it in |
227 | | -case you need to roll back your changes. Another approach consists in writing a separate migration to undo the changes. |
228 | | - |
229 | | - |
230 | | -## Customizing the migration logic via Event Listeners |
231 | | - |
232 | | -An easy way to hook up custom logic to the execution of migrations - without having to implement your own customized |
233 | | -action executors - is to use Event Listeners. |
234 | | - |
235 | | -Two events are fired *for each step* during execution of migrations: |
236 | | - |
237 | | - * ez_migration.before_execution => listeners receive a BeforeStepExecutionEvent event instance |
238 | | - * ez_migration.step_executed => listeners receive a StepExecutedEvent event instance |
239 | | - |
240 | | -An event is fired only in case a migration fails because a step throws a specific migration abort exception: |
241 | | - |
242 | | - * ez_migration.migration_aborted => listeners receive a MigrationAbortedEvent event instance |
243 | | - |
244 | | -In order to act on those events, you will need to declare tagged services, such as for ex: |
245 | | - |
246 | | - my.step_executed_listener: |
247 | | - class: my\helper\StepExecutedListener |
248 | | - tags: |
249 | | - - { name: kernel.event_listener, event: ez_migration.step_executed, method: onStepExecuted } |
250 | | - |
251 | | -and the corresponding php class: |
252 | | - |
253 | | - use Kaliop\eZMigrationBundle\API\Event\StepExecutedEvent; |
254 | | - |
255 | | - class StepExecutedListener |
256 | | - { |
257 | | - public function onStepExecuted(StepExecutedEvent $event) |
258 | | - { |
259 | | - // do something... |
260 | | - } |
261 | | - } |
262 | | - |
263 | | - |
264 | | -## Known Issues and limitations |
265 | | - |
266 | | -* unlike the Doctrine Migrations Bundle, this bundle does not support rollback of changes. Read above for the reason. |
267 | | - |
268 | | -* if you get fatal errors when running a migration stating that a node or object has not been found, it is most likely |
269 | | - related to how the dual-kernel works in eZPublish, and the fact that the legacy and Symfony kernels use a separate |
270 | | - connection to the database. Since the migration bundle by default wraps all database changes for a migration in a |
271 | | - database transaction, when the Slots are fired which allow the legacy kernel to clear its caches, the legacy kernel |
272 | | - can not see the database changes applied by the Symfony kernel, and, depending on the specific Slot in use, might |
273 | | - fail with a fatal error. |
274 | | - The simplest workaround is to disable usage of transactions by passing the `-u` flag to the `migrate` command. |
275 | | - |
276 | | -* if you get fatal errors without any error message when running a migration which involves a lot of content changes, |
277 | | - such as f.e. altering a contentType with many contents, it might be that you are running out of memory for your |
278 | | - php process. |
279 | | - Known workarounds involve: |
280 | | - - increase the maximum amount of memory allowed for the php script by running it with option '-d memory_limit=-1' |
281 | | - - execute the migration command using a Symfony environment which has reduced logging and kernel debug disabled: |
282 | | - the default configuration for the `dev` environment is known to leak memory |
283 | | - |
284 | | -* if you get fatal errors with he message 'You cannot create a service ("request") of an inactive scope ("request")', |
285 | | - take a look at the following issue for a possible explanation and ideas for workarounds: |
286 | | - https://jira.ez.no/browse/EZP-24691 |
287 | | - |
288 | | -* if you are using eZPublish versions prior to 2015.9, you will not be able to create/update Role definitions that |
289 | | - contain policies with limitations for custom modules/functions. The known workaround is to take over the |
290 | | - RoleService and alter its constructor to inject into it the desired limitations |
291 | | - |
292 | | -* when updating a Role, you have to specify in the migration *all* the policies for it. Any existing policies that are not |
293 | | - in the yml file will be removed. |
294 | | - To make it easy to create a migration for updating a role, please use the `migration:generate` command using the `--type=role` flag |
295 | | - |
296 | | -* take care when creating content types: the eZPublish API, used internally by the migration bundle, will let you use dash |
297 | | - characters in the content type identifiers, even if the resulting content types will then be unusable, eg. |
298 | | - |
299 | | - Example of an invalid definition: |
300 | | - |
301 | | - type: ezstring |
302 | | - name: Topbar-hover-color |
303 | | - identifier: topbar-hover-color |
304 | | - |
305 | | - |
306 | | -## Frequently asked questions |
307 | | - |
308 | | -### How can I update a specific content which has a different Id on dev, test and prod environments? |
309 | | - |
310 | | -A: use the 'reference/set' migration step to define a reference for the desired content Id, and use a Symfony parameter |
311 | | -to store a different value for each Symfony environment. For example: |
312 | | - |
313 | | - - |
314 | | - type: reference |
315 | | - mode: set |
316 | | - identifier: content_id_ref |
317 | | - value: '%a.parameter.name%' |
318 | | - |
319 | | - - |
320 | | - type: content |
321 | | - mode: update |
322 | | - match: |
323 | | - content_id: "reference:content_id_ref" |
324 | | - etc: ... |
325 | | - |
326 | | - |
327 | | -## Extending the bundle |
328 | | - |
329 | | -### Supporting custom migrations |
330 | | - |
331 | | -The bundle has been designed to be easily extended in many ways, such as: |
332 | | -* adding support for custom/complex field-types |
333 | | -* adding support for completely new actions in the Yml definitions |
334 | | -* adding support for a new file format for storing migration definitions |
335 | | -* adding support for a new resolver for the custom references in the migration definitions |
336 | | -* taking over the way that the migrations definitions are loaded from the filesystem or stored in the database |
337 | | -* etc... |
338 | | - |
339 | | -Following Symfony best practices, for the first 4 options in the list above all you need to do is to create a service |
340 | | -and give it an appropriate tag (the class implementing service should of course implement an appropriate interface). |
341 | | - |
342 | | -To find out the names of the tags that you need to implement, as well as for all the other services which you can |
343 | | -override, take a look at the [services.yml file](Resources/config/services.yml). |
344 | | - |
345 | | -### Running tests |
346 | | - |
347 | | -The bundle uses PHPUnit to run functional tests. |
348 | | - |
349 | | -#### Running tests in a working eZPublish installation |
350 | | - |
351 | | -To run the tests: |
352 | | - |
353 | | - export KERNEL_DIR=ezpublish (or 'app' for ezplatform setups) |
354 | | - export SYMFONY_ENV=behat (or whatever your environment is) |
355 | | - |
356 | | - bin/phpunit -c vendor/kaliop/ezmigrationbundle/phpunit.xml |
357 | | - |
358 | | -*NB* the tests do *not* mock interaction with the database, but create/modify/delete many types of data in it. |
359 | | -As such, there are good chances that running tests will leave stale/broken data. |
360 | | -It is recommended to run the tests suite using a dedicated eZPublish installation or at least dedicated database. |
361 | | - |
362 | | -#### Setting up a dedicated test environment for the bundle |
363 | | - |
364 | | -A safer choice to run the tests of the bundle is to set up a dedicated environment, as done when the test suite is run on |
365 | | -Travis. |
366 | | -The advantages are multiple: one one hand you can start with any version of eZPublish you want; on the other you will |
367 | | -be more confident that the tests wll still pass on Travis. |
368 | | -The disadvantages are that you will need to spend some time setting up the test environment, and that the environment |
369 | | -you will use will look quite unlike a standard eZPublish setup! |
370 | | - |
371 | | -Steps to set up a dedicated test environment: |
372 | | - |
373 | | -(to be documented...) |
374 | | - |
375 | | - |
376 | | -[](https://packagist.org/packages/kaliop/ezmigrationbundle) |
377 | | -[](https://packagist.org/packages/kaliop/ezmigrationbundle) |
378 | | -[](https://packagist.org/packages/kaliop/ezmigrationbundle) |
379 | | - |
380 | | -[](https://travis-ci.org/kaliop-uk/ezmigrationbundle) |
381 | | -[](https://scrutinizer-ci.com/g/kaliop-uk/ezmigrationbundle/?branch=master) |
382 | | -[](https://scrutinizer-ci.com/g/kaliop-uk/ezmigrationbundle/?branch=master) |
383 | | -[](https://insight.sensiolabs.com/projects/7f16a049-a738-44ae-b947-f39401aec2d5) |
| 4 | +Fork von [kaliop-uk/ezmigrationbundle](https://github.com/kaliop-uk/ezmigrationbundle) |
| 5 | + |
| 6 | +### Zusätzliche Änderungen |
| 7 | + |
| 8 | +| Tag | Änderungen | |
| 9 | +| --- | --- | |
| 10 | +| 4.2.4 | [4.2.0](https://github.com/kaliop-uk/ezmigrationbundle/commit/dde077877bd231cf94df7162e06ac80d8c338af5) + [PR-127](https://github.com/kaliop-uk/ezmigrationbundle/pull/127) + [PR-136](https://github.com/kaliop-uk/ezmigrationbundle/pull/136) + [PR-137](https://github.com/kaliop-uk/ezmigrationbundle/pull/137) | |
| 11 | +| 4.2.3 | [4.2.0](https://github.com/kaliop-uk/ezmigrationbundle/commit/dde077877bd231cf94df7162e06ac80d8c338af5) + [PR-127](https://github.com/kaliop-uk/ezmigrationbundle/pull/127) + [PR-136](https://github.com/kaliop-uk/ezmigrationbundle/pull/136) + [PR-137](https://github.com/kaliop-uk/ezmigrationbundle/pull/137) | |
| 12 | +| 4.2.2 | [4.2.0](https://github.com/kaliop-uk/ezmigrationbundle/commit/dde077877bd231cf94df7162e06ac80d8c338af5) + [PR-127](https://github.com/kaliop-uk/ezmigrationbundle/pull/127) + [PR-136](https://github.com/kaliop-uk/ezmigrationbundle/pull/136) + [PR-137](https://github.com/kaliop-uk/ezmigrationbundle/pull/137) | |
| 13 | +| 4.2.1 | [4.2.0](https://github.com/kaliop-uk/ezmigrationbundle/commit/dde077877bd231cf94df7162e06ac80d8c338af5) + [PR-127](https://github.com/kaliop-uk/ezmigrationbundle/pull/127) + [PR-136](https://github.com/kaliop-uk/ezmigrationbundle/pull/136) | |
| 14 | +| 4.1.1 | [4.1.0](https://github.com/kaliop-uk/ezmigrationbundle/commit/59c96b406741af2303265bf0127326d8f8458c77) + [PR-127](https://github.com/kaliop-uk/ezmigrationbundle/pull/127) | |
| 15 | +| 4.0.2 | [dev-master](https://github.com/kaliop-uk/ezmigrationbundle/commit/b101c451d6d540bb8d747345e33d5060faaabc4d) + [PR-125](https://github.com/kaliop-uk/ezmigrationbundle/pull/125) + [PR-126](https://github.com/kaliop-uk/ezmigrationbundle/pull/126) + [PR-127](https://github.com/kaliop-uk/ezmigrationbundle/pull/127) | |
0 commit comments