Automated Testing

Summarized using AI

Continuous Deployment with Rails

Sebastian von Conrad • February 19, 2014 • Earth

In the video titled 'Continuous Deployment with Rails', presented at RubyConf AU 2014, speakers Keith Pitt and Mario Viik discuss the principles and practices surrounding continuous deployment in Rails applications. The talk emphasizes the importance of automating deployment processes and encourages development teams to integrate a more streamlined and frequent deployment strategy into their workflows. Key points include:

  • Definition of Continuous Deployment: Continuous deployment automates the release of code changes to production, contrasting with continuous delivery which involves manual deployment steps.
  • Advantages of Continuous Deployment: The speakers highlight three major advantages: fast feedback on code changes, increased confidence in the deployment processes, and enhanced predictability.
  • Ingredients for Successful Deployment: The key elements required to implement continuous deployment effectively include feature planning, efficient code review processes, and the critical need for automated testing.
  • Feature Toggles: Utilizing feature toggles allows developers to control which features are visible to users, enabling safe deployment without immediate exposure of new features.
  • Zero Downtime Deployments: Strategies to implement zero downtime during deployments are discussed, including the importance of careful database migrations to avoid disruptions to user experience.
  • Handling Errors Post-Deployment: The speakers advise a proactive approach when deployment issues arise, advocating for feature toggles to disable problematic features instead of immediately rolling back changes.
  • Monitoring and Metrics: They stress the need for effective monitoring tools to track performance and bugs after deployment to quickly address potential problems.

Throughout their presentation, Pitt and Viik also share practical examples from their own projects, such as utilizing CI scripts for deployment and managing deployments on services like Heroku. They conclude with a strong encouragement to adopt continuous deployment practices to significantly enhance development processes and adapt quickly to user feedback.

Continuous Deployment with Rails
Sebastian von Conrad • February 19, 2014 • Earth

RubyConf AU 2014: http://www.rubyconf.org.au

Recently it has become common practise for development teams to deploy their code several times a day, as well as encouraging new developers to deploy on their first day at work.
In our talk, we will discuss how we use continuous deployment to push these practises to the extreme. Automatically deploying the master branch on new changes is an awesome way to improve your development process.
Automatically deploying master will fundamentally change how you work. Gone are the days of the epic pull request. You'll quickly find yourself writing smaller more manageable chunks of code, that overall have a great impact on the quality of the software you produce.
By the end of the talk you'll know how to change the GitHub merge pull request button into a deploy button - and have the confidence to do so.
Some things we'll go over in the talk:
How to setup your CI environment for deployments Why having fast tests are important How to use your Staging environment for testing deployments How to use feature flags to hide deployed features from some users Zero downtime deploys, even when there are database migrations Your new deploy button, AKA The GitHub merge pull request button What to do when deployment goes wrong

RubyConf AU 2014

