📑 오류기록

[husky] Checking errors when build projectstdin is not a tty

Po_tta_tt0 2023. 6. 9. 13:52
반응형

아주 애정이 깊은 Stackticon 프로젝트에서 발생한 에러다. 이슈 해결을 위해 로컬에서 작업을 하고, push하려는데 발생했던 문제다.
husky 관련 작업을 하루가 진행했기 때문에, 이 글의 목표는 잘 모르던 husky에 대한 이해와 함께 에러 해결 방법을 공유하기 위함이 될 것 같다.
husky에 관련된 내용은 상단에, 에러 관련 내용은 하단에 작성할 예정이니 에러 해결 방법만 슥 보고 싶다면 아래로 가셔서 빠르게 해결 방법을 보는 것도 시간 절약에 도움이 될 것 같다! 👊😆✨

husky는 왜 쓰는 걸까?: 시스템으로 규칙 만들기

🐇: 우리 진짜 열심히 하자! 커밋 메세지 규칙은~ 블라블라
🦎: 너무 좋아!! 그러니까... feature, fix, chore ... style... test... : XXX
🐈: 첫 글자는 대문자로 쓰고~

어쩌고저쩌고

+3개월 후
🐇,🦎,🐈: 커밋 규칙 뭐더라

어느 순간 정책을 지키지 않은 메세지들이 올라와 있다.

사람이 규칙을 지키고, 습관을 형성하기 위해서는 넛지를 통해 자극하거나(무의식적인 자극), 의식적인 뇌를 사용해야 할 경우(커밋 메세지) 정책을 강제하는 것이 좋다.
이 '정책을 강제하는 것'을 돕는 것이 husky다.

사실...

비단 husky만 '정책을 강제'하지는 않는다.
Git Hooks를 이용해 정책을 강제할 수 있다.
이벤트 발생 시 특정 스크립트를 실행하게 함으로써
<클라이언트>

  • 테스트 코드 점검
  • 코드 스타일 검사
  • commit 메세지 자동으로 생성
  • commit된 것을 알림
  • commit이 유효한지 확인
  • master로 직접 push 방지
    등...

<서버>

  • push 권한 제어
  • push된 것을 알림
    등...

을 할 수 있다.

Git hook으로도 할 수 있는데 왜 굳이 Husky🐺?

강아지가 있어서~🐺는 당연히 아니다

Git Hooks의 특징을 조금 더 살펴보자.
Git Hooks는 .git 내부에 저장되는데. .git은 버전 관리 대상이 아니다. 따라서 .git 내부에 작성한 Git Hooks를 공유하기 위해서는, 새롭게 내용을 CRUD할 때마다 팀원들을 불러서 공유해야 한다.

이런...

template 폴더를 만들어 공유할 내용을 작성한 후, 프로젝트 clone시 template 폴더를 경로로 설정하면 된다.
단점으로는, clone 시 --template 옵션을 빠뜨리는 경우 git 내부에 hooks을 적용할 수 없다.

😐: 조금만 신경쓴다면, 뭐, 나쁘지 않네요

이번에 오픈 소스를 약간 손대봤는데(아아주 약간), commit 규정을 지키지 않아서 커밋을 실패했었다.
작은 팀에서 template를 공유하고 으쌰으쌰 하면 이 방법도 나쁘지 않을 것 같지만,
만약 오픈 소스라면? --template 없이 그냥 clone만 했던 내가, 커밋 규정에 맞지 않게 커밋을 작성했다면?!?!

그래서 husky

프로그래머가 git hooks를 사용하지 않을 확률이 다분하다. 위에서 말한 예시처럼 오픈소스라면 더더욱!

어떻게 사용할까?

husky 설치
Yarn2

yarn add husky --dev
yarn add pinst --dev # ONLY if your package is not private

npm

npm install husky --save-dev

Git hooks 활성화
Yarn2

yarn husky install

npm

npx husky install

설치 후 Git hook 자동으로 활성화하기
yarn

{
  "private": true, // ← your package is private, you only need postinstall
  "scripts": {
    "postinstall": "husky install"
  }
}

npm

npm pkg set scripts.prepare="husky install"
{
  "scripts": {
    "prepare": "husky install" 
  }
}

뭐가 문제였을까?

commit 시에는 문제가 없고, push 시에만 문제가 발생했으니
.husky 내부에 있는 pre-push만 보자.

pre-push

#!/usr/bin/env sh

protected_branch='main'
policy='[Policy] DO NOT PUSH it directly to '$protected_branch' branch'

current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

push_command=$(ps -ocommand= -p $PPID)

is_destructive='force|delete|\-f'

will_remove_protected_branch=':'$protected_branch

do_exit(){
  echo $policy
  exit 1
}

if [[ $push_command =~ $is_destructive ]] && [ $current_branch = $protected_branch ]; then
  do_exit
fi

if [[ $push_command =~ $is_destructive ]] && [[ $push_command =~ $protected_branch ]]; then
  do_exit
fi

if [[ $push_command =~ $will_remove_protected_branch ]]; then
  do_exit
fi

unset do_exit


# check if there is an error when build project
echo "[husky] Checking errors when build project"
yarn build

push 시 에러

[husky] Checking errors when build projectstdin is not a tty

공식문서를 보자.

Windows에서 Yarn을 GIt Bash와 함께 사용할 때 Git hook가 실패할 수 있다.

Create .husky/common.sh:

command_exists () {
  command -v "$1" >/dev/null 2>&1
}

# Workaround for Windows 10, Git Bash and Yarn
if command_exists winpty && test -t 1; then
  exec < /dev/tty
fi

Source it in in places where Yarn is used to run commands:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
. "$(dirname -- "$0")/common.sh"

yarn ...

 

그래서 어떻게 해결했나?

.husky 내부에 common.sh 파일을 생성했다.

command_exists () {
  command -v "$1" >/dev/null 2>&1
}

# Workaround for Windows 10, Git Bash and Yarn
if command_exists winpty && test -t 1; then
  exec < /dev/tty
fi

pre-push 상단에

#!/usr/bin/env sh

. "$(dirname -- "$0")/common.sh" # 이 부분!

을 추가했다.

사실,

  1. . "$(dirname -- "$0")/common.sh"가 아니라 . "$(dirname -- "$0")/common.sh"이 명령어만 추가했는데도 동작하는 이유를 잘 모르겠다.
  2. pre-commit.sh에는 . "$(dirname -- "$0")/_/husky.sh"만 있어도 잘 동작한다.

pre-push는 Remote 이름과 주소를 넘겨주고 stdin을 통해 리스트를 받아와야 해서 그런건가... 불투명한 궁금증만 있다.

알려주세요 😥💦

 

📛 issue

Mac에서는 안된다고 합니다!!

관련 내용 추가해놓겠습니다!

반응형