avatarMirek Stanek

Summary

Azimo's web engineering team has successfully integrated Renovate to automate the update process for their numerous dependencies, ensuring their web applications remain stable, secure, and up-to-date.

Abstract

Azimo, a financial services company, has implemented the Renovate tool to streamline the management of its extensive list of external dependencies in its tech stack. This integration has been crucial in maintaining a high level of stability and security for their web applications, particularly their main page microservice, which utilizes over 90 dependencies. The company emphasizes the importance of keeping dependencies updated to minimize bugs, vulnerabilities, and breaking changes. Renovate facilitates this by automatically creating merge requests for dependency updates, complete with release notes and source code comparisons. Azimo's preparation for this automation included establishing high quality standards such as a crash-free ratio above 99.9%, comprehensive test coverage, and a robust CI/CD pipeline that includes lint checks, unit tests, visual regression tests, and deployments. The integration has allowed their small team to efficiently manage over 100 dependency updates in a single quarter, contributing to the overall reliability and modernity of their tech stack.

Opinions

  • The use of external dependencies is seen as a significant growth driver in technology, allowing companies to focus on their core competencies.
  • Keeping dependencies up to date is considered essential for maintaining software quality and security.
  • Renovate is praised for its convenience in managing dependency updates and its features like auto-merge and conflict rebasing.
  • The high crash-free ratio is valued not just for user experience but also for detecting anomalies and identifying issues introduced by dependency updates.
  • Process automation, including a comprehensive CI/CD pipeline, is viewed as critical for managing the volume of updates and ensuring that changes do not negatively impact the application.
  • Extensive testing coverage, including UI regression tests, is highlighted as a key factor in the successful adoption of Renovate, as it helps to quickly identify potential UI issues resulting from updates.
  • The company acknowledges the importance of the groundwork laid by their Web and DevOps engineering teams, particularly the contributions of Artur Kania and Bartek Grzybowski, in facilitating the successful integration of Renovate.
  • The integration of Renovate is part of Azimo's broader goal to improve financial services globally, and they invite others to join them in this mission through their careers page.
Photo by Mark de Jong on Unsplash

Automatic dependencies updates for frontend services

Our path to Renovate

Building software is like building LEGO bricks. Most tech solutions are the compositions of open source libraries, public APIs, or 3rd party libraries that we can plug directly into our code. This modularity is one of the biggest growth drivers in the world of technology. The company can focus on its core competencies while using external services created by experts in their domains. Azimo is no different here — in our tech stack, we use external SDKs (like Onfido to verify people’s identities), frameworks/runtimes — Node.js, Angular, React, or open-source libraries (like RxJS or RxSwift for reactive code). With all of these, we can focus entirely on building financial services that are fast, cheap, and available to all and don’t try to tackle problems already solved.

Having countless external dependencies is invaluable in terms of building your product. But it leads to new challenges. Being on top of all of the changes and bug fixes released under new versions is one of them.

Let’s look closer at one of our microservices responsible for serving our main page — azimo.com. It is an SSR (server-side rendering) web application, built on top of Node.js, containerized with Docker, and hosted on AWS infrastructure. But Node and Docker aren’t the only dependencies we use. This particular service uses 90+ dependencies (or more than 3000, when we include dependencies of these dependencies 🤯). Among them, there are big ones, like React, Redux, RxJS, Bootstrap. But we also use single-purpose projects like UUID or cookie-parser, tools like web-vitals, and our internal libraries.

Keep them all up to date

Keeping all of the things up to date is essential, period. The longer you wait with updates, the bigger is the list of changes. On the one hand, your app uncovers more bugs and vulnerabilities; on the other, there are more breaking changes in public interfaces to which you need to adapt your code.

To make this process more convenient, we integrated the repository with Renovate. This tool creates Merge Requests with dependencies updates — either a single library’s bump with breaking changes or a bundled update with minor versions. It has some neat features too, like rebasing when conflicts appear or doing auto-merge. Each Merge Request has release notes fetched from the updated dependency. You can also compare source code changes between your version and the newest one.

For more, check to Renovate documentation.

Example Merge Requests created by Renovate

Very cool automation, isn’t it? But this is not the end of the story. Integrations like Renovate or Dependabot require some preparation. Otherwise, you may end up with tens of open Merge Requests, production failures, and constant feeling that most dependencies are not up to date.

When we integrated Renovate with our main page microservice for the first time, we got 40+ MRs within one week (and another 20 in the following one). It wouldn’t be possible for a small team like ours to handle so many changes if we hadn’t prepared our project for that. Here are our quality standards which make the updating process seamless.

Quality standards

Crash free

Over the years, our web engineering team invested a lot of time to ensure our web app was stable. Nowadays, most of the time, we keep our crash-free ratio at >99.9% level. Stability metric is essential not only from the user experience perspective. Some of our crashes aren’t even visible in the customer’s journey. They just generate noise in crashlytics tools. But keeping its level as low as possible will make it possible to spot anomalies during the lifetime of our product. Thanks to that, it’s much easier to identify the root cause, such as a dependency update.

Crash-free metrics for our main page app

Process automation

Another thing is process automation. What Renovate does for us is create MRs with an updated package.json file. It’s not very sophisticated automation, is it? But more important things happen later. Our Merge Request pipelines have some of these steps:

  • Lint checks and unit tests
  • Test coverage report
  • Visual regression tests
  • Deployment

It means that Renoved doesn’t only update packages versions (you could do the same with npm commands) but also runs all of the checks against this update. With this information, it’s much easier to decide what can be merged instantly and which changes require more attention from our side.

Testing coverage

The part of process automation are tests. Over the years, we put a lot of effort into ensuring that tests cover a significant part of our codebase. The microservice responsible for our landing page is currently covered on >80% level. Moreover, 100% of our UI components are described in Storybook and covered with UI regression tests. Even the most minor changes in the user interface need to be reviewed and approved during the code review process. If any dependencies updates affect our UI, we will very likely see it in Merge Request reports.

Example report from our UI regression tests

Integration with Renovate is an important improvement to our product development process. It will help us to keep our tech stack up-to-date, free of bugs, and secure. We plan to adopt it across all of our microservices in the following months. But this integration wouldn’t be beneficial without some groundwork we did in last years — high crash-free with some monitoring around that or process automations, including multi-level testing.

Thanks to all of that, in the last quarter only, our relatively small web engineering team could merge more than 100 updates for dependencies, making our landing page even more stable, secure, and up to date.

Statistics from the Renovate adoption in main page microservice

Acknowledgments

Building this kind of integration wouldn’t be possible without the hard work of our Web and DevOps engineering teams. The biggest credits go to Artur Kania, Tech Lead for Web Engineering, and DevOps Engineer Bartek Grzybowski. Both built the foundation for the integrations described in this article.

Towards financial services available to all

We’re working throughout the company to create faster, cheaper, and more available financial services all over the world, and here are some of the techniques that we’re utilizing. There’s still a long way ahead of us, and if you’d like to be part of that journey, check out our careers page.

Web Development
DevOps
Software Development
Microservices
Programming
Recommended from ReadMedium