How a proper software development process helps you deal with unforeseen problems
Software development is often unpredictable. Changes in the infrastructure or libraries we depend on happen. Bugs come up. Milestones slip by. To be able to deal with all of those changes, we need a proper process in place that will help us deal with unforeseen problems and give us the confidence to upgrade any part of our system at any time.
Often, we only perceive dependencies on a library level as they are the ones we deal with daily. Not updating those means taking on technical debt. By setting up proper automated testing and continuous delivery where the system tells us when it’s ready, we can get to a point where upgrading any library is simple. But this workflow often doesn’t extend to more basic parts of the infrastructure, like the Operating System we use on our machines. We often take them for granted as their release cycles are slow and they are typically supported for a long time. But depending on that level of support, without a well-thought-out plan to update these parts, it just pushes the pain of dealing with it to a later point, where it becomes chronic and much more difficult to manage.
So even the best development process with automated testing and continuous delivery can’t help us if we don’t consider the whole system while building workflows.
Managing Large Changes
We’re currently in the process of upgrading the Ubuntu version we use on our servers. Those changes took quite a while to implement. It wasn’t just a technical challenge to provide the same consistent high-level of quality we expect at Codeship, but also to have a process that lets us slowly release those changes and find any problems we have before the general release.
We can now roll out different versions of our infrastructure based on different operating systems and decide on which of those to run our builds. This allows us to test the whole infrastructure much more thoroughly and ensures that we don’t negatively interrupt our customers’ deployments.
We had to dive deep into the process necessary to roll out these changes and decide on how our technology needs to support those processes. It’s often hard to decide early what these specific update paths are and how to deal with them in the future. But it’s critical to set up your team and development to see change as the natural order. We fully stand behind this and it’s something that we implement across our company and technology. We need to Build for Change.
While you might not need the technology or the process to replace every part of your infrastructure from the beginning, you need to be aware of the dependencies you build and how those might affect you in the future.
In software projects, we often build up dependencies that aren’t visible on first sight, but painful once we need to deal with them. So deal with them early and often, even if it’s just as an experiment on the side that isn’t intended to go into production. At least you’ll have the data and experience to work with, and a process to deal with that changes, once it becomes inevitable.
You will have to handle unforeseen changes, upgrades to your dependencies and general problems in your infrastructure. Sometimes those might turn out as minor or sometimes they grow while investigating them, similar to what happened with our Trusty upgrade.
If you fear those changes and ignore them today, they will come back even stronger tomorrow. A minor change, a small process improvement or a minimal technology upgrade becomes an unbeatable beast that will suck up your time, energy and productivity.
Prepare your team, your process and your technology for change. This will allow you to face it without any fear. Fear is what holds us back, fear is what decreases our performance and innovation. By preparing and reducing this fear, we can build products that are truly innovative and truly loved by our users.
Did you have to make changes you were afraid of? How did you handle them? Let us know in the comments.