A Strategy for Enforcing Formatting with Your Build Server

Now that we've learned to use clang-format and created style rules for our project, we need to make sure we're enforcing clang-format usage.

In an optimal flow, we would enforce formatting before allowing changes to be checked in. A common strategy would be to enforce formatting using a git commit hook. However, I have two problems with enforcing formatting with a git hook.

First, it can be a major disruption to the development flow. I don't necessarily want my code to be auto-formatted whenever I commit, as I may want to go back and disable clang-format around some sections of specifically formatted code. I also don't want commits to be rejected while I'm initially working through changes and testing for functionality.

Second, the use of git hooks requires users to install the hooks on their end. It's hard to fully enforce that flow, especially since you're relying on developers to remember that hooks need to be installed.

Instead, I've decided to take it out of the developer's hands and enforce it using my build server. By combining Jenkins with GitHub protected branches and status checks, we can ensure that all changes are checked for formatting before they are merged into master.

When a continuous integration build is triggered (due to submitting a pull request or by committing a new change to a monitored branch), we run a format step as part of the build pipeline. The format step uses the clang-format-patch wrapper script from the format repository. After the build and test stages complete, we use the clang-format-patch script and check for the existence of a patch file. If there are formatting changes needed, the build will fail and the patch file will be archived for the developer to reference.

The format build stage also reports in to GitHub using its own status string. This allows us to monitor pull requests and see which stage of the CI build failed and to block merges until formatting is acceptable. If you are interested in reporting a specific formating status for your own projects, please refer to my reportFormatStatus function in the jenkins-pipeline-lib.

I have been using this flow on my managed projects for the past few months and have found that it is a great middle ground between enforcing formatting and letting developers keep their own flow.

Further Reading