はじめに
機密情報をコミットしないようにgit-secretsの設定をしようとしたところ、既にprecommit用のNode.jsライブラリhuskyがインストールされていたため、コンフリクトしてgit-secretsの設定ができませんでした。
どっちとも使いたかったので、それぞれ動くように工夫してみました。
2019/07/10 追記
会社の @aki77 さんが、もっと良い方法を見つけてくれたので、
そっちを「方法1」として追記しました!
方法1: husky内でgit-secretsを呼び出す
gitのhooks内では、デフォルトのままhuskyだけが呼ばれるようにしておき、
huskyでのチェック項目の1つとして、git-secretsを呼び出します。
lint-stagedも併用します。
git-secretsをグローバルにインストール
brew update
brew install git-secrets
git secrets --register-aws --global
このあと、プロジェクト内で**git secrets --install
はしないように!**
husky,lint-stagedをプロジェクトにインストール
yarn add --dev husky lint-staged
husky内でgit-secretsを動かすように設定
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"*": [
"git secrets --scan"
],
"*.{js}": [
"eslint --fix",
"git add"
]
}
}
やっている意味はこんな感じ。
- JSだろうが何だろうが、まず全ファイルを
git-secrets
でチェック - それがOKなら、JSファイルだけ
ESLint
でチェック
あとは必要に応じて
js
拡張子のeslint --fix
の部分を変更したり、
js
以外の拡張子のルールを追加したり、
よしなにやっちゃいましょう
方法2: hooksスクリプトを2種類順番に実行
最初に書いてた、自分でスクリプトをマージする方法です。
gitのhooks内で、git-secretsとhuskyを順番に呼び出します。
他のprecommit用ライブラリにも応用できるような汎用的な方法ですが、
git cloneのたびに手動で設定する必要があったり、
いつのまにか設定が壊れちゃう可能性もあるので、今は方法1に移行しました。
git-secretsをグローバルにインストール
brew update
brew install git-secrets
git secrets --register-aws --global
git-secretsをプロジェクトで有効化
cd path/to/dir
git secrets --install
✓ Installed commit-msg hook to .git/hooks/commit-msg
✓ Installed pre-commit hook to .git/hooks/pre-commit
✓ Installed prepare-commit-msg hook to .git/hooks/prepare-commit-msg
git-secretsが作ったhookスクリプトをサブフォルダ作って移動
mkdir .git/hooks/git-secrets
mv \
.git/hooks/commit-msg \
.git/hooks/pre-commit \
.git/hooks/prepare-commit-msg \
.git/hooks/git-secrets/
huskyをプロジェクトにインストール
yarn add --dev husky
huskyが作ったhookスクリプトをサブフォルダ作って移動
mkdir .git/hooks/husky
mv \
.git/hooks/commit-msg \
.git/hooks/pre-commit \
.git/hooks/prepare-commit-msg \
.git/hooks/husky/
git-secretsとhuskyを順番に呼ぶhookスクリプト作成
#!/bin/bash
SCRIPT_NAME=$(basename $0)
SCRIPT_DIR=$(cd $(dirname $0);pwd)
${SCRIPT_DIR}/git-secrets/${SCRIPT_NAME} "$@" && \
${SCRIPT_DIR}/husky/${SCRIPT_NAME} "$@"
exit $?
3ファイル全て上記の内容にしておけばOK
- .git/hooks/commit-msg
- .git/hooks/pre-commit
- .git/hooks/prepare-commit-msg
実行権限の付与
chmod a+x \
.git/hooks/commit-msg \
.git/hooks/pre-commit \
.git/hooks/prepare-commit-msg
これで、コミット時は以下の順番で動いてくれます
- git-secretsでチェック、ダメならエラー終了
- huskyでチェック、ダメならエラー終了
- 両方OKならコミット実行
注意点
git-secretsのhookスクリプトはシンプルなので良いんですけど、 huskyのhookスクリプトはファイル名を変更すると動作しないので注意してください。
最初はサブフォルダ作らずに.git/hooks/commit-msg.husky
みたいに変名して呼ぼうとしてたんですが、失敗しました。
hookスクリプト内でこんな風に「自分のファイル名をそのまんま別プログラムの引数に渡す」仕組みなので、そこが崩れるとおかしくなっちゃうんです。
hookName=`basename "$0"`
# 中略
node_modules/run-node/run-node $scriptPath $hookName "$gitParams"
なので「サブフォルダを切って、その中に同じファイル名で配置」してあげる必要があります。
参考サイト
コミット前に Lint を強制するなら lint-staged が便利
クラウド破産しないように git-secrets を使う
bashスクリプトのおかれているディレクトリの完全なパスを取得したい
Bashの便利な構文だがよく忘れてしまうものの備忘録#$*, $@, "$@" の違い
ではまた〜。