Running tasks before a commit with pre-commit and Docker

There are some tasks I really find necessary before committing code and reaching the CI pipeline, for example formatting, linting, and running unit tests. The sooner any issue can be catch in that regards the quicker a feature or bugfix can be delivered.

One amazing tool for this that is language/ecosystem-independent is pre-commit, which helps us create git hooks that are triggered before a commit, to perform tasks on staged files.

The way I prefer to run these hooks is with Docker, as it removes the need to have any additional set up like a language installed, or a runtime version in our computers or in our colleagues', only the tool itself.


Install pre-commit.

If using macOS with Homebrew:

brew install pre-commit

Configuration file

Create a pre-commit config file named .pre-commit-config.yaml

Hooks configuration

Add the tasks we want to run

  - repo: local # Use a local repository
      - id: docker-go
        name: foo-format
        language: docker_image
        entry: golang:1-alpine sh -c "cd foo && go fmt ./..."
        files: ^foo/
        verbose: true

      - id: docker-go
        name: foo-vet
        language: docker_image
        entry: golang:1-alpine sh -c "cd foo && go vet ./..."
        files: ^foo/
        verbose: true

      - id: docker-go
        name: foo-test
        language: docker_image
        entry: golang:1 sh -c "cd foo && export XDG_CACHE_HOME="/tmp/.cache" && go test ./..."
        files: ^foo/
        verbose: true

In this example we set up to run a formatter, a linter, and testing using a Docker image, for staged files that are located inside the folder foo.

Each task will be executed independently in sequential order.

Git hooks setup

To convert these tasks into git hooks so they are caught by git, run:

pre-commit install

This will inform us that the git hooks have been created.

From now on any commit will trigger these hooks that will in turn execute the defined tasks. If any task fails or a file is modified automatically, the commit will be stopped, saving us from commiting non-ready code to the repository.

If you're using dark mode, do you like the code blocks's theme? I have it available for VS Code, feel free to check it.