Comments by "Andrea Laforgia" (@andrealaforgia) on "Continuous Delivery"
channel.
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
Scenario 1: You can indeed have only 1 function in your code that will implement one behaviour or the other based on the version (for example, you could use the Strategy pattern there). No need to keep your code physically separated when you can have logical separation.
You don’t need to duplicate any other version of the code that the two libraries have in common. No need to fix bugs in that part of the code multiple times.
In general, you can use feature toggles to logically separate “branches” of logic in the same code base. It works really well.
In some languages (e.g. Java + Spring Boot), leveraging dependency injection, there are some neat ways of injecting behaviours based on conditions that make the above very easy to do (look at how ff4j works, for example).
Scenario 2: the longer code is parked on a feature branch, the higher the risk of diversion from master and merge conflicts. The best way to develop code we know so far is to continuously integrate into a shared mainline multiple times a day (e.g. Continuous Integration). See above: using feature toggles, you can delay releasing a specific feature as long as you want.
The big misunderstanding here is that each push to master will release to production. One thing is pushing to master, another thing is releasing to production. You can have that with Continuous Deployment. With Continuous Delivery, your code is always releasable but not always released. The key point here is that you must be able to release whenever you want with no fear.
The reason why trunk-based development seems dangerous to you is because you’ve never used it. Companies like Google or Facebook (but I could also mention some smaller companies I’ve worked for) use scaled trunk-based development on extremely large projects with thousand developers on them.
What you describe in your last paragraph is not continuous integration.
Continuous Integration is defined as: “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.By integrating regularly, you can detect errors quickly, and locate them more easily.” (ThoughtWorks)
1
-
@markar34 Of course I am aware of semver, it's a de facto standard. Semver is irrelevant though. You can use whatever versioning mechanism.
I totally understand why you need to keep two separate versions of your library. That's a common scenario in any software, especially when you deal with "dinosaur" companies that move at a very slow pace and are reluctant to upgrade even when they would need to (e.g. big financial institutions).
I don't think you understood my comment though. I am not questioning the logical separation of your versions; I am questioning the physical separation. Believe it or not, you don't need long-lived branches to maintain that separation. You can have a logical separation of versions within the same single branch. You can deploy from the shared mainline using different configurations for each client and each version.
As I said before, if you have hundred or thousand clients, you cannot possibly afford long-lived branches for all of them. The ability to keep developing your software would grind to a halt.
I mentioned dependency injection with regard to how to use feature toggles properly with some languages/frameworks, just to avoid the mess in the code that you were mentioning. Your code can be architected in a way such that the usage of feature toggles has a very minimal impact on it. Unfortunately, it would take time and a real example to show you how that works. The ff4j library is very powerful from this point of view, leveraging proxies and DI.
>The fact that we share say, the develop branch, and our CI builds it, and runs automated tests, that's enough to say it's continuous integration. I'm not sure what is your definition of continuous integration.
Nope. Not if you use long-lived branches. Continuous Integration, as defined by ThoughtWorks, 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. By integrating regularly, you can detect errors quickly, and locate them more easily."
If your development happens on long-lived feature branches, it's not CI.
CI doesn't just mean having a CI build. It's a development practice.
1
-
1
-
1
-
1
-
1
-
1
-
>In real life you often have to undo days of work, refactor days of code, incorporate feedback from other stakeholders and so on.
People keep mentioning this "real life" like they are the only ones living in the real world and people like Dave Farley come from Mars. Please appreciate the fact that we all belong to the same reality. It's just that we have different work experience. The way of working that Dave is advocating is used effectively by many companies, some of which very large, with extremely large projects, and a huge number of developers.
>people will start using your unfinished code and start editing files you are working on.
Long-lived feature branches only make things worse in that case. TBD is much better, especially when heavy refactoring is involved. Imagine what would happen if we work in the same team, I branch from master, you branch from master, and start refactoring a number of classes you are working on, maybe removing some code that you are changing. I finish and merge into master. At the moment you need to merge, you will end up in merge hell. It will be impossible for you to understand how to fix the merge conflicts cause you don't know my changes. You will need me to help out, which basically means having you redo the work of days on a completely changed codebase.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
Mob programming has been my favorite way of working for quite a long time now. Whenever I used it, we ended up being way more productive than working independently, with the nice side effect of sharing knowledge across the team, increasing confidence in answering questions about the system, increasing job satisfaction, reducing burnout (deadline was 5pm — no work after that time). I remember joining a team where 4 out of 5 people were new. There was only 1 person who'd been in the company for a few years, who knew the system well and could answer questions. He ended up spending most of his day assisting others. I proposed moving to a mob programming model. It started as an experiment but it became our standard way of working. For me, the crucial moment was when, jokingly, someone said, well "C. is the expert in our team!", to which C. smiled and replied "not anymore!!". Everybody had become an expert. I think there is an upper limit, though, and that's 4-5 people (which, to me, should be the size of a team). I'm aware, however, of a few contexts where large mobs worked really well. Austin Chadwick and Chirs Lucian (Mob Mentality Show, here on YouTube and LinkedIn) interviewed an engineer from Tesla some time ago, if you are interested.
1
-
1
-
@miletacekovic >Of course, you can delay branch creation till bug is found in it, and create a branch from tag when the bug is found. But once branch is created to fix a bug, you need CI pipeline attached to it.
It's not a CI pipeline, it's a build pipeline. It's different. CI means something specific: Continuous Integration. You don't do Continuous Integration on the releasae branches, you keep them for hotfixes. In general, however, keeping a release branch for every customer, assuming that you have hundreds of customers, is suicidal, a good recipe for disaster. You cannot really expect to have to hotfix a bug on hundreds of branches. You will need to make those customers converge into a new release at some point.
>Verifying if a bug fix did not break anything on developer workstation is little scary for medium to large systems .
What developer workstation? Who has ever talking about developer workstations? Developers' workstations are temporary workbenchs. CI is about integrating developers' work into a shared mainline multiple times a day. Tests run on the mainline.
1
-
@miletacekovic You are not doing continuous integration on the release branch. Therefore you cannot call the build for that release branch a "CI pipeline". You are fixing bugs on that release branch, you are not continuously integrating new development. That bug-fixing activity causes frustration among your developers, rest assured, given that they have to apply the same fixes in multiple places, with all the problems that that practice entails. If you have several bugs, discovered for multiple client's version, you need to multiply that bug-fixing activity for all those branches, increasing frustration and fear of mistakes. The idea that you can keep release branches open indefinitely is not a sustainable model. It doesn't really work anywhere. You will need, at some point, to make your release branch converge into master again or you are doomed to eternal sadness.
Stop calling it "CI pipeline". CI happens ONLY on the shared mainline of development, nowhere else. You are talking about separate builds that happen on the CI server. It's not a "CI pipeline".
1
-
1
-
1
-
1
-
1
-
1