[5주차] GitHub Hooks에 대한 이해
이 문서는 [월간-CS][24년 4월] React, Next 배포와 배포 자동화 A부터 Z를 위해서 작성된 문서입니다. 이 문서에는 그 어떤 저작권이 없으며, 편하게 참고 및 사용하셔도 됩니다.
개요
본 문서에서는 코드 형상 관리 툴인 Git Hooks를 이해하고 이를 통해 Git Hooks를 통한 다양한 워크로드를 구성하기 위한 최소한의 지식을 담고 있습니다.
Git Hooks란?
Git Hooks는 어떤 이벤트가 생겼을 때, 자동으로 특정 스크립트를 실행하도록 하는 기능입니다.
Git Hooks는 일반적으로 .git/hooks 디렉토리에 저장합니다.
실행할 수 있는 스크립트를 확장자 없이 .git/hooks 디렉토리에 넣으면 Hook Script가 실행됩니다.
일반적으로 스크립트는 Shell/Perl Script로 작성합니다.
하지만 실행할 수만 있으면 Ruby, Python 같은 익숙한 언어로 만들어도 됩니다.
이식성을 고민해보자
Ruby, Python, JavaScript, TypeScript 등의 고수준 언어는 다양한 실행환경에 모두 준비되어 있지 않습니다.
또한 최신 문법일수록 다양한 버전에서 지원하지 않을 수 있습니다.이러한 부분들을 고려해서 여러 운영체제에서 일관되게 실행할 수 있는 스크립트라면 “이식성이 좋다”라고 말할 수 있을 것입니다.
Git Hooks 샘플
.git/hooks에는 Git에서 기본으로 제공하는 Shell/Perl Script 예제들이 포함되어 있습니다.
sample 확장자를 제거하면 바로 Git Hooks로서 기능하게 됩니다.
VSC에서 .git/** 폴더 보는 법
Ctrl + , 을 입력한 이후에 files:exclude를 검색한다.
출력된 리스트 중에 **/.git을 제거한다.
Git Hooks의 종류
Git Hooks는 크게 2가지로 분류되지만, 만든 정책이 반드시 강제되게 하려면 Server-side Hooks를 사용해야 한다.
Client-side Hooks
Commit Workflows Hooks (👍)
커밋과 관련된 워크플로우 훅스
pre-commit → prepare-commit-msg → commit-msg → post-commitEmail Workflows Hooks (😒)
이메일과 관련된 워크플로우 훅스
applypatch-msg → pre-appypatch → post-appypatch
Other Hooks (👍)
pre-rebase, pre-write, post-merge, pre-push, pre-auto-gc
Server-side Hooks
Push 전후로 발생하는 워크플로우 훅스
pre-receive → update → post-receive
(Linux 상식) 표준입력, 출력, 에러?
이 세 개념은 프로세스 간의 통신에서 사용되는 개념입니다.
프로세스란 실행 중인 프로그램을 일컫는 단어입니다.
따라서 프로세스 간 통신은 실행 중인 여러 프로그램이 메세지를 주고받는 것을 의미할 것입니다.
일반적으로 약어를 통해서 표현하고 있으며 STDIN, OUT, ERR로 표기하고 있습니다.
표준입력(STDIN, Standard Input)
키보드나 다른 프로세스의 출력을 읽어들이는 장치
일반적으로 File Descriptor 0을 사용하고 있습니다.
표준출력(STDOUT, Standard Output)
프로그램이 결과를 출력하는 기본 장치
보통은 콘솔 화면에 출력하지만, 리디렉션을 통해서 파일 등으로 출력할 수 있습니다.일반적으로 File Descriptor 1을 사용하고 있습니다.
표준에러(STDERR, Standard Error)
프로그램이 오류 메세지나 디버그 정보 등을 출력하는데 사용하는 장치
표준 출력과는 별도로 오류 메세지를 따로 처리할 수 있게 해줍니다.일반적으로 File Descriptor 2를 사용하고 있습니다.
(Linux 상식) 시그널 코드
프로세스는 프로세서에 의해서 처리됩니다.
프로세스 : 실행 중인 프로그램
프로세서 : CPU 등의 중앙 처리 장치
하지만 특정한 신호가 주어지면 프로세서는 신호에 맞는 특정한 행동을 처리하게 설계되어 있습니다.
예를 들어 2번, SIGINT 신호가 주어지면, 프로세서는 프로세스를 종료하거나 중단하게 됩니다.
(Node.js) 시그널 코드 예제
이해를 돕기 위해서 Node.js에서 실행 가능한 예제를 포함하였습니다. (작성일 시점 Node.js 20.11.0 버전에서 성공적으로 실행되었습니다.)
작업 경로에 sample.js 파일을 만들고 아래 파일을 붙여넣기 해주세요. 이후 node sample.js를 통해서 실행하고 Ctrl + C를 누르면 3초 후에 스크립트가 종료되는 것을 알 수 있습니다.
process.exit을 주석 처리하면, 실행 중인 터미널을 닫기 전까지 계속해서 “Process is running...”이 터미널에 출력됩니다.
function getCurrDatetime() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0'); // 시간을 두 자리로 만들기
const minutes = String(now.getMinutes()).padStart(2, '0'); // 분을 두 자리로 만들기
const seconds = String(now.getSeconds()).padStart(2, '0'); // 초를 두 자리로 만들기
const milliseconds = String(now.getMilliseconds()).padStart(3, '0')[0]; // 밀리초를 세 자리로 만들기
return `${hours}:${minutes}:${seconds}.${milliseconds}`;
}
console.log(getCurrDatetime(), "SIGINT handler registered. Press Ctrl+C to trigger.");
process.on("SIGINT", () => {
console.log(getCurrDatetime(), "SIGINT received");
setTimeout(() => {
console.log(getCurrDatetime(), "SIGINT executed")
process.exit(0)
}, 3_000)
});
setInterval(() => {
console.log(getCurrDatetime(), "Process is running...");
}, 1_000);
실무에서 보는 시그널 코드 활용 사례
[월간-CS][24년 4월] React, Next 배포와 배포 자동화 A부터 [2주차] GitHub Action 환경에서의 AWS ELB, EC2 배포 설정 및 배포 자동화 (Next SSR) - Console # 컴퓨팅 리소스에 서버 배포하기 (수동) - 7 PM2를 활용하여 서버를 데몬 프로그램으로 실행하기 에서 저희는 터미널을 닫은 이후에도 서버를 키기 위해서 PM2를 사용하였습니다.
PM2는 프로세스 프로세스 관리 툴로서, 프로세스에 이름을 부여하고 터미널이 닫힌 이후에도 실행되도록 보장해주는 프로그램입니다.
하지만 PM2로 Next 서버를 재시작하게 되면 일시적으로 서버를 접속할 수 없게 됩니다.
이를 해결하기 위한 재실행 가이드가PM2 (Docs) | PM2 Graceful Start/Shutdown # Explanation: Signals flow 문서에 포함되어 있습니다. 여기서는 PM2에서는 SIGINT, SIGKILL 등으로 연결되어 있으며 임의로 다른 신호로 대체할 수 있다고 나와있습니다.
실제로 LINE Engineering (Blog) | PM2를 활용한 Node.js 무중단 서비스하기에서도 이러한 내용이 다루어지고 있습니다. 실습을 원하신다면 PM2로 서버를 가동하신 다음에 아래 명령어를 입력하고 사이트를 새로고침 해보시면 됩니다.
재시작 과정에서 일정 시간 동안 Next.js 서버에 접속되지 않을 것입니다.
pm2 restart <APPLICATION_NAME>