Luciano Serruya Aloisi

Git hooks with husky on a monorepo

Let's suppose your monorepo consist of a frontend directory and a api directory. If you want to only execute some task on pre-commit when files on the frontend app change, this should be your pre-commit script

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

DID_FRONTEND_CHANGE=$(git diff --cached --name-status | grep 'frontend/' || true)

if [ "$DID_FRONTEND_CHANGE" ]; then
  # DO SOMETHING IN HERE
fi

My use case was updating the version of a React app (using npm version), so I also needed a custom script to get the next version

const exec = require('child_process').exec;

const execute = (command) => {
  return new Promise((resolve, reject) => {
    const child = exec(command, (err, stdout, stderr) => {
      if (err != null || typeof stderr != 'string') {
        reject(err);
      } else {
        resolve(stdout);
      }
    });
  });
};

(async () => {
  const getBranchNameCommand = `git rev-parse --abbrev-ref HEAD`;
  const getCommitHashCommand = `git rev-parse --short HEAD`;

  const response = await execute(`echo "$(${getBranchNameCommand})-$(${getCommitHashCommand})" | head -1`);

  const currentVersion = require('../package.json').version;
  const base = currentVersion.split('-').shift();

  const version = `${base}-${response.replace('/', '-')}`;

  process.stdout.write(version);
})();

Hope you liked it!

🐦 @LucianoSerruya

📧 lucianoserruya (at) gmail (dot) com