Continuous Deployment, Integration, Testing & Delivery for Drupal is Hard
Well before “DevOps” was a thing, and long before DevShop existed, was “CI”. Continuous Integration is a critical part of successful software development. As a web CMS, Drupal has lagged a bit behind in joining up with this world of CI.
One of the reasons that we don’t see CI being used as much as we’d like is that it is hard to setup, and even harder to maintain long term. Wiring up your version control systems to your servers and running tests on a continual basis takes some serious knowledge and experience. There are a lot of tools to try and make it easier, like Jenkins, but there is still a lot of setup and jerry-rigging needed to make everything flow smoothly from git push to test runs to QA analysis and acceptance.
Setup is one thing, keeping things running smoothly is another entirely. With a home-spun continuous integration system, the system operators are usually the only ones who know how it works. This can become a real challenge as people move to new jobs or have other responsibilities.
This is one of the reasons why we created DevShop: to make it ridiculously easy to setup and keep up a CI environment. DevShop’s mission is to have everything you need out of the box, with as little setup, or at least as simple a setup process as possible.
DevShop has always had Continuous Deployment: When a developer pushes code to the version control repository, it is deployed to any environment configured to follow that branch. This is usually done on the main development branch, typically called master, and the environment is typically been called dev.
However for the last few years, DevShop has had the ability to host unlimited “branch environments”. This means that individual developers can work on their code on separate branches, and each one can get it’s own copy of the site up and running on that branch. This reduces the chances for conflicts between multiple developers and helps reduce the time needed to debug problems in the code because if you find a problem, you know what branch it came from.
We’ve found that having branch environments is a much more productive way to code than a shared dev environment on the master branch.
Pull Request Environments
DevShop has been able to react to GitHub Pull Requests by creating a new environment since last year. Each project can be configured to either clone an environment or run a fresh install every time a Pull Request is created. It will even tear down the environment when the Pull Request is closed.
Developers have less management to do using Pull Request environments: They don’t need access to DevShop at all. Everything is fully automated.
This method is even better than setting up branch environments, since Pull Requests are more than just code: anyone on the team can comment on every Pull Request, offering advice or asking questions about the proposed code. Users can even comment on individual lines of code, making the peer review process smoother than ever by letting teams communicate directly on the code..
Recently we’ve added built-in behat testing to DevShop: When a “Test” task is triggered, the logs are saved to the server and displayed to users through the web interface in real time. The pass or fail result is then displayed in the environment user interface as green or red, respectively, along with the full test results with each step highlighted with Pass, Fail, or Skipped.
This gives developers instant feedback on the state of their code, and, because it is running in an online environment, others can review the site and the test results along with them.
The future of DevShop testing is to incorporate even more tests, like PHPUnit, CodeSniffer, and PHP Mess Detectors. Having a common interface for all of these tests will help teams detect problems early and efficiently.
Continuous Integration can mean different things to different people. In this context I am referring to the full integration of version control, environments, tests, and notifications to users. By tying all of these things together, you can close the feedback look and accelerate software development dramatically.
GitHub, the most popular git host in the world, got to be that way in part by providing an extremely robust API that can be used to setup continuous integration systems. Each repository can have “Post commit receive” webhooks setup that will notify various systems that new code is available.
The “Deployments” API” allows your systems to notify github (and other systems) that code was deployed to certain environments. The “Commit Status” API can be used to flag individual commits with a Pass, Fail, or Pending status. This shows up in the web interface as a a green check, a red X, or an orange circle both on the commit and on each open Pull Request in the repository. A failing commit will notify developers that they should “Merge with Caution”, making it much less likely that code reviewers will merge bad code.
DevShop now leverages both the Deployments and the Commit status APIs for Pull Request environments.
Deployments are listed right in line with the commit logs of a pull request, and give the team direct links to the environments created by devshop.
Commit Statuses display not only a pass or fail status, but also link directly to test results, giving developers the instant feedback needed to respond quickly to issues.
An important part of any CI system is the notifications. Without them, developers and their teams don’t know that there is anything for them to do. GitHub has great integration with just about any chat service, and now so does DevShop.
When your CI system is integrated with a chat service, the entire team gets visibility into the progress and status of the project. New commits pushed notify others that there is new work to pull, and test notifications alert everyone to the passing or failing of those code pushes. Having immediate feedback on these types of things in crucial for maintaining a speedy development pace.
With all of the pieces in place, you can start to think about Continuous Delivery. Continuous Delivery is the act of “going live” with your code on a continuous basis, or at least very often.
DevShop allows your live environment to track a branch or a tag. If tracking a tag, you must manually go in and deploy a new tag when you are ready to release your code.
If tracking a branch, however, your code will deploy as soon as it is pushed to that branch. Deploy hooks ensure all of the appropriate things run after the code drop, such as update.php and cache clearing. This is what makes continuous delivery possible.
If using Pull Requests for development, you can use GitHub’s Merge button to deploy to live if you setup your production environment to track your main branch. With the Commit Status and Deployment APIs, you can be sure that not only did the tests pass but the site looks good with the new code.
Merging to deploy to live is a great way to work. You no longer need to access devshop to deploy a new tagged release, and you no longer need to manually merge code, hoping that everything works.
If it’s green, it’s working. If your tests are robust enough, you can guarantee that the new code works.
If your tests are so complete that you start to reach 100% code coverage, you can start thinking about true continuous delivery: Tests Pass? Automatically merge to live and deploy. This requires that your tests are amazing and reliable, but it is possible.
All wrapped up in a Bow
With DevShop, you will spend (much) less time on your support systems so you can focus on your websites. We hope to continue to find ways to improve the development process and incorporate them directly into the platform.
We encourage everyone to embrace continuous integration principles on their projects, whether it is using DevShop or not. Not only does efficiency go up, but code quality and morale does too.
If you are a software developer, having tests in place will change your life. Everyone involved in the project, from clients to quality assurance folks to the dev team, will sleep better at night.
Originally published at thinkdrop.net.