DEV Community

Cover image for The Only Way to Achieve Continuous Integration.
Sadick
Sadick

Posted on • Originally published at thepractising.dev

The Only Way to Achieve Continuous Integration.

Single Branch.

The only way to achieve continous integration is through Trunk-Based Development. Trunk-based development is based on the idea that there is a single branch i.e main|master|dev|trunk in which all the developers on your team commit to frequently (at least once everyday).

The confusion around continous integration.

I have heard countless times people describe continous integration in terms of tools. They think continous integration is the process of passing code changes through a tool which produces results ✅ at the end of the process. That thinking is even made worse with how some tools name themselves. i.e CircleCI, Gitlab CI e.t.c.

Continous integration is the act of developers merging their code changes together frequently.

The issue with branching.

Most if not all of us are used to branching. Whenever there is a new feature we want to develop, we create a branch for it. If there is a bug, we create a branch to fix the bug. Branching has become part and parcel of our everyday work. We create branches to isolate our changes. But is creating branches the best way to work with your team?

branching

Below are some of the issues I see with branching.

Isolated development.

When developers work on different branches they may not always be aware of what the other developers are doing. It is possible that the developers might be changing the same piece of code without them knowing. Distance is created because every developer will only be concerned with the changes they want to bring in therefore forming silos.

Working in this way means developers hide changes from each other untill they are ready to show them. As developers we should be embracing change not hiding it.

Complexity of conflicts.

As the number of branches and the complexity of the codebase increase, so does the likelihood of conflicts. Complex conflicts can be challenging to resolve because they may involve changes in multiple files or dependencies. I know you have experienced this at least a couple times and its not fun to deal with. I have never met a developer who likes to resolve conflicts.

Developers working in isolation on their branches may miss opportunities for collaboration and sharing of ideas, leading to missed improvements and innovation. The lack of collaboration inhibits collective ownership of the code. No developer feels its their responsibilty to make sure the code is stable and easy to work with.

Implementing Trunk-Based Development.

Have single branch, where your teams commit to thats it. But this creates other issues like,

  • How handle code reviews.
  • What about big features?

Blindly implementing single branch for all your teams' work leads to alot of chaos. For trunk-based development to be successfull there are a couple of guidelines that you can follow.

Small changes.

Every commit should be small, buildable and testable. The smaller the change between two working states the easier it is to find and fix any issue introduced by that change.
How small is small? A small commit is a commit that addresses a single task or issue and makes a meaningful change to the codebase.

Frequent commits.

You and your team need to commit frequently and push the commits. This ensures faster integration with everyone elses code. Frequent commits also reduces the likelyhood of hard to resolve merge conflicts. When you and your team are pushing regularly, it gives your team a change to see each others work, which encourages collaboration.

Keep the pipeline green.

If for some reason the build is broken, then your team should drop everything they are doing to fix the build. This will ensure no problematic change makes it to production. Also your team should make it a habit to test and build on their own machines before pushing it to the build pipeline. 😉

Keep your builds fast ⚡

When you are making small commits, you wouldn't want to be slowed by the build speed. You should strive to bring your build speed down to seconds. You could use strategies like cached builds or incremental builds to improve the speed of your builds.

All the above guidelines are good, but still doesn't answer the questions like, code reviews and big features.

How handle code reviews.

  • You could review code after the integration after a section of code has received significant changes.
  • You could introduce pair programming, were two people would work on a feature together. Since their is an extra eye on your work most issues will be caught by your programming pair. You could consider the commit you made reviewed when working with another person on a problem.
  • If you are adventurous you could even try Mob programming. That is where you have more than 2 people working on a task. Mob programming is very effective when it comes to knowledge sharing.

Handling big features.

Since you will be doing small, single focused commits frequently, there is no way you will fit a big feature into a single commit. You will likely make more commits before a feature is considered done.

One way to handle this is through feature flags.

feature-flags

You would start by creating a feature flag for the feature you are working on and keeping it turned off. Once you complete all the work neccessary for the feature you would turn the feature on. After some monitoring, if you are convinced that the feature is working as intented in production, you will need to delete the feature flags from your code and the platform you use to manage the feature flags.

Even if you are not ready to adopt trunk-based development, at least keep your commits small and focused on a single well defined task.✌️

Top comments (0)