Coding Standards

We value high quality, easy to read and easy to maintain code. It’s not easy to produce such code, so we’ve got a set of tools to help us.

We use static code analyzers such as RuboCop for Ruby, SwiftLint for Swift and ESLint for JavaScript. These tools help to make the code more consistent and easier to read. We try to stick to community style guides as much as possible. This helps new team members because they are commonly more familiar with standard style guides. Also, standard configurations usually set a very high bar, and that is exactly what we want.

We also use code quality analysis tools such as the code smell detection tool Reek or the structural similarities analysis tool Flay. These tools help us to identify where some pattern or some other structural improvement should be introduced. We also try to stick with default configurations as much as possible for higher quality.

We take these tools seriously because most of the time, they provide huge value and help us to maintain our high standards.

Git Double

When it comes to bigger projects you often find that there are multiple people working in parallel on multiple new features, such parallel developments present challenges. One of the biggest challenges you face is the compatibility of new features with each other.

We have tried well-known branching and integration models, but none of them have worked well for high-quality releases multiple times a day. Git Flow’s release branches require a lot of effort to maintain the entire release process when features are released multiple times a day. Github Flow is suitable for releasing multiple times a day, but it’s very inconvenient for QA teams to test separate feature branches and at the same time test compatibility with the other features under development. We ended up with our own model and named it Git Double. The main concept behind Git Double is that it has two main branches develop and testing, which hugely simplifies the integration and testing process.

This approach has many advantages:

  • QA doesn’t need to deploy any specific version; they simply test the automatically deployed testing branch;
  • there is no need for multiple testing environments because everything is merged into the single testing branch, this branch is automatically deployed to the testing environment;
  • the main develop branch has a clean linear history with squashed commits;
  • it supports both continuously and non continuously deployed projects.

Collective Ownership

Bigger projects are too big to be held in one person’s mind. Some teams choose to delegate particular parts of the code to particular developers. This is a very risky approach. Knowledge gaps develop over time. Code becomes inconsistent and of lower quality.

We use an entirely different approach. Any developer can change any line of code in the codebase. No one owns any part of the code. This leads to numerous benefits in the long run. More developers know more about the entire system. Everyone is encouraged to improve any part of the system. It also highly reduces the risks of knowledge gaps.

Code Review

Code reviews are one of the most important contributors to high quality code. This process also helps you to spread knowledge about the project code. It develops developer skills too - during reviews developers learn new things from each other.

The entire review process is very lightweight and supported by GitLab. The author pushes changes to a remote feature branch and opens a Merge Request in GitLab. A continuous integration server runs tests and code quality tools, and reports build results to GitLab. At least two people review every pull request and leave comments in GitLab. The team lead is one of those reviewers. The author then improves the code according to both the developers and automated reviews. Merge Request is closed only when build passes and accepted suggestions have been implemented. Finally, the feature branch is merged using Git Double.

We rarely perform exceptions to this flow; it works great both for features and small changes, so there is no reason not to follow it for every change.

Pair Programming

Some issues are way harder to solve than others. It’s better to have extra brains for such issues. Pair Programming works very well in such situations. Everyone in the team is free to ask another team member to join a Pair Programming session. We don’t code in pairs a lot, but we are happy to do this when it’s really needed. We found that Pair Programming leads to much faster and higher quality solutions for the most complex issues. We also found that it’s not necessary to use Pair Programming for all code because most problems aren’t usually that complex.

Another reason why we don’t perform Pair Programming full time is that we perform a code review during the Merge Request process. The code here is reviewed by at least two people. This process has the likelihood of even greater efficiency as two people are involved in the review here as opposed to the one reviewer during the Pair Programming session.