Question

We are using Magento setup scripts located in the sql and data directories to propagate data changes to all working copies and environments. This includes configuration settings, creation of new tables, attributes and so on.

[Update] Project-specific code goes into several Client_Module extensions.

Nonetheless often enough we need to add data migrations (i.e. setup scripts) which can't be attributed to an existing extension. Thus we use a Company_Client module (or Client_General, someting like that) for these changes.

Imagine multiple developers working on the same project at the same time. It may happen that developer A and developer B are both bumping the version number of Company_Client and create a new upgrade script. Even if you update your working copy frequently, you will get conflicts more often than you like, have to change the version of your local Company_Client extension and make sure that the scripts of your fellow colleagues run when you fetch their changes.

Three solutions from the top of my head:

  1. Create many extensions for project-specific parts (pollutes the code pools with many unnecessary extensions).
  2. Create one extension per developer for upgrade scripts (may work, but doesn't make sense).
  3. Bite the bullet and manually do that kind of conflict resultion I explained before.

How do you handle this?

Was it helpful?

Solution

I believe to have found a solution that fulfills my needs.

My prerequisites:

  • Use only one extension for all the small data / structure migrations that don't fit into any other extension
  • Enable multiple developers to create setup scripts without having conflicts because of the version numbers

The first part to my solution: use multiple setup script resources within one extension. This is easily possible (content of config.xml):

<?xml version="1.0"?>
<config>
    <!-- Your other config stuff... ->
    <global>
        <!-- Your other config stuff... ->
        <resources>
            <[your_setup_name_1]>
                <setup>
                    <module>[Your_Extension]</module>
                </setup>
            </[your_setup_name_1]>
            <[your_setup_name_2]>
                <setup>
                    <module>[Your_Extension]</module>
                </setup>
            </[your_setup_name_2]>
        </resources>
    </global>
</config>

The problem you will face is that all of your setup resources will have the same version number in the database table core_resource (which is the version number you specify in your modules node). You don't want that as it will create problems and conflicts for your developers again.

Enter part two of my solution: a custom resource setup class with a tiny change. By modifying one line in each of the methods applyDataUpdates() and applyUpdates() you can tell Magento to read the version number from another XML node.

Replace

$configVer = (string)$this->_moduleConfig->version;

with

$configVer = (string)$this->_resourceConfig->setup->version;

Now you can specify different version numbers for each of your setup resources:

<?xml version="1.0"?>
<config>
    <!-- Your other config stuff... ->
    <global>
        <!-- Your other config stuff... ->
        <resources>
            <[your_setup_name_1]>
                <setup>
                    <module>[Your_Extension]</module>
                    <class>Emzee_MultipleSetupVersions_Model_Resource_Setup</class>
                    <version>0.0.3</version>
                </setup>
            </[your_setup_name_1]>
            <[your_setup_name_2]>
                <setup>
                    <module>[Your_Extension]</module>
                    <class>Emzee_MultipleSetupVersions_Model_Resource_Setup</class>
                    <version>0.0.2</version>
                </setup>
            </[your_setup_name_2]>
        </resources>
    </global>
</config>

The setup scripts will be executed independently and the correspondent version number will be written to core_resource. Everything else should work as always.

Now you just have to decide on your strategy how to split up the resources (one setup resource per entity, per developer, ...).

You can have a look at a proof of concept extension on Github.

OTHER TIPS

From the above Company_Client naming convention it sounds like you only leave scope for 1 project specific module per client which is forcing multiple developers to work within the same module while likely developing completely different features.

Why not go with a Client_Module setup where Module describes the purpose of the module being created? This approach has worked fine for me in the past and also assures you are not developing a single, rather bloated module that does all kinds of different things.

Sometimes I understand you need to make minor changes which don't realistically warrant their own module and in this case I do tend to use one module with the same Module name across all clients, but Client obviously changing - I have settled on Client_Override for these kinds of changes.

You are always going to come across conflicting code from time to time, but enforcing a proper work flow, good module naming and intelligent use of branching in your repository keeps this to a minimum.

I'm developing an extension called "Mageploy" with the intent to solve the problem of maintaining different environments in sync:

https://github.com/pug-more/mageploy

It still has to be extended, well documented and fully tested even if I'm already using it in a couple of projects having some benefits.

It's open source and any help or suggestion wil be appreciated.

Regards

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top