I have been playing around with a neat tool called husky for my TypeScript repositories. It allows you to create Git hooks that you could subscribe to. I use it as part of my development tools. I use husky, alongside commitlint, to lint commit messages so that they are guaranteed to adhere to the Conventional Commits standard. I have been discovering some interesting use cases for it like running the code linter on staged files using lint-staged.
pre-push hook which is conceptually the same with the current version of husky today.
pre-push hook is triggered, husky executes a
git diff HEAD --quiet && npm test command. The
git diff command is used to check whether there are local uncommitted changes in the repository. It silently exits with an exit code of
1 if there are changes. Thus, the
npm test command only runs when there are no local uncommitted changes.
When there are local uncommitted changes in the repository, husky throws an ambiguous
error: failed to push some refs exception message. This can definitely baffle a developer. There should be a better way to directly convey the error message.
The solution can be to tinker with the bash scripts individually provided by Husky. Edit the
.husky/pre-push file, like so:
"$(dirname -- "$0")/_/husky.sh" if git diff HEAD --quiet; then npm run test else echo "Cannot run pre-push tests due to local uncommitted changes" exit 1 fi.
In this bash script, the same
git diff command is ran and returns an exit code of
0 (no difference) or
1 (with difference). If there are differences, the tests are ran. Otherwise, a friendly error message is presented and exits.
Running tests before pushing to a remote repository is a cool idea indeed. It is worth noting that this approach is only feasible when your tests can be run locally and fast. If you are going to run a lot of tests that take a while, you should better delegate that task to your continuous integration pipeline instead.
Special thanks to Kacper Wdowik for writing the article that served as inspiration for this one. Cheers! 🎉