For some years I have been collaborating on code with my team using Git, following a practice called Continuous Integration (CI).
Continuous Integration (CI) is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible.
Getting a team involved, trained and disciplined has been quite a journey. In this article, I am about to share my lessons learned with you. I will start by explaining a bit of context before I will continue telling you about my experience implementing it.
Continuous Integration in a DevOps culture
Organizations work agile in a DevOps culture. In such a culture, understanding CI is essential when practicing Continuous Delivery (CD) and Continuous Deployment (another CD). Version control and configuration management are fundamental, especially when automated pipelines are involved.
Continuous Delivery vs. Continuous Deployment
Continuous Delivery is an extension of CI to make sure you can release new changes to your customers quickly. You are able to deploy your application at any point in time with the click of a button. The moment of releasing totally depends on your business requirements. Whereas Continuous Deployment goes one step further and deploys changes automatically without human intervention. Only a failed test will prevent a new change to be deployed.
Git is a distributed version control system for tracking changes in source code during software development, but it can be used to track changes in any set of files. Git can be a key component for CI.
A git repository (repo) is a folder in which you are storing all the files related to your project. The folder itself contains a hidden .git folder in which all changes are tracked. On a single developer machine, this can be called a local repository. When developers start collaborating on code, a remote repository can be created. This can also be referred to as a remote repository or a git server. A remote repository generally lies somewhere outside your system, on a remote machine.
Dealing with changes
Every new, updated or deleted code that gets staged, committed and eventually pushed by a developer, using a dedicated git client or via terminal, can be identified as a commit. A commit can be created or reverted. Every new change results in a new commit.
Working with branches
When a git repository is initialized, a default branch called master is created. A branch is a movable pointer to a set of commits. Using different branches such as: a development branch, feature branches, release branches and hotfix branches is very useful to separate commits within one repository. For instance, working on a feature branch can result in 20 commits. You don't want all these commits to be visible in your development branch. When merging the feature branch with the development branch, all changes can be reflected by a single commit. The entire feature can be reverted by reverting just one single commit. Making it easier to comprehend.
Release branches can be created from the development branch where features and hotfixes are added. After bug fixes have been completed on the release branch the master branch can be updated and commits tagged with a version number. Each branch is verified using an automated build and tests.
Shifting left strategy
At this moment I’m dealing with two remote repositories. As a QA consultant I’m working for a client which owns a repo in which a regression test suite is stored. Another repo is owned by the software vendor providing the application I’m testing for my client. My aim is to shift left and move the tests from my repo to the vendors repo. My goal is to benefit from the tests as early as possible during development. Eventually resulting in less defects and less work.
Doing CI properly was one of the challenges we faced as a team. We started of working all together on one master branch and started to include and run tests. With multiple local working copies (x8) it was important that everyone pushed and pulled their changes on a regular basis. This did not happen. Resulting in many merge conflicts. A merge conflict is likely to happen if your local copy is ahead and changes in the same file were already pushed by someone else. To make sure this doesn't happen, it is best practice to work on a separate branch, e.g. a feature branch.
Ensuring Code Quality
Company policy is just recently restricting pushes directly to the master branch. There is only one way to update the master now, and that is to make changes in a separate branch and create a merge request to merge that branch into the master. A merge request is protected and requires approval first from one of your team members. This 4-eye principle restriction enforces code review to ensure code meets quality standards. This principle can be configured for any branch of your choice.
Maintain a clean git history
In some cases, we are working with more than one developer on the same feature branch. In that case frequently pulling and pushing code, to keep the central repository and your local working copy up-to-date, stays relevant. If your local working copy is ahead and the feature branch was updated by your colleague, you can pull and merge changes. Creating a new single commit with all changes. But this approach can pollute your git history quite a bit. It is hard for developers to understand what was included in the change and track who did it. Using a git pull --rebase is another way of merging the code, but lets you keep a clean git history. A git pull --rebase fetches all commits first from the master and adds your local commits on top. Ending up in the same state of the code but maintaining a clean git history.
Try it yourself
Start using git yourself by following a few scenarios on KataCoda. No prior installations needed: https://www.katacoda.com/courses/git
Another link I found particularly useful is this one. It provides you a git cheat sheet: https://zeroturnaround.com/rebellabs/git-commands-and-best-practices-cheat-sheet/
You can use this git cheat sheet and try the features out yourself. One piece of advice, first focus on observing your repository and make a change, before moving on to synchronize. Finish by working with branches. It’s not too difficult, and very valuable to know.