Ruby Unconf 2018

Updating Depencencies Sucks, So Let's Do That More Often

Ruby Unconf 2018

00:00:15.389 Hey everyone, my name is Florian Munz, I'm a developer. I'm working with this to occur depth alongside Young, who was opening up the conference. I want to talk a little bit about the ideas behind continuously updating dependencies and why we think doing this automatically and all the time is a much better approach than waiting indefinitely and then doing it all at once.
00:00:21.029 As a developer, one thing that I really enjoy doing is building tools, whether for our team or for the customer success team. It's gratifying to make small improvements to processes. Here, we can build small CI tools or larger web tools that genuinely help people. I want to emphasize the importance of updating dependencies and how we can apply that approach across projects.
00:00:41.850 Let's start with a quick show of hands: who is updating dependencies at all? Alright, great! And who is doing that on a regular basis? Good, about two-thirds. Now, who is using any kind of tool for that, potentially something self-written? Awesome! So, why do we even bother updating dependencies? You could just leave them as they are and forget about it. I think if you were to ask that question, many people would wonder why. The topic of security always comes up as the most obvious reason. Security is a major concern because vulnerabilities often reside within the dependencies. How do you find out about these vulnerabilities, and how easy is it to deploy fixes? That’s really the goal of updating dependencies - to minimize the time it takes to roll out security patches.
00:01:13.080 With everything happening on the internet nowadays, you're in a race against automated scripts that look for vulnerabilities and exploit them. No one cares about an obscure application unless it has a significant vulnerability. So, we need to minimize the time it takes to address these issues. Another reason to update dependencies is that as time passes, the requirements become more complex. I’m sure many of you have had to take over an old Rails app, where no one has looked at it for a long time. If you try to run `bundle update` or update a single gem, you may find you can't do it because it depends on outdated libraries. Often, you're stuck with the interlocks of many dependencies and have to update everything at once, which can be quite daunting.
00:02:20.780 There are more reasons for regularly updating dependencies. One concept that I really like is codebase hygiene. When you have an actively maintained project, it feels good to have everything up-to-date. It demonstrates that your team cares about the code and the application. You also gain access to new libraries and performance improvements as updates often include bug fixes and new features. Of course, there's always the risk of regressions where performance might worsen, but we should always strive for improvement.
00:03:35.569 So what are the challenges regarding updating dependencies? The first issue I've encountered is simply inertia. It’s so easy to neglect updates when there are deadlines for features and other important tasks. Updating dependencies can take a back seat to immediate project needs. Another challenge is identifying who handles the updates. In many cases, there’s one person responsible, often updating on a Friday afternoon when there isn’t much else to do. This task isn’t typically treated as part of our development processes and rarely gets formal recognition. Updating dependencies is not a scrum task or a readily delegated resource.
00:04:45.880 Conceptually, it would be nice to update dependencies one by one, running tests after each change. This way, you can see what breaks or fails. However, with larger applications, tests can take a while to run, often ranging from ten minutes to half an hour. When you push an update, you have to wait for feedback, which can disrupt your workflow. You might forget about it entirely, which is not an ideal scenario.
00:05:55.399 Another surprisingly difficult task can be figuring out what changed in a new version when updating a gem. You have to identify the gem, navigate to its GitHub repo, and look for a changelog or release notes, which can sometimes be absent. In many cases, you must go through commits yourself to assess whether anything risks impacting your application. As a result, updating dependencies often feels tedious and thankless, without visible achievements to celebrate at the end of the year. It’s crucial to automate this process and perform these updates continuously in the background, balancing oversight without excessive ceremony.
00:07:02.160 Let me discuss some tools we might find helpful. There are open-source resources available for JavaScript and other ecosystems, but I want to highlight what our team is working on. The first step we take is generating pull requests. Rather than notifying you of new versions via email or showing them on a dashboard, we integrate updates directly into your workflow by presenting them as pull requests within your repository. This approach allows for informed decision-making as everything needed is consolidated within the pull request. It also triggers endpoints to run tests, giving you an understanding of how easy it is to apply each update.
00:08:27.180 This methodology allows us to minimize downtime while keeping our dependencies up-to-date. We believe that a small amount of pain in regular doses is preferable to a major overhaul after an extended period. Performing updates little by little is less burdensome than trying to handle all changes at once after six months. This strategy translates into less material to consider when deploying updates, adapting gradually to smaller changes in the codebase.
00:09:41.150 Additionally, we employ a system that sends pull requests focusing on only a limited number to manage their influx. You won't receive an overwhelming amount; instead, we try to maintain a manageable number, say seven pull requests at a time. This way, it becomes less daunting, and merging can happen more fluidly. The pull requests detail the current version you’re using, what the new version is, and provide links to read the release notes or changelogs. This transparency enables you to conduct lightweight code reviews while updating dependencies seamlessly.
00:10:56.370 For security updates, we highlight these pull requests distinctly, encouraging immediate attention. Notably, there’s a critical distinction between security updates and standard updates, as neglecting certain dependencies can lead to conflicts due to interdependencies. The goal is to keep your repository state current, enabling smooth transaction of updates and security patches.
00:12:27.920 Naturally, many may question the efficacy of using partial updates and whether they impede collaborative processes. As I noted, we impose a limit on concurrent pull requests to maintain a manageable workflow. It’s vital to examine the actual application of these pull requests as every merge builds on existing work. Observations reveal how often dependencies need updates based on their current repository state and that staying updated is certainly easier than initiating a whole new project of upgrades.
00:13:43.460 Currently, users often report surprises regarding the testing expectations once they aggregate dependency updates. Although many gems facilitate minor changes, larger gems can incur significant workload during necessary updates. Ultimately, real effort is needed to evaluate risks and changes to ensure that the application operates smoothly after installing the latest updates.
00:15:00.830 Moreover, many developers are cautious when considering how often they should perform updates. This uncertainty can lead to hesitance in incorporating updates into their existing workflows. For many routine minor version updates, developers may overlook the nuances or decide not to prioritize updates until absolutely necessary. As I would argue, this mentality can trap the application in a perpetual state of neglect.
00:16:29.490 To address this, it would be beneficial to evaluate our update strategies and identify the risk levels associated with each. Developers often seek to minimize risks; thus being prepared for major upgrades or significant patches can lead to a more stabilized production environment. This emphasis on maintaining better awareness in code dependency management can indeed simplify the integration of changes substantially.
00:17:40.550 To clarify, the approach to continuous updating isn't just a trend; it represents a shift in how we manage dependencies and can support long-term project health. The system we’re developing aims to streamline this updating process and incorporate lessons learned from our experiences. We invite feedback and ideas for improvement as we grow this tool, which is open-source for public and personal repositories. Through this initiative, we hope to facilitate knowledge around dependency management in the Ruby community.
00:19:17.580 We have been fortunate to work with various teams and companies who provide input that ultimately contributed to refining our process and utility. We emphasize that if teams aren’t feeling compelled to manage dependencies effectively, this initiative won't resonate with them. Ultimately, collaboration across your team is needed to promote healthy practices within development cycles. I encourage everyone to give this a try! It's easy to experiment with and requires very minimal setup. The future of Ruby projects can truly benefit from a smoother workflow surrounding dependency updates.
00:21:03.000 Thank you so much for your time and attention!