Skip to content

Instantly share code, notes, and snippets.

@CITguy
Last active October 19, 2022 07:00
Show Gist options
  • Save CITguy/e8cecbbb7408a93f28c1cbaccaec6765 to your computer and use it in GitHub Desktop.
Save CITguy/e8cecbbb7408a93f28c1cbaccaec6765 to your computer and use it in GitHub Desktop.
Automatic Git Hook Configuration for Node-based projects

Automatic Git Hook Installation for Node workflow

NOTE: This setup assumes that your project is for a shared NPM package and your workflow has a start script defined in package.json.

1. Git Hooks Directory

Recommendation: git-hooks/

Since git ignores the .git/ directory, you'll need to create a separate directory to house your version-controlled hooks. I'd recommend git-hooks/ to make its purpose obvious. Whatever name you give your hooks directory, you'll need to make sure that the scripts/setup-git-hooks.sh script uses the same name.

2. Shell Scripts

The following shell scripts will allow you to set/revert hooksPath git config for the current project (won't affect other projects).

2.1 Setup Script

NOTE: make sure that the hooksPath value points to the directory created in the previous step.

scripts/setup-git-hooks.sh

#!/bin/sh

# See revert-git-hooks.sh to revert actions in this script

if [ ! $CI ] # don't run in CI environment
then
  echo "Setting git-hooks/ as the project git hooksPath..."
  git config core.hooksPath git-hooks
  echo "DONE"
fi

2.2 Revert Script

This script is optional, but recommended to provide an easy way to reset hooksPath configuration for the project. This may be useful in cases where you may need to temporarily turn off the git hooks for debugging or edge cases.

scripts/revert-git-hooks.sh

#!/bin/sh

# Revert actions performed in setup-git-hooks.sh

if [ ! $CI ] # don't run in CI environment
then
  echo "Reverting project git hooksPath..."
  git config --unset core.hooksPath
  echo "DONE"
fi

3. Package Script

3.1 Within an Application

If you're configuring hooks for an application (not an NPM package/library), you may be able to get away with using preinstall or postinstall, because the only users that will need it are the project devs.

In package.json, add or edit the preinstall script to include the following:

{
  "private": true,
   ...
   "scripts": {
       ...
       "preinstall": "scripts/setup-git-hooks.sh & ...",
       ...
   },
   ...
}

3.2 Within a Library

If your project ships a shareable library to NPM, you'll want to avoid using preinstall and postinstall, because NPM/Yarn will attempt to run the setup script in the consuming dev's project. If the project doesn't have a script at the same path as defined in package.json, it'll fail and prevent installation of project dependencies.

Given that most npm library workflows probably define a start script, we can add our setup to the prestart task. When a dev runs npm start/yarn start, the script automatically configures git hooks for them (with console output to inform the dev about what has happened).

In package.json, add or edit the prestart script to include the following:

{
   ...
   "scripts": {
       ...
       "prestart": "scripts/setup-git-hooks.sh & ...",
       ...
   },
   ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment