When we were considering switching to the Pantheon hosting platform, one of the features that made us confident in our decision is what they call Multidev. In order to understand why Multidev is so important for us, and Pantheon's other customers, it's important to understand the best practices that go into developing and hosting a website.
In the earliest days of the web, a site consisted of a bunch of HTML files sitting on a server. Even today it's still possible to ssh into a machine, edit files by hand, and have those changes (or typos) immediately served by a web server. It didn't take too long, or too many typos, for people to set up a second site (or web server) to use for testing and proofreading changes before public consumption.
Now (hopefully) every developer knows they should at least have one testing environment alongside their live site where they can work and test new code. Even for small teams there are often more than just two sites. A configuration of a development site, a test site, and the live site is quite common (and just happens to be Pantheon's default configuration). While managing multiple environments can add a bit of overhead they come in quite handy when you need a pristine site to demo new functionality but you don't want to block your development team from continuing to work.
Let's say you're interested in trying out a new version of PHP, or you are thinking about swapping out a new theme, or adding a new major piece of functionality that isn't quite ready for prime time yet. Wouldn't it be nice if you could spin up a new environment for each of these changes in parallel? If that was possible you'd have an actual interactive website to share with stakeholders and test against before affecting the rest of the development team. Thankfully, that's exactly the problem the Pantheon workflow and Multidev helps us solve.
Drupal deployment best practices and pain points
Drupal deployment has traditionally been somewhat difficult. This is especially true of older versions of Drupal (prior to Drupal 8). Since Drupal can store configuration in the database alongside the code powering the site, figuring out how to capture all of that configuration in code (and hence version control) was not always an easy task. Tools like update hooks, CTools exportables, and the Features module have all evolved to help us solve this problem. By establishing a policy that keeps as much configuration in code as possible, we can confidently say that code must be deployed through the Dev -> Test -> Live environments and can only be promoted in one direction. Meanwhile, the data and content that makes up our site flows in the opposite direction. As needed, the database can be copied from the Live -> Test -> Dev environments at any time. Thankfully the Pantheon dashboard makes this process incredibly easy. It can even be scripted using an automation tool like Jenkins and Pantheon's command line tool Terminus.
If you're new to administering Drupal sites, or this kind of deployment infrastructure, I'd recommend you check out a few resources before continuing on.
- Using git for version control (Drupalize.Me)
- Drupal deployment with Features module (Drupalize.Me)
- The Features module - an overview (Lullabot.com)
Now that we've got a few deployment and infrastructure best practices established, let's get back to understanding what Multidev offers and why it's a game changer.
Multiwhat?
At its core, Multidev is just a method of spinning up complete environments for code that hasn't yet been merged into the main development branch. The main benefit to this is that it makes it incredibly easy to build a complete website environment that parallels your live site where any team member can functionally and visually test changes before they're fully merged. From a practical standpoint this means that doing functional testing while reviewing a pull request (especially for simple fixes like typos) can be done without disrupting a developer's local environment. Multidev can quickly spin up new environments based on git branches, allowing developers to share their progress with the team and get feedback without disrupting the main shared Development or Testing environment.
As a part of Lullabot I'd been using something similar for quite a while, which we then brought over to Drupalize.Me after I joined the team. About 3 years ago James Sansbury wrote the original version of something we called the Pull Request Builder. Other Lullabots became excited about the project and we eventually renamed it to Tugboat. Since then Tugboat.qa has evolved quite a bit, but at its heart are the same principles as Pantheon's Multidev. An added bonus with Multidev is that it's integrated with, and configured identically to, the infrastructure that hosts our live website.
The Pantheon workflow and Multidev
Now that we're running on Pantheon here is a sneak peek at what our development workflow and infrastructure looks like.
The code for our site is hosted in a private GitHub repository. When working on code we roughly follow the Git Flow model. When we start working on a particular issue we create a feature branch and push the work to GitHub. This then triggers a webhook which pushes the new branch to our Pantheon git repository. One thing to note is that Multidev environments created from git branches on Pantheon have certain restrictions on branch names. In particular,
>Multidev branch names must be all lowercase and less than 11 characters. Environments cannot be created with the following reserved names: master, settings, team, support, multidev, debug, files, tags, and billing.
This means we also need to run a bit of additional code, prior to synchronizing our GitHub and Pantheon repositories, to truncate branch names.
With our git branch pushed to our Pantheon repository we can create a new Multidev environment either via the dashboard or from the command line using terminus ( terminus multidev:create <site-name>.<environment> <new-environment-name>
).
It's also worth noting that you can create a new Multidev environment without an associated git branch. This can come in really handy for quick, disposable experimentation.
A newly created Multidev environment contains the new code from the related feature branch, along with the filesystem and database from the environment it was cloned from (Development by default in our case). Now we have a URL we can share with the rest of the team to see the new work in action. While we still do full code reviews on GitHub, for less technical tickets, e.g. typos or small CSS tweaks, this allows us to double check our work on an actual copy of our site. We've noticed how empowering this can be for less technical team members. With a small amount of training using GitHub's editing and pull request interfaces everyone on our team is able to submit pull requests and help with immediately testing their work. While we typically do our code review and perform merges via GitHub, Pantheon's dashboard also provides buttons for merging the commits from a Multidev environment. Once the code has been merged, we're off to choose another issue to work on.
It's hard to overstate the amount of time this workflow saves everyone on our development team. Peer review can be done faster, more easily, and with a lower barrier to entry. Local development environments don't need to be constantly reset when dealing with context switching between tasks. Being able to preview work on a fully functional site alongside a code review is incredibly valuable. Honestly, it's hard to imagine how teams large and small are able to work together efficiently without something like Pantheon's Multidev.
If you have any other workflow tips or tricks we'd love to hear from you! If you're interested in learning more about Multidev in particular try these resources:
- Using Pantheon Multidev (Drupalize.Me)
- Mutlidev cloud environments (Pantheon.io documentation)
Comments
This was very helpful (thanks!).
You mention you have some code that truncates your branch names so they work as legal multidev names on pantheon. Could you please share this code with me? I'm hoping to do the same, but I'm a bit lost.
Hi Anne,
In our case we use Jenkins to run these terminus commands and actually create the multidev environments for us. Jenkins provides a few different environment variables for each build, one of which is a unique BUILD_ID. We're just using the branch naming convention `ci-BUILD_ID` for our multidev branch ids. This allows us to trace a multidev environment back to the Jenkins build that created it (and then to the pull request).
Hope this helps clear things up.
Add new comment