Drupal 8 opens the door for clean, readable, version-controlled configuration in Drupal development. But how can we leverage this system effectively in development teams?
Configuration Management in Drupal 7, Our Process
Our collaborative Drupal 7 development process typically starts with a site built by a team, entirely defined in code. We don’t do databases until content comes into play, and even then we use code (hook_update_n()) to push any configuration changes up to a staging or production server. We achieve this in Drupal 7 by leveraging features, strong arm, and functional code to create hybrid feature modules that expose functionality and define the configuration surrounding that functionality in stand-alone, portable modules. In this way, we effectively manage everything outside of content in code (in new and in living, deployed websites). Napkin deployments are not done here. No one at NEWMEDIA sweats a deployment because the deployment has been defined in code, has been peer-reviewed, and has been tested in mirrors of the production environment to verify successful roll-out.
Our Current Pain-Points
hook_update_n() Numbering in Teams
Sometimes more than one developer working collaboratively in a team will need to inject hook_update_n() implementations into the same profile or module on a project at the same time – and without proper coordination and communication this can result in merge conflicts that involve duplicate hook_update_n() function names. When this happens it’s quite visible and fix is generally a simple function name change, but it does come up from time to time.
Features and Merge Conflicts
We find that the way in which the features module stores configuration makes it almost impossible to avoid semi-complex merge conflicts when two or more developers make changes to the same feature concurrently. These conflicts are absolutely resolvable and for the most part preventable by appropriately breaking site configuration down into multiple features and strategically focusing team members on separate areas of the site for each sprint.
Configuration Management in Drupal 8 Utilizing Core
The GUI / Drush Approach
At DrupalCon Austin 2014 mtift presented the following workflow in his talk Introducing the Drupal 8 Configuration System:
- Clone a website down to a development environment to work on it.
- Adjust the website’s configuration through the GUI.
- Export the entire site’s configuration to a compressed package of yaml files using the new Core configuration GUI or Drush.
- Log into the staging or production server and upload the yaml file package using the new GUI or Drush.
- Import the new configuration (again, GUI or Drush), wiping out the entirety of the old configuration with what is contained in the uploaded package.
While the process above does technically place configuration in code, this configuration is only temporarily placed into code while it moves from one environment to another. This code is handled like file content and is deleted once the import has finished.
Our Concerns With the GUI/Drush Workflow
Potential for Lost Configuration in Teams
In team development different parts of the site’s functionality and configuration are being worked on in parallel. What happens when, simultaneously, one developer creates the blog functionality while another developer creates the newsletter functionality of the same site? At the end of the day, they’d each have a combination of functionality-related commits on the project and a full-site YAML configuration package to upload. Because the YAML package each developer possesses would not contain the other developer’s work, the first developer to upload his/her YAML package would see his/her additions get wiped out once the second developer’s YAML package was imported.
Configuration Not Version-Controlled in Git
When a configuration change is made by a developer, we feel this should happen in a commit (in code). That way there’s a chance for peer review, testing, and discussion. An export of configuration to code for the sole purpose of transferring configuration, from one environment to another isn’t going to cut it. Configuration needs to be version-controlled just like the rest of the project. It’s a pretty central piece of the project, right? Once the entirety of a project, including its configuration, is version-controlled, the migration of configuration from one environment to another is effortless.
Our Team-Friendly Drupal 8 Configuration Management Strategy
At the core of this Configuration Management Initiative is an API we can use to bundle configuration with custom modules. This gives us a nice spot to place configuration in code. Given that, we can have our modules ship with appropriate yaml configuration for site-install situations and use hook_update_n() in combination with ConfigInstaller::installDefaultConfig() to enforce new and updated configurations in existing sites.
To make this workable for all team members and not just back-end developers, I could imagine the features module stepping into the space with a nice UI, auto-discovery of configuration trees and dependencies, and per-module default configuration status (overridden/default) with the ability to revert and regenerate configuration on the module-level. I’m also not sure a module would necessarily need to be a “features module” anymore to play ball if features went with the core Configuration API as its back-end. Features would just provide a new level of awareness and functionality with regard to a module’s code-defined configuration.
The CMI GUI-approach as it stands today appears to be a great option for solo developers but doesn’t appear to be the right solution for teams. The API, on the other hand, appears to offer the functionality we’re after in terms of holding configuration in code, but it won’t be an easy option for our non-backend developers. Once the API stabilizes I believe the contrib space (most likely the 8.x branch of the features module) will come in and fill in the gaps currently present in the GUI to make both GUI and pure-code routes viable options for team development.