Better code commits

March 28, 2022

Introduction

As a DevOps/Cloud engineer, git is an essential tool in our arsenal. A git commit is an action that we execute daily, hourly and sometimes more often than that. I hope that you, the reader, are not committing code every second - that would be shocking. Committing code not only creates a snapshot of the work you have done but it also describes the work you have done in a commit message.

git add .

git commit -m "It works"

By the end of this post I hope that the two commands above are not the only ones you will run prior to pushing code. Regarding the second command… well it is unacceptable and stick around to find out why 👀 .

Why the fuss?

Git provides a decentralised workflow, where you as an engineer contribute to a repository that others can also contribute to. It is therefore important that a commit provides a clear insight to changes that have been made for quicker debugging (time is money). It is also important that we test our code for linting issues. Your code doesn’t need to work but it needs to look good. The code does not need to be complete for it to be commited.

Most CI/CD pipelines are triggered on git pushes so it is important to do everything you can to prevent a failure in the pipeline.

So how do I make my code better?

Here I will introduce two tools:

  1. pre-commit- This tool will be used for code testing
  2. commitizen- To create better commits

What is pre-commit?

Pre-commit is a python package which acts as a framework for managing pre-commit hooks. Pre-commit allows you to run several staged code checks prior to committing your changes.

Why use pre-commit?

To save time and money! Once a code gets pushed into git and your pipeline kicks off, it can take a few seconds or minutes to find where an error has come from. So by using pre-commit, we can prevent simple errors such as terraform validation or even simpler YAML lint!

Where do I start with pre-commit?

We are going to add a pre-commit config to the terraform code we have built in the previous post. If you haven’t gone through it or don’t want to, that is absolutely fine. Add a pre-commit config to any code you are working on and try to make it a habit. Adding a pre-commit config to a template repository is a perfect way to introduce this tool to your wider team.

Prerequisites

Step 1

pip install pre-commit

Step 2

pre-commit --version

## output should look similar to this

pre-commit 2.17.0

Step 3

touch .pre-commit-config.yaml

Step 4

---
-   repo: https://github.com/pre-commit/pre-commit-hooks #name of repo with hook
    rev: v4.1.0 # version of the repo (tag) or branch
    hooks:
    -   id: trailing-whitespace #id of the hook. Some repos have multiple hooks

Step 5


git status
git add .
pre-commit install # run pre-commit every time you run a commit command. You can skip it for now.
pre-commit run --all-files

#output should look something like this
Trim Trailing Whitespace.................................................Passed
-   repo: https://github.com/gruntwork-io/pre-commit
    rev: v0.1.17
    hooks:
      - id: terraform-fmt
      - id: terraform-validate
      - id: tflint

Step 6

The code snippet below will tell the markdownlint test to accept a configuration that has been set within the .ci/.mdlrc path.

-   repo: https://github.com/jumanjihouse/pre-commit-hooks
    rev: master
    hooks:
    -   id: markdownlint
        args: ['-c','.ci/.mdlrc']

What does the config file look like?

|- .ci                      #<--- This is a new directory
|   |- .mdlrc               #<--- This is a new file
|   |- markdown.rb          #<--- This is a new file
|- main.tf                  # These
|- providers.tf             # files
|- repositories.yml         # already exist.
|- README.md                # This example structure builds
|- .pre-commit-config.yaml  # on the terraform 101
|- .gitignore               # blog post

  1. The .mdlrc file with the following content. More documentation on this file is available here.
style '.ci/markdown.rb'
  1. The markdown.rb file with the actual rule exceptions defined. This is the file that you can populate with the exceptions you require for the code base.
all
exclude_rule '<MDrule number>'

For example the configuration below enforces all Markdown rules excluding MD002.

all
exclude_rule 'MD002'

What is commitizen?

Commitizen is a Python package for writing descriptive and standardised commits across teams. It also allows for changelog creation once you release a new version of the code base you are working on.

Why use commitizen?

  1. To create a commit standard across your team.
  2. To capture work items (Jira tickets or Azure board tickets) within your commit.
  3. To create commit prefixes that you can trigger pipelines base on.
  4. And many more!

Where do I start with commitizen?

Step 1


pip install -U commitizen

#alternatives

sudo pip3 install -U Commitizen

brew install commitizen

Step 2

cz commit

Alt text for my gif

Final remarks

git status
git diff ## only if you know how to get out of vim
git add .
pre-commit run --all-files
git add . ## pick up changes made by pre-commit
cz commit
git push