Inspecting changes locally before pushing

If you work on your branch you run into the situation that you would like to push your changes to the remote repository. CI will then pick up your changes and run the linting and code quality checks on it. Afterwards, you will see whether you improved the quality. But perhaps there are some new violations that crept into the code? Happens to all of us!

I usually like to see and check if any new issues might come up on CI. This lets me improve them before I push.

The checks I run locally depend on the kind of work that I do. Lately that's a lot of Ruby on Rails again — which is great. I love that framework and the language.

To grade my code, I use Rubocop, Reek and Flay. If you run their respective commands on your repository, they will check the whole code base. This might be ok, if you didn't have any issues before. Since I join teams, these days, that work on legacy projects it is rare that there are no problems with the code. If I run the commands just so, I will get a long list and couldn't possibly see the issues that I introduced through my changes. Lucikly, there is Git and some "command line foo" that can help us here:

git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs rubocop

This command will fetch the current state from the remote and diff your branch/changes to master branch. It then runs rubocop on these changes.

In my ~/.aliases.local file I added three lines for all three linters.

# Code Quality
alias rubocop-changes="git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs rubocop"
alias reek-changes="git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs reek"
alias flay-changes="git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs flay"

I am still working on a way to just call one command and have all thee commands run. That doesn't yet work. Probably because of exit-code reasons, when one linter finds issues.

These simple commands offer a convenient way to find local issues and correct them before pushing to CI.

What role does CI/CD play in your PR?

My guideline for development workflows leans heavily on having a CI/CD server that orchestrates the whole workflow. CI/CD means continuous integration and continuous deployment. There is a lot to CI, and why and how you should do it. Look for multiple articles on that from me here. For the time being, you can get a wonderful introduction to the subject from another expert: [Martin Fowler on his site].

Your CI server should do certain steps when a PR is opened. These include:

  • Check the code for linting errors and warnings.
  • Run all automated tests, including long-running integration tests.
  • Run static (and behavioral) code quality analysis.
  • Deploy the feature branch to a test environment automatically.
  • Inform the reviewers about the results of the above steps, through a comment on the PR, and post the url of the deployed test environment.
  • Block or unblock the the PR from being able to be merged, depending on the results of the above steps.

If you make your CI server report all linting errors, you free your developers to focus on the changes in the logic. Imagine the case where reviewers wants to check your PR, and the first thing they have to do is create lots and lots of comments about linting violations. Nobody will be able to focus on the really important changes and the discussions will grow very big. So let your robots (CI server) handle that for you.

Computer says “no”

[…] we do have formal rules that we should obey when writing code. A team has rules, and new team members need to learn them before trying to write any code.

That's what I wrote yesterday. It's my email so I can write whatever I think is correct. You'll let me know through your answers if I am wrong.

My friend Tino answered on Friday and asked whether a university degree or certificates might function as a driver's license. And that is true to a certain degree. I am getting a new certificate these days as well. I hope to complete the exam on Wednesday (ISTQB Advanced Level — Technical Test Analyst).

The obvious difference to a driver's license? I am not legally required to obtain one before I can start writing code. Tino also said that he'd find it interesting to be (self)tested in current web-standards and best practices. I do believe these tests are valuable. If I come around to create one, I'll let you know.

Back to the beginning of the email. Why do rules matter to a team? Developers have their style for writing code. Even if there are rules and certain regulations you have to follow, developers still find ways to write code in their unique style. And that's a good thing. It would be boring otherwise.

Still, this style has to obey the rules. Here's why:

  • The code won't be too complex. Because your static analysis tools tell you if your cyclomatic complexity metric is too high.
  • Classes and modules will have low coupling and high cohesion. This leads to code that's more easily testable and has higher reusability than other code.
  • If you have an error if explaining comments are missing, you could make sure that your developers take some extra time to make sure code can be easier to understand. Other rules, like variable and method/class/module naming conventions, have the same goal.

In short: Rules help your team to write code that is maintainable and has low technical debt. This reduces the total costs of ownership. If you only look at the cost of writing the code and delivering the software, the costs might be higher if you follow stricter rules. Over the complete lifecycle of a software (product), the total costs would be lower because of better maintainability and a lower number of defects.

This is already getting long. See you tomorrow with even more thoughts on this topic.

Did you see it?

The last few days I wrote about continuous integration without a branching model. I told you who coined the term and who wrote the book about it.

I don't know about you, but upon hearing of this model, I was reminded of Subversion. If you are doing software development longer than I am, perhaps you even used CVS (Concurrent Versions System). Both systems have the notion of branches. As both systems are centralized version control systems, every commit you check in automatically is available for every other user to use. You don't commit locally and then push your changes once you're happy.

Continue reading Did you see it?

Advantages of CI without branches

Yesterday I wrote about what continuous integration means in its purest form. Today I want to share one or two ideas on how that might be good for you.

If you do not work on a (feature) branch, you do not have to merge this branch into the master branch at some point. I don't know how often you commit. I try to write really small commits (of the size that I change one typo in one comment and commit that already). If you work only on one branch, together with all the other developers, you have to keep your commits small. You have to commit frequently. Otherwise your work might get lost (the same way it could get lost on a branch that receives no commits).

Continue reading Advantages of CI without branches