You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I started using Ruby and Rails in 2007, versions 1.8 and 2.x respectively at that time. Being new to engineering as a career and also to the language and framework, I didn't know much about engineering best practices at that time, and I just focused on making sure I got things done in whatever ways that worked.
That worked out pretty ok. The app worked. The company progressed. As far as I can remember, I didn't update/upgrade the code base much. The only times when I did bundle update rails were probably due to security fixes. I shunned away from doing any form of updates because some things would break unknowingly as I don't have automated regression tests to warn me of side effects.
That continued for about another 2+ years before I joined Pivotal Labs. In Pivotal Labs, I learned a lot more about engineering best practices and one of which is Testing. It's important to have automated tests because of many reasons, i.e. prevent regressions etc. And if you can go another level up, doing Test Driven Development is even better.
This post is not about Testing though, but it's related to another best practice that I learned. One of keeping your code base updated always, including all the gems that you are using!
Always Update Your Code
Why is that important?
It's common knowledge now that software projects never ends, and so, your team will probably be working on the same code base for many years. Case in point, Shopify has a 11 year old code base, quote:
Shopify now runs on Rails 4.2. Same codebase started on Rails 0.5 in August 2004 roughly 11 years ago.
Because of that, there are several reasons it's important to keep your code base updated always:
Improvements
There are improvements made to Ruby and Rails everyday through the hardwork of the dedicated community, and every version update allows the language or framework to better cope with the increasing demands of new apps nowadays. At the same time, most RubyGems have frequent updates too - both feature improvements and bugs fixes.
Hence doing frequent updates allow applications to take advantage of these improvements which could possibly make applications perform better (in terms of speed and memory) or make engineers more productive (nothing legacy to maintain).
Hiring
Would you like to work on an old code base? Some people might really like the challenge. I would prefer not to, and most of the people I know would want to work on a well-maintained updated code base.
Moreover..
You would also need to hire folks with intimate experience of the language and framework, to be able to support and maintain the code base and that limits your search scope for talents.
And it would be difficult to onboard junior developers because they would probably have been learning the new and shiny stuff and have very little clue on how to work with older versions of the language or framework.
More time will be spent hiring or training and that's not time well-spent.
So, it's better to keep your code base updated for as it aids hiring and training.
Easier Now Than Later
You'll need to update your code sooner or later, for various reasons like a security fix in a latest version of a dependency, or for a new feature that's easier done with a new RubyGem. So, why wait?
Based on my experience since the Pivotal Lab days, it's pretty painful to only do the updates when you need it in a big bang approach and the typical scenario goes like this..
Maybe you set out to only upgrade one single dependency, but as it turns out, it also requires a new version of another dependency and so on and so forth - a chain reaction ensues.
Your app could be broken by any of these changes and it takes time to hunt down the offender. You end up spending a lot more time on the update (making code base changes, fixing bugs) while the rest of team continues the development.
Oops.. Now you'll get conflicting changes between the update branch and the continued development on master. Next, you have to deal with the pain of merging your updates back into master.
What was supposedly simple turns out to be not so simple afterall. Hence it's really easier to update your app iteratively, in smaller steps than to do it in a big bang approach.
A Good Engineering Discipline
Last but not least, imo, it's just simply a good engineering discipline. Why would you let your code base decay?
There may be times when you should lock your dependencies to specific versions, but there should always be a strong reason to back that up. Otherwise, my belief is always to keep it updated to the lastest version.
Frequent Updates as a Practice
Can everyone put this into practice though? The answer is "No".
Remember my story about my first engineering job? I wouldn't have been able to do this in my first job, simply because my app doesn't have tests. Hence, if I do frequent updates (e.g. once per week), I would have to spend more time running manual tests after each update to make sure everything still worked as expected, and that would just be unscalable. And so fundamentally, I need to fix the problems of (lack of) testing in that case.
But if you are already have a great test coverage, I strongly encourage you to do frequent updates!
The Manual Way
In Pivotal Labs, we used Jenkins as the CI server and so we would have two builds for each project.
The first build would run on every commit to master:
# set up repo
bundle install
rake spec
The second build would run every midnight on master:
# set up repo
bundle update
rake spec
Then in the morning we would be able to see if master's all good with updated gems. If it is, we will do a manual bundle update locally and push it up.
Works, but a pretty manual still. And as humans, sometimes we procrastinate or forget, and so we might only be updating the app once per 2 weeks?
The Service Way
Since moving to other cloud CIs, I missed the functionality of scheduling builds at specific times. But more importantly, I really hope to do this more consistently and spread this practice more (especially to my clients).
deppbot will help us run bundle update daily and issue a Pull Request (PR) for it. As we have GitHub hooked to our CI (Codeship), tests will automatically run when a PR is issued, and so we can simply merge the PR into master if everything is green. Simple. Convenient.
The Pull Request also comes with a great description of the updated changes (using GitHub's compare view) so it's easy to see the changes of the gems and be sure that nothing is out of the extraordinary.
We have been running this for a while with internal projects and clients, and we really love it, so we feel it's time to release it to the public.
Give it a try now at https://www.deppbot.com - Free for all public repos, and paid plans are inexpensive too.
Although it's built as a SaaS, deppbot is really more about the practice to keep your code updated (and which is easier when you have specs), than just a service that performs bundle update. It's a practice that we believe in and we hope all teams do too, as we know it will make the team happier. :)
Epilogue
Maybe you might be thinking though:
I don't dare to do automated daily updates even if I have tests. I would prefer to do it manually so that I can test it before merging
These are the questions that I have though:
How frequent will you update if you do it manually?
What would make you more confident of the updates if you do it manually?
What would you test differently if you do it manually?
Why don't you encode that difference as an automated test then?
I started using Ruby and Rails in 2007, versions 1.8 and 2.x respectively at that time. Being new to engineering as a career and also to the language and framework, I didn't know much about engineering best practices at that time, and I just focused on making sure I got things done in whatever ways that worked.
That worked out pretty ok. The app worked. The company progressed. As far as I can remember, I didn't update/upgrade the code base much. The only times when I did
bundle update rails
were probably due to security fixes. I shunned away from doing any form of updates because some things would break unknowingly as I don't have automated regression tests to warn me of side effects.That continued for about another 2+ years before I joined Pivotal Labs. In Pivotal Labs, I learned a lot more about engineering best practices and one of which is Testing. It's important to have automated tests because of many reasons, i.e. prevent regressions etc. And if you can go another level up, doing Test Driven Development is even better.
This post is not about Testing though, but it's related to another best practice that I learned. One of keeping your code base updated always, including all the gems that you are using!
Always Update Your Code
Why is that important?
It's common knowledge now that software projects never ends, and so, your team will probably be working on the same code base for many years. Case in point, Shopify has a 11 year old code base, quote:
Because of that, there are several reasons it's important to keep your code base updated always:
Improvements
There are improvements made to Ruby and Rails everyday through the hardwork of the dedicated community, and every version update allows the language or framework to better cope with the increasing demands of new apps nowadays. At the same time, most RubyGems have frequent updates too - both feature improvements and bugs fixes.
Hence doing frequent updates allow applications to take advantage of these improvements which could possibly make applications perform better (in terms of speed and memory) or make engineers more productive (nothing legacy to maintain).
Hiring
Would you like to work on an old code base? Some people might really like the challenge. I would prefer not to, and most of the people I know would want to work on a well-maintained updated code base.
Moreover..
You would also need to hire folks with intimate experience of the language and framework, to be able to support and maintain the code base and that limits your search scope for talents.
And it would be difficult to onboard junior developers because they would probably have been learning the new and shiny stuff and have very little clue on how to work with older versions of the language or framework.
More time will be spent hiring or training and that's not time well-spent.
So, it's better to keep your code base updated for as it aids hiring and training.
Easier Now Than Later
You'll need to update your code sooner or later, for various reasons like a security fix in a latest version of a dependency, or for a new feature that's easier done with a new RubyGem. So, why wait?
Based on my experience since the Pivotal Lab days, it's pretty painful to only do the updates when you need it in a big bang approach and the typical scenario goes like this..
Maybe you set out to only upgrade one single dependency, but as it turns out, it also requires a new version of another dependency and so on and so forth - a chain reaction ensues.
Your app could be broken by any of these changes and it takes time to hunt down the offender. You end up spending a lot more time on the update (making code base changes, fixing bugs) while the rest of team continues the development.
Oops.. Now you'll get conflicting changes between the update branch and the continued development on master. Next, you have to deal with the pain of merging your updates back into master.
What was supposedly simple turns out to be not so simple afterall. Hence it's really easier to update your app iteratively, in smaller steps than to do it in a big bang approach.
A Good Engineering Discipline
Last but not least, imo, it's just simply a good engineering discipline. Why would you let your code base decay?
There may be times when you should lock your dependencies to specific versions, but there should always be a strong reason to back that up. Otherwise, my belief is always to keep it updated to the lastest version.
Frequent Updates as a Practice
Can everyone put this into practice though? The answer is "No".
Remember my story about my first engineering job? I wouldn't have been able to do this in my first job, simply because my app doesn't have tests. Hence, if I do frequent updates (e.g. once per week), I would have to spend more time running manual tests after each update to make sure everything still worked as expected, and that would just be unscalable. And so fundamentally, I need to fix the problems of (lack of) testing in that case.
But if you are already have a great test coverage, I strongly encourage you to do frequent updates!
The Manual Way
In Pivotal Labs, we used Jenkins as the CI server and so we would have two builds for each project.
The first build would run on every commit to master:
The second build would run every midnight on master:
Then in the morning we would be able to see if master's all good with updated gems. If it is, we will do a manual
bundle update
locally and push it up.Works, but a pretty manual still. And as humans, sometimes we procrastinate or forget, and so we might only be updating the app once per 2 weeks?
The Service Way
Since moving to other cloud CIs, I missed the functionality of scheduling builds at specific times. But more importantly, I really hope to do this more consistently and spread this practice more (especially to my clients).
Hence we built deppbot - https://www.deppbot.com!
deppbot will help us run
bundle update
daily and issue a Pull Request (PR) for it. As we have GitHub hooked to our CI (Codeship), tests will automatically run when a PR is issued, and so we can simply merge the PR intomaster
if everything is green. Simple. Convenient.The Pull Request also comes with a great description of the updated changes (using GitHub's compare view) so it's easy to see the changes of the gems and be sure that nothing is out of the extraordinary.
We have been running this for a while with internal projects and clients, and we really love it, so we feel it's time to release it to the public.
Give it a try now at https://www.deppbot.com - Free for all public repos, and paid plans are inexpensive too.
Although it's built as a SaaS, deppbot is really more about the practice to keep your code updated (and which is easier when you have specs), than just a service that performs
bundle update
. It's a practice that we believe in and we hope all teams do too, as we know it will make the team happier. :)Epilogue
Maybe you might be thinking though:
These are the questions that I have though:
Think again. Are manual updates really better?
Why don't you give deppbot a try? 😘
Thanks for reading!
@winston ✏️ Jolly Good Code
About Jolly Good Code
We specialise in Agile practices and Ruby, and we love contributing to open source.
Speak to us about your next big idea, or check out our projects.
The text was updated successfully, but these errors were encountered: