I think you misunderstood what continuous integration is:
Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.
Nowhere does it say "branch". CI is infact very compatible with gitflow and infact gitflow is entirely designed towards CI. Feature branches are part of the shared repository and developers are encouraged to make regular commits (check-ins) to their feature branch. Your pipeline can be setup to verify and automatically build each feature branch, so you can detect problems early. When the feature branch is ready it gets merged into a developer branch. This dev branch is then also verified and built, if the build fails, it is easy to revert the change. Gitflow allows you to detect merge conflicts early.
With trunk based development if there's a conflict or a build error, your pipeline fails and someone has to undo the commit, assuming you can figure out which commit is the actual problem... What happens if two developers make commits to your trunk one second after the other and the pipeline wasnt finished yet? How do you figure out which commit is broken? How are you going to fix it? All the time you spend figuring this out, nobody can make commits because the pipeline fails... In gitflow if the dev pipeline fails, you simply revert the merge and everybody can continue happily working on different features. Or am I missing something and do code conflicts magically not happen in trunk based development?
I don't see where you think I said CI requires a branch either? I recommended a way to follow Continuous Integration after providing the definition and a link to additional material.
Branch builds doesn't work well in practice since it either results in one environment per build which is impractical or no actual deployment which means you are only testing a local copy of the code.
Unfortunately undoing commits is another bad practice that should be avoided. When a pipeline fails you should fix the code, not undo the work that was already done.
"What happens if two developers make commits to your trunk one second after the other and the pipeline wasnt finished yet?" The pipeline runs once for the first commit and once for the second in order. If the first fails then it was the first, if the second fails then it was the second. You fix it by looking at the change, fixing the code, and integrating the fix into the code base.
The whole premise of Continuous Integration is that when a developer breaks a build they and anyone else who wants to fix it do so immediately. It started with developers using a single shared machine to run the builds, only one person could use it at a time, and it had to be working when they were done.
Code conflicts are so tiny and dealt with so quickly in trunk development that it seems like magic.
"Gitflow has fallen in popularity in favor of trunk-based workflows, which are now considered best practices for modern continuous software development and DevOps practices. Gitflow also can be challenging to use with CI/CD."
Branch builds doesn't work well in practice since it either results in one environment per build which is impractical or no actual deployment which means you are only testing a local copy of the code.
No? I mean... how you setup your build pipeline is entirely up to you... Atleast for web development its pretty easy to add a deployment step to your build pipeline that puts the compiled code in an environment that's a reflection of production (e.g. running the same services (or copies of them) that are running in production). You can control which environment you deploy in by adding environment flags in your code, like dev, staging, prod or whatever works for you.
Unfortunately undoing commits is another bad practice that should be avoided. When a pipeline fails you should fix the code, not undo the work that was already done.
Yes, thats nice in theory, but in practice I've seen many occassions where the dev team was not able to fix the code in a timely fashion and had to revert, in order to be able to continue other work.
The whole premise of Continuous Integration is that when a developer breaks a build they and anyone else who wants to fix it do so immediately.
That sounds like a blocking proces to me... so now feature 1 cannot be released because feature 2 has broken the pipeline and it needs to be fixed first... In a gitflow-like process that is non-blocking, if the pipeline for feature 1 succeeds it can be released, regardless of whether feature 2 pipeline fails. The way you're describing trunk based development to me right now, sounds like feature 2 would prevent feature 1 from being released, meaning failing to meet deadlines on ALL the work the team was working on.
Code conflicts are so tiny and dealt with so quickly in trunk development that it seems like magic.
I'll have to take your word for it... I don't see any proof of why that would be the case though...
You either have 1 environment per branch, shared environments (which is terrible for knowing what is deployed if you are using multiple branches), or aren't deploying your code. Which of these are you proposing?
I've done it in practice but I'm sure there are always teams that can't just fix their code when it breaks. Normally this happens when teams are making changes that are too big due to lack of automation and continuous delivery.
Yes it is intentionally blocking, and once that is accepted we can talk about how to continuously develop features that don't break pipelines using feature flags and other solutions.
Fair enough, I only write these articles to point at what I think we should be doing. Feel free to give it a try and let me know how it goes.
You either have 1 environment per branch, shared environments (which is terrible for knowing what is deployed if you are using multiple branches), or aren't deploying your code. Which of these are you proposing?
No? Your options are limitless when it comes to building and deploying your code... You're not limited to deploying into a shared environment, each branch can have its own space even though it interacts with other services that might be running in develop/staging/production... that entirely depends on how you set it up yourself...
I've done it in practice but I'm sure there are always teams that can't just fix their code when it breaks. Normally this happens when teams are making changes that are too big due to lack of automation and continuous delivery.
I don't believe in perfect humans... Or perfect devs for that matter. I've seen pipelines fail for the silliest of typos... Everybody makes mistakes, if the whole dev team is blocked and has to fix the pipeline, everytime someone makes a mistake... I just don't see it ending well.
Yes it is intentionally blocking, and once that is accepted we can talk about how to continuously develop features that don't break pipelines using feature flags and other solutions.
If you want to convince me of why trunk based development is better and why intentionally blocking development is better, you're going to have to explain how feature flags and "other solutions" are going to magically fix that.
Fair enough, I only write these articles to point at what I think we should be doing. Feel free to give it a try and let me know how it goes.
I havent heard anything yet thats different from the horrible period that existed before gitflow :P
They aren't limitless, it is one of the three I've mentioned and I was asking so I know what you think the solution is.
I never said people are perfect but ignoring pipeline failures and delaying fixes or integration is worse than fixing them immediately. A typo is easy to fix since the person that made the change can just make another change.
Sure, we can get to that. This article was just about identifying that feature branching isn't compatible with continuous integration.
I think it is important to note that the people that wrote the gitflow document don't recommend it and propose trunk development as a better practice. Either they are saying gitflow was a misstep or trunk development isn't the same as what was before both.
They aren't limitless, it is one of the three I've mentioned and I was asking so I know what you think the solution is.
The solution is to stop thinking there are only three options of deployment, in order to justify dismissing gitflow. I can deploy my feature branch just fine, infact I can deploy each seperate pull request for a feature branch and show the result to my team members or clients and it wont interfere at all with other branches or pull requests that are deployed. But most importantly I can run integration tests on each pull request seperately, without them interfering.
I think it is important to note that the people that wrote the gitflow document don't recommend it and propose trunk development as a better practice.
I agree it's sad that they dismissed gitflow and mention a replacement, without explaining how it is actually better. I don't really care what anyone says if they dont offer a better solution and nobody has explained to me yet how trunk development is better than gitflow. If something better comes along that doesn't block the dev process and the release cycle, I'd be happy to switch.
Feature branches are part of the shared repository
Hold on, the definition we are working from says
"developers to integrate code into a shared repository"
Just having a branch in a shared repository does not mean it is 'integrated'. If you have three people push their work branch into a shared repo, the work was not integrated. That is the point of this discussion on Trunk based flow.
There are issues with branches, and feature flags, and rebaseing, and any other collaborative strategy. What we don't want to do is claim our side is doing something it is not.
If you have three people push their work branch into a shared repo, the work was not integrated. That is the point of this discussion on Trunk based flow.
That entirely depends on where and when you run your integration tests. If you run integration tests for each pull request, the work will be integrated with whatever is the current status of the branch they're integrating into.
What we don't want to do is claim our side is doing something it is not.
I definitely don't want to claim my side is doing something it is not. Ofcourse it sucks when your pull requests integration tests fail because another feature was merged into the source branch first and the changes somehow affect your work (usually an indicator someone went out of scope). As far as I understand trunk based development has this same issue. My issue with trunk based development is that when this happens you cannot release or continue development on other features.
work will be integrated with whatever is the current status of the branch they're integrating into
But it is not integrated with other people's work continuously. That is the point. I don't agree that we need to go to that extreme, but if you have long lived feature branches you aren't doing continuous integration (only with one long lived feature branch at a time)
Trunk based dev reduces conflicts because you're more likely working in the latest modified code. With branches people can go days without pulling in mainline. The issue is less with the branching model and more to do with the people.
Even git flow does not endorse long lived branches, but that still happens.
But why do you want to integrate with other peoples work if their work isnt even ready to be integrated into the source branch yet? That doesnt make sense to me.
Trunk based development wants to integrate with each and every commit... won't that discourage people from making regular commits? They'll feel forced to only commit when they're completely finished with a task and are already pretty sure that their code wont break the pipeline.
I'd prefer if people made commits to the feature branch as often as possible even with "unfinished" code and pull in the source branch into the feature branch as often as possible in order to avoid conflicts, rather than postponing their commit because they're scared it won't integrate with the trunk yet.
Because adding new functionality to the code base that isn't used in production isn't that hard and it reduces the time to integrate which reduces complexity and wasted work.
No, it is just a different style of development, accepting that there is no such thing as a complete start to end finished task in one commit. There is also nothing wrong with tests failing in the pipeline. It is more important to improve quickly than guarantee green tests (which can't be done anyway).
That doesn't help integrate their branch into the mainline which is what continuous delivery is. That fear and worry goes away if you try it and have a reasonable work environment.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I think you misunderstood what continuous integration is:
Nowhere does it say "branch". CI is infact very compatible with gitflow and infact gitflow is entirely designed towards CI. Feature branches are part of the shared repository and developers are encouraged to make regular commits (check-ins) to their feature branch. Your pipeline can be setup to verify and automatically build each feature branch, so you can detect problems early. When the feature branch is ready it gets merged into a developer branch. This dev branch is then also verified and built, if the build fails, it is easy to revert the change. Gitflow allows you to detect merge conflicts early.
With trunk based development if there's a conflict or a build error, your pipeline fails and someone has to undo the commit, assuming you can figure out which commit is the actual problem... What happens if two developers make commits to your trunk one second after the other and the pipeline wasnt finished yet? How do you figure out which commit is broken? How are you going to fix it? All the time you spend figuring this out, nobody can make commits because the pipeline fails... In gitflow if the dev pipeline fails, you simply revert the merge and everybody can continue happily working on different features. Or am I missing something and do code conflicts magically not happen in trunk based development?
I don't see where you think I said CI requires a branch either? I recommended a way to follow Continuous Integration after providing the definition and a link to additional material.
Branch builds doesn't work well in practice since it either results in one environment per build which is impractical or no actual deployment which means you are only testing a local copy of the code.
Unfortunately undoing commits is another bad practice that should be avoided. When a pipeline fails you should fix the code, not undo the work that was already done.
"What happens if two developers make commits to your trunk one second after the other and the pipeline wasnt finished yet?" The pipeline runs once for the first commit and once for the second in order. If the first fails then it was the first, if the second fails then it was the second. You fix it by looking at the change, fixing the code, and integrating the fix into the code base.
The whole premise of Continuous Integration is that when a developer breaks a build they and anyone else who wants to fix it do so immediately. It started with developers using a single shared machine to run the builds, only one person could use it at a time, and it had to be working when they were done.
Code conflicts are so tiny and dealt with so quickly in trunk development that it seems like magic.
There is a reason that the Gitflow document (atlassian.com/git/tutorials/compar...) explicitly states that:
"Gitflow has fallen in popularity in favor of trunk-based workflows, which are now considered best practices for modern continuous software development and DevOps practices. Gitflow also can be challenging to use with CI/CD."
No? I mean... how you setup your build pipeline is entirely up to you... Atleast for web development its pretty easy to add a deployment step to your build pipeline that puts the compiled code in an environment that's a reflection of production (e.g. running the same services (or copies of them) that are running in production). You can control which environment you deploy in by adding environment flags in your code, like dev, staging, prod or whatever works for you.
Yes, thats nice in theory, but in practice I've seen many occassions where the dev team was not able to fix the code in a timely fashion and had to revert, in order to be able to continue other work.
That sounds like a blocking proces to me... so now feature 1 cannot be released because feature 2 has broken the pipeline and it needs to be fixed first... In a gitflow-like process that is non-blocking, if the pipeline for feature 1 succeeds it can be released, regardless of whether feature 2 pipeline fails. The way you're describing trunk based development to me right now, sounds like feature 2 would prevent feature 1 from being released, meaning failing to meet deadlines on ALL the work the team was working on.
I'll have to take your word for it... I don't see any proof of why that would be the case though...
You either have 1 environment per branch, shared environments (which is terrible for knowing what is deployed if you are using multiple branches), or aren't deploying your code. Which of these are you proposing?
I've done it in practice but I'm sure there are always teams that can't just fix their code when it breaks. Normally this happens when teams are making changes that are too big due to lack of automation and continuous delivery.
Yes it is intentionally blocking, and once that is accepted we can talk about how to continuously develop features that don't break pipelines using feature flags and other solutions.
Fair enough, I only write these articles to point at what I think we should be doing. Feel free to give it a try and let me know how it goes.
No? Your options are limitless when it comes to building and deploying your code... You're not limited to deploying into a shared environment, each branch can have its own space even though it interacts with other services that might be running in develop/staging/production... that entirely depends on how you set it up yourself...
I don't believe in perfect humans... Or perfect devs for that matter. I've seen pipelines fail for the silliest of typos... Everybody makes mistakes, if the whole dev team is blocked and has to fix the pipeline, everytime someone makes a mistake... I just don't see it ending well.
If you want to convince me of why trunk based development is better and why intentionally blocking development is better, you're going to have to explain how feature flags and "other solutions" are going to magically fix that.
I havent heard anything yet thats different from the horrible period that existed before gitflow :P
They aren't limitless, it is one of the three I've mentioned and I was asking so I know what you think the solution is.
I never said people are perfect but ignoring pipeline failures and delaying fixes or integration is worse than fixing them immediately. A typo is easy to fix since the person that made the change can just make another change.
Sure, we can get to that. This article was just about identifying that feature branching isn't compatible with continuous integration.
I think it is important to note that the people that wrote the gitflow document don't recommend it and propose trunk development as a better practice. Either they are saying gitflow was a misstep or trunk development isn't the same as what was before both.
The solution is to stop thinking there are only three options of deployment, in order to justify dismissing gitflow. I can deploy my feature branch just fine, infact I can deploy each seperate pull request for a feature branch and show the result to my team members or clients and it wont interfere at all with other branches or pull requests that are deployed. But most importantly I can run integration tests on each pull request seperately, without them interfering.
I agree it's sad that they dismissed gitflow and mention a replacement, without explaining how it is actually better. I don't really care what anyone says if they dont offer a better solution and nobody has explained to me yet how trunk development is better than gitflow. If something better comes along that doesn't block the dev process and the release cycle, I'd be happy to switch.
Hold on, the definition we are working from says
"developers to integrate code into a shared repository"
Just having a branch in a shared repository does not mean it is 'integrated'. If you have three people push their work branch into a shared repo, the work was not integrated. That is the point of this discussion on Trunk based flow.
There are issues with branches, and feature flags, and rebaseing, and any other collaborative strategy. What we don't want to do is claim our side is doing something it is not.
That entirely depends on where and when you run your integration tests. If you run integration tests for each pull request, the work will be integrated with whatever is the current status of the branch they're integrating into.
I definitely don't want to claim my side is doing something it is not. Ofcourse it sucks when your pull requests integration tests fail because another feature was merged into the source branch first and the changes somehow affect your work (usually an indicator someone went out of scope). As far as I understand trunk based development has this same issue. My issue with trunk based development is that when this happens you cannot release or continue development on other features.
But it is not integrated with other people's work continuously. That is the point. I don't agree that we need to go to that extreme, but if you have long lived feature branches you aren't doing continuous integration (only with one long lived feature branch at a time)
Trunk based dev reduces conflicts because you're more likely working in the latest modified code. With branches people can go days without pulling in mainline. The issue is less with the branching model and more to do with the people.
Even git flow does not endorse long lived branches, but that still happens.
But why do you want to integrate with other peoples work if their work isnt even ready to be integrated into the source branch yet? That doesnt make sense to me.
Trunk based development wants to integrate with each and every commit... won't that discourage people from making regular commits? They'll feel forced to only commit when they're completely finished with a task and are already pretty sure that their code wont break the pipeline.
I'd prefer if people made commits to the feature branch as often as possible even with "unfinished" code and pull in the source branch into the feature branch as often as possible in order to avoid conflicts, rather than postponing their commit because they're scared it won't integrate with the trunk yet.
Because adding new functionality to the code base that isn't used in production isn't that hard and it reduces the time to integrate which reduces complexity and wasted work.
No, it is just a different style of development, accepting that there is no such thing as a complete start to end finished task in one commit. There is also nothing wrong with tests failing in the pipeline. It is more important to improve quickly than guarantee green tests (which can't be done anyway).
That doesn't help integrate their branch into the mainline which is what continuous delivery is. That fear and worry goes away if you try it and have a reasonable work environment.