Back in 2010s DevOps movement was introduced.
I remember me being confused what the heck does this whole DevOps mean. Aight, it has to be something with infrastructure management. But they talk a lot about it being connected to development, and I am the developer right?
At the company I was working at the moment, we had this team of "DevOps" guys. They were responsible for building and configuring pipelines for our code base. That was particularly interesting, because I saw the stuff they were doing and I was wondering: how this kind of work requires a specialized team?
Ok, I assumed this has to be something with company's compliance and permissions. And maybe for other teams they do more complex stuff.
So like I said, the DevOps team was building pipelines for us. The thing is that today I know to call it just a "pipeline" but back then everyone was calling it "CI".
Well, I wondered again: What does it mean? Especially CONTINUOUS?
We were very agile, we used Scrum and later we switched to Kanban to be even more agile. But:
- I was working on feature branch for a sprint or two
- I had to fight my way through the merge or rebase
- Then my changes were blocked in the review queue
- Then once merged (if I were lucky and review didn't fail, which will probably make me to merge/rebase again with the new changes on master), it stuck in the QA queue
It didn't feel CONTINUOUS at all.
Today I think that back then it wasn't just me who did not understand what this whole DevOps actually is. Even the "DevOps team" did not understand that, or at least they were not propagating the methodology nor educating us what it really is.
One of the reason we we couldn't fit our development cycle into CONTINUOUS integration practice was GitFlow. I won't describe here what GitFlow is, because it has no sense.
You can read about it at the source, i.e. Vincent Driessen blog post about "A successful Git branching model" from 2010.
For the sake of this article this is enough to take a look at this famous graphic:
I remember this graphic years ago was introduced to explain what GitFlow is to me. I didn't understand all the complexity then nor TBH I think I can say I remember all the intricacies today. But what is important, I worked with this approach for years and I know it's effects:
❌ Merge Hell
Developers working on long-lived branches are getting more and more desynchronized from the changes on the master branch which leads to more and more complicated merges/rebases
❌ Changes desynchronization & branch dependencies
Feature branches start to depend on each other, because my teammate already built some components on their branch that I need to implement my feature. But it's not on the master, so I can't. And it won't be for long time, because it has to get through the whole cycle.
And my feature is actually smaller, and it's actually ready, but I have to wait for the other branch to get merged.
❌ Delays in Feedback & Bug Fixes
All the testing is possible only after successful integration (which sometimes means after weeks the last line of code was written). At this point, the developer can work on another task and they have to switch the context which leads to decreased productivity.
❌ Complicated CI/CD pipelines
You can test feature branches, but how do you deploy them to the infrastructure? Do you create separate pipelines/infrastructure per feature branch? Or you use just one, which means blocking it for other team members?
❌ Encourages Manual Code Reviews instead of Automated Quality Gates
We don't invest in efficient automated tests, because we don't trust them. In that case we rely on manual reviews and testing.
But what if no one have time for review? It's getting stuck.
How do you manually test the whole system for regression, after years of development, where number of features is too big to retest for every release. And what if after testing phase, the code needs to be merged/rebased again?
All the above leads to
❌ Slower Release Cycles
So what is the alternative?
- Have just one main branch, where all the developers merge their work every day (or even more often)
- Keep just one CI pipeline and do all the testing there
- Keep the automated test suite that will validate the whole system stability after every change
- After the stability is confirmed, deploy (Continuous Delivery)
Results:
✅ Limited merge conflicts
✅ Smallest changes available to every one (no branch dependencies)
✅ Immediate feedback from regression test suite
✅ Simplified CI/CD pipeline (just one)
✅ No blocking reviews (reviews can be done after the change is merged, and improvements are just getting the next change)
✅ Bug fixes are just another change (no roll-backs)
✅ The main branch is always release-ready
Of course it introduces other challenges:
- How do I build the automated test suite?
- How do I make the test suite to provide immediate feedback?
- How do I manage which changes are getting visible to the user? Some features aren't ready yet
These things were figured out too, and I will write on these topics in next articles, so make sure to follow.
Actually you can already read about the second question here:
But at the end of the day this is the only way to be Agile and have the integration (and delivery) being CONTINUOUS. And it turns out, the described workflow was there since 1990s, introduced by Kent Beck in his Extreme Programming and it is called:
Trunk Based Development
________
No ChatGPT (or other AI) was used to write this article.