00:00:06.600 Hello everyone, my name is Keith. This is Mario Viik, and today we're going to talk to you about continuous deployment with Rails. The original talk title was 'Keith and Mario's Guide to Continuous Deployment with Rails', but they shortened it to just 'Continuous Deployment'. So, we retaliated by making it longer. Continuous deployment, or why automatically deploying your master branch to production is a good idea. That's the name of our title.
00:00:17.720 You may remember us from such presentations as 'Keith and Mario's Guide to Fast Websites' that we did last year and the highly informative lightning talk that Mario gave. Also, this is Mario Viik, the modern man with a modern haircut. He works at a company you may have heard of called Invado. He lives in Melbourne, and there's a picture of a laneway in Melbourne. There are nerds there, and... wait for it... hipsters!
00:00:37.079 Thank you very much! Melbourne has great coffee, which is fantastic, especially compared to what we'll find out soon. Little fun fact, Mario has aspirations to become a do-jillionaire. I'm not sure if you've Photoshopped that, but it's quite a challenge! So let's get started. Thanks, Keith, for that excellent segue. This is my good friend Keith Pitt. For some reason, in every single photo we found of him, he is holding a different Apple product. I think this one is a MacBook. The other one is an iPad.
00:01:12.000 Keith works for a mob called Pin Payments, whose role is to make payments in Australia easier and better. They do that from their headquarters in Western Australia, which is beautiful. It's actually where I'm originally from. Western Australia has this lovely place called Little Creatures, located in Fremantle. It's one of my favorite places, and it's where Keith discovered his love for beer. Fun fact: everyone knows Dary Lok, who did a talk before we visited Little Creatures. He ordered a pizza there, specifically the sea salt pizza, which sounded good, but it was just a pizza base with a little salt on top.
00:01:44.960 For everyone from Western Australia or those who may have heard about it, the region is renowned for its mining and fly-in, fly-out workers who often wear high visibility vests. You can see our Prime Minister here sporting one. It's a known fact that you could commit any crime in a high visibility vest and get away with it! It makes it an authoritative type of uniform. Unfortunately, we're also known for our flavored milk, which is full of sugar—one of these has more sugar than a can of Coke. But it's delicious! Speaking of non-paleo foods, we also have excellent-tasting coffee.
00:02:13.320 Another fun fact: as Josh mentioned earlier, Keith won an award in 2007 for his impressive skills in archery. He was the South Australian archery champion of the year in 2007. Keith and I have worked on a couple of websites together where we developed some of the continuous deployment techniques we'll discuss today. One of them is Microlancer, which is made by the nice folks at Invado, to help freelancers sell their digital services online, and they do that quite well.
00:02:35.760 Additionally, Keith and I built a wallpaper sharing website that uses Dropbox as its backend. It's very user-friendly. Keith also now works on a semi-hosted CI service called Buildbox. Think of it as an alternative to Jenkins or TeamCity, providing ease of use without hosting challenges. Before we delve deeper, we'd like to conduct a quick quiz. Can anyone in the audience who has an application in production and writes tests for it please raise your hands?
00:03:05.500 Okay, we see a good majority. Now, can you keep those hands raised? If you do not have a CI or a dedicated test server that picks up your builds, please put your hands down. Great, most of you still have your hands up. Now, keep your hands up if, once the build is green, a production deploy occurs. Awesome! Everyone with their hands up, you've graduated from this session. And there's nothing of value here! Although John is giving an excellent talk upstairs—I think that's the best one at the moment.
00:03:47.719 Let’s begin with some terminology. There are two key terms we should define: continuous delivery and continuous deployment. I recently had a conversation with a gentleman in the hall and I seem to mix these terms up. The difference between the two is that continuous delivery encompasses the entire process where you have a CI server that picks up your build, integrates it continuously, and then provides you with a status. At that point, you can optionally deploy to production, which is the final manual step.
00:04:06.000 In contrast, continuous deployment automates that step. When we talk about continuous deployment, we're discussing the latter. Now, why would you want to engage in continuous deployment? There are three major aspects to consider: the first is fast feedback. We don't really know what will increase conversions on a website, even with our theories. So, getting small changes out to production and monitoring their impact is essential, and we believe continuous deployment enhances that opportunity.
00:04:45.120 The second aspect is confidence. Human deployers, in my experience, can be error-prone, especially when nervous about releasing changes. Continuous deployment provides a structured pipeline that gives you more confidence in your deployment process. Lastly, predictability is vital. You want a deployment process that you can anticipate will happen consistently.
00:05:11.600 Now, let's take a look at these three aspects as we visualize them in a Venn diagram. While I'm not sure if this is the correct use of a Venn diagram, I just put some overlapping circles. I had to think of a way to make the slide work, so I added the center to create a diagram. Anyway, moving on. Thanks, Keith.
00:05:50.960 As the famous saying goes, you can't do continuous deployment without breaking a few eggs. Now, let’s look at the ingredients necessary for continuous deployment. These are the components you need to implement it, but don’t be scared; we’ll go through each one step by step and discuss them. The first ingredient is feature planning. Ask yourself: what is the smallest thing you can ship today? If you're tasked to create a large feature, the key is to break it down into manageable portions—one small part today, another tomorrow, and then deploy, deploy, deploy! Eventually, you can piece together the whole thing.
00:06:36.020 With feature planning, we also need to consider how to deploy features without downtime. If you're introducing Redis into your stack or any new technology, it's essential to ask how you can incorporate it into the application without disrupting service for users. The last part of feature planning involves handling database migrations effectively. If you've ever dealt with zero downtime before, you know that database migrations can be a make-or-break moment.
00:07:20.520 Now, let's discuss Code Reviews. This is Bill Gates thoughtfully looking at paper—a serious business topic. GitHub pull requests have transformed the QA process. When I write a feature in a feature branch, I push it to GitHub. Mario then undertakes the review process, typically giving a thumbs up. The pull request merges into the master branch, which triggers deployment to production. It’s critical for us to get feedback before features are released into production.
00:07:54.480 Each commit in the master branch goes to production shortly after merging, which emphasizes the importance of performing sanity checks. It's vital to ensure there are no security vulnerabilities or performance issues before deploying. The way I write code has changed dramatically with this awareness. Knowing that my work will be in production shortly makes me more cautious and deliberate. We have several tools to assist with QA, such as Cane by Square, which performs code base analysis, checking for long method lines or code complexity, and highlighting areas that need refactoring.
00:08:40.520 Another helpful tool is RuboCop, which enforces Ruby standard style guidelines. It checks aspects like the appropriate hash syntax and many others to maintain code quality. Additionally, let's consider feature toggles, which are crucial to our process. Essentially, feature toggles allow you to wrap a condition around a flow or feature and then turn it on or off without redeploying. It's a straightforward application of conditional logic.
00:09:15.640 When implementing feature toggles, it’s beneficial to keep them simple. For example, if there’s a new user flow that includes a button, just hide the button until the feature is ready for use. Often, we conceal the user interface elements while allowing developers to access features without extensive testing. Using gems like Rollout for simple toggling or Flip for more functionality allows teams to manage features in a structured way.
00:09:57.920 When executing automated deployments, it's equally crucial to implement automated tests. It's best to write just enough tests to trust your code without steering off course. Your tests become a part of the deployment pipeline; if they take too long, it slows the deployment process. Thus, ensuring your tests run swiftly is paramount. Streamlining testing often means focusing on unit tests while limiting comprehensive integration tests.
00:10:27.560 As part of your testing strategy, include smoke tests, which verify essential functions post-deployment. A smoke test simply confirms if the homepage displays the product name or essential elements correctly—things that provide sanity checks post-release. You can also reuse existing integration tests for your staging server, testing for functionality and potential data changes.
00:11:04.680 Zero downtime deployments are critical as they prevent disruption to end users during frequent deployments. A zero downtime deployment ensures users do not encounter maintenance pages. Heroku presents some challenges in achieving this, as traditionally, applications take time to boot post-deployment. However, features like Heroku's preboot allow new applications to spin up without affecting current users. This way, the old version can continue to run while the new one initializes.
00:11:38.520 If you're not using Heroku, it’s beneficial to explore various web server documentation for strategies focused on achieving zero downtime deployments—it's a term you'll frequently come across in these discussions. One critical issue with deployments is handling migrations correctly. Migrations can pose complications, especially if they involve removing columns from ActiveRecord models.
00:12:04.840 A common migration strategy is to mark the application in maintenance mode while updates are made. This approach, however, contradicts our zero downtime principles. Therefore, we need to ensure the application runs smoothly throughout. Rails manages model columns upon booting, keeping active columns in memory, which can lead to complexities if columns are removed during runtime. This requires special handling in migrations to ensure seamless operation.
00:12:46.440 One strategy is to implement a maintenance mode during deployments that involve migrations. This is simple: detect migration cases, turn on maintenance mode, and execute the migration. However, if a migration doesn't affect existing data or schema, you can potentially automate the process without interruptions. The alternative approach is more complex, wherein your application needs to accommodate schema changes in real-time. Outstanding resources are available, such as articles explaining how to navigate zero-downtime migration challenges.
00:13:39.760 Another difficulty involves database locks during long migrations—queries that lock tables or rows can severely hinder workflow in a production environment. The goal is to minimize downtime and disruptions. There are projects like the Large Hyron Migrator to help you manage these scenarios effectively if you are working with MySQL. This is a tool we have utilized in one of our projects at Invado.
00:14:05.679 Let’s shift focus back to what happens after we deploy. When a deployment goes wrong, the best approach is to move forward rather than revert entirely. Continuous deployment doesn’t emphasize rollback as the first response. Instead, we look for options to mitigate the issue at hand. One strategy is to immediately turn off any problematic feature using feature toggles. This way, we can quietly address the issue without users ever being aware of the problem.
00:14:30.600 If using feature toggles isn't feasible, you can still revert the changes directly through Git, which is a smart approach. Just change the last commit in master, and the adjustments or issues will be resolved automatically, moving through the deployment pipeline seamlessly. This practice helps ensure that changes are small enough to mitigate risks while also focusing the attention on the last deployed feature if something does go wrong.
00:15:15.400 On the off chance we run into a critical problem that interrupts the user experience, we can always have a maintenance page ready to go. This option is akin to pulling the plug on something that has gone awry. In cases where we’ve pushed a total failure into production, this might be necessary. Although it might not be the best outcome, it’s an option in the toolbox to minimize user impact while correcting errors.
00:15:45.799 The monitoring aspect is crucial for continuous deployment. You want to establish bug tracking to catch any issues that may arise. One tool we’ve used before is BugSnag, which allows you to track bugs efficiently across different projects. Performance monitoring should also be included in your strategy. New Relic has become a go-to for performance tracking, enabling you to stay aware of how your application is performing.
00:16:29.200 You might want to consider tracking business-level metrics, such as user sign-ups or registrations. David Goodlad has an excellent talk about business metric monitoring that you can find with a quick Google search. All these strategies are useful, but they should integrate well with systems to give you feedback when things go wrong, which is why we recommend tools like PagerDuty. It provides notifications right when issues arise, allowing you to respond quickly.
00:17:12.239 So now that we've covered the necessary ingredients for effective deployment, let’s explore how we can apply them in a practical scenario. It's time to build out a script for deployment on our CI server. Initially, the script may look simple—once our code reaches the master branch, it will kick off a deployment process using Heroku!
00:17:37.400 The script starts with a few flags for efficiency, aiming to report everything happening during the process while halting at any point of failure. This approach is great for beginners; however, for established products, we require confidence in the deployment pipeline. So we need to integrate checks into our deployment script.
00:18:01.960 This involves static analysis through tools from the C gem, which will stop the build if code quality checks flag any failures, such as overly long methods or high complexity. If everything checks out, we proceed through our automated tests and, upon their successful completion, deploy to production. However, post-production deployment checks are equally critical, like running smoke tests to confirm that the homepage displays correctly after updates.
00:18:42.720 Eventually, we reach a stage where we question our confidence in the migration process. In instances where migrations could potentially fail, it’s helpful to utilize staging environments for sanity checks prior to general deployment. Staging not only allows us to run smoke tests but also helps showcase any problematic migrations ahead of time, minimizing any downtime in production.
00:19:33.120 Incorporating a realistic subset of production data in your staging environment means those migrations are tested against the same data structure, which is crucial for identifying potential issues. This strategy reinforces the confidence in our deployments, ensuring a smooth rollout and allowing us to address errors without affecting the end-users.
00:20:14.840 To conclude our session, let's recap the methodologies we discussed during this talk as they relate to deployment effectiveness. We want to ensure we're incorporating a robust strategy into our workflows that helps frame decision-making processes.
00:20:38.160 For our implementation on DeskTopper, the wallpaper sharing site, we aim to integrate social media buttons based on prior research which proves beneficial regarding user engagement. I commenced coding on the feature and have a promising functionality for sharing links among social media, including Pinterest and LinkedIn. Once I finished, I initiated a pull request, prompting Mario to review.
00:21:23.040 Upon reviewing my work, Mario expressed enthusiasm about the feature’s capabilities, which inspired me to merge the pull request into master. Consequently, our CI script ran, executing the necessary quality checks and tests, then proceeded with staging deployment. Once confirmed operational, deployment to production commenced.
00:22:06.400 With the feature now in production, we utilize feature toggles to initially turn it on for specific users, allowing us to gather feedback before a full-scale rollout. At each phase, these changes inform how we can further refine the feature based on user interaction.
00:22:44.879 In conclusion, we aim for continuous improvement, leveraging data to enhance user experiences. Recapping our session, we established a strong structure for deployments, emphasizing speed, reliability, and feedback—crucial components for any successful continuous deployment process.
00:23:28.080 We'll now open the floor for questions. Remember, we are happy to clarify anything about implementations discussed today or various deployment strategies that suit your projects. So, feel free to approach us.
00:24:01.040 As a reminder, it's crucial to maintain an effective, cohesive workflow to adopt continuous deployment smoothly. As we look into minimizing disruptions and improving error management, the strategies we shared hopefully inspire you to elevate your deployment practices.
00:24:34.920 Overall, as someone who has seen the transformations brought about by continuous deployment, I encourage you to embrace this shift. We are quite eager to hear your thoughts on adopting continuous deployment and how it can potentially optimize your workflow.
00:25:00.000 Thank you very much for your time and engagement. We hope you enjoyed the session!
Explore all talks recorded at RubyConf AU 2014
+17