Smee.io 기반 GitHub push webhook 자동 배포 CLI 도구
Project description
Git Catcher
Smee.io SSE proxy를 활용하여 GitHub push webhook을 실시간 수신하고, 허용된 브랜치에 대해 자동으로 git pull 및 사용자 정의 배포 명령을 실행하는 Python CLI 도구입니다.
방화벽/NAT 환경에서도 동작하며, 연결 끊김 시 exponential backoff 기반 자동 재연결을 지원합니다.
설치
pip install -r git_catcher/requirements.txt
의존성
| 패키지 | 용도 |
|---|---|
httpx |
SSE 스트림 HTTP 클라이언트 |
rich |
컬러 콘솔 로깅 |
python-dotenv |
.env 파일 환경변수 로드 |
InquirerPy |
Interactive CLI 질문 (init 명령어) |
hypothesis |
Property-based testing (개발용) |
pytest |
테스트 프레임워크 (개발용) |
빠른 시작
1. Interactive 초기 설정 (권장)
python -m git_catcher.main init
또는 간편 실행:
python run.py init
대화형 질문에 답하면 .env 파일과 docker-compose.yml이 자동 생성됩니다.
- Smee.io URL 자동 생성 (브라우저 열기)
- Webhook Secret 랜덤 생성
- 저장소 경로, 허용 브랜치 선택
- Slack 알림 설정
2. 수동 설정
.env.example 파일을 복사하여 .env 파일을 생성하고 값을 수정합니다.
cp git_catcher/.env.example git_catcher/.env
| 변수 | 기본값 | 설명 |
|---|---|---|
SMEE_URL |
https://smee.io/YOUR_CHANNEL_ID |
Smee.io 채널 URL (smee.io/new에서 생성) |
WEBHOOK_SECRET |
"" |
GitHub Webhook Secret (미설정 시 서명 검증 스킵) |
REPO_PATH |
/path/to/your/repo |
배포 대상 Git 저장소 로컬 경로 |
ALLOWED_BRANCHES |
main,master |
배포 허용 브랜치 (쉼표 구분) |
POST_PULL_COMMAND |
"" |
git pull 후 실행할 shell 명령어 |
RECONNECT_DELAY |
1 |
초기 재연결 대기 시간 (초) |
MAX_RECONNECT_DELAY |
300 |
최대 재연결 대기 시간 (초) |
ALLOWED_REPOS |
"" |
허용할 저장소 목록 (owner/repo 형식, 쉼표 구분). 빈 문자열이면 REPO_PATH의 git remote origin에서 자동 감지 |
SLACK_WEBHOOK_URL |
"" |
Slack Incoming Webhook URL. 빈 문자열이면 알림 스킵 |
NOTIFY_ON_START |
true |
시작 시 Slack 알림 전송 여부 (true/false) |
POLL_INTERVAL |
0 |
Git 상태 폴링 간격 (초, 0이면 비활성) |
LOG_LEVEL |
INFO |
로그 레벨 (DEBUG, INFO, WARNING, ERROR) |
LOG_FILE |
"" |
로그 파일 경로 (빈 문자열이면 파일 로그 비활성) |
SHOW_ALL_EVENTS |
false |
모든 push 이벤트 로그 출력 (true/false) |
2. Smee.io 채널 생성
- https://smee.io/new에 접속합니다.
- 자동으로 고유한 채널 URL이 생성됩니다. (예:
https://smee.io/AbCdEfGhIjKlMn) - 이 URL을 복사해 둡니다. GitHub Webhook의 Payload URL과
.env파일의SMEE_URL에 동일한 값을 사용합니다.
참고:
git-catcher init명령을 사용하면 브라우저에서 자동으로 Smee.io를 열어줍니다.
3. GitHub Repository Webhook 추가
- GitHub 리포지토리 페이지에서 Settings → Webhooks → Add webhook을 클릭합니다.
- 아래와 같이 설정합니다:
| 항목 | 값 |
|---|---|
| Payload URL | Smee.io 채널 URL (예: https://smee.io/AbCdEfGhIjKlMn) |
| Content type | application/json |
| Secret | .env의 WEBHOOK_SECRET과 동일한 값 |
| Which events? | "Just the push event" 선택 |
| Active | 체크 |
- Add webhook 버튼을 클릭하여 저장합니다.
참고: Secret을 비워두면 Git Catcher도 서명 검증을 스킵합니다. 보안을 위해 Secret 설정을 권장합니다.
3-1. GitHub App으로 전체 저장소 Webhook 수신 (선택)
단일 저장소만 필요하면 위의 3. GitHub Repository Webhook 추가를 사용하세요. 개인 계정의 모든 저장소(향후 생성 포함)에서 push webhook을 수신하려면 GitHub App을 생성합니다.
1) GitHub App 생성
GitHub Settings → Developer settings → GitHub Apps → New GitHub App에서 앱을 생성합니다.
| 항목 | 값 | 설명 |
|---|---|---|
| App name | 임의의 이름 | 예: my-git-catcher |
| Homepage URL | https://github.com/본인계정 |
앱 식별용 필수 항목 |
| Webhook URL | Smee.io 채널 URL | 실제 webhook 데이터를 수신할 목적지 |
| Webhook Secret | .env의 WEBHOOK_SECRET과 동일한 값 |
서버-GitHub 간 페이로드 위변조 방지용 공유 키 |
2) 권한 및 이벤트 구독
생성 화면 하단에서 다음을 설정합니다:
- Repository Permissions → Contents:
Read-only이상으로 설정 (코드 변경 감지에 필요) - Subscribe to events → Push 체크 (코드 push 시에만 webhook 발생)
3) 계정에 앱 설치
이 단계가 가장 중요합니다. 앱을 생성만 하면 webhook이 동작하지 않으며, 반드시 계정에 설치해야 합니다.
- 생성된 앱 페이지에서 Install App 메뉴를 클릭합니다.
- 본인 계정을 선택하고 All repositories를 선택합니다.
- Install 버튼을 클릭합니다.
All repositories를 선택하면 현재 존재하는 저장소뿐 아니라, 향후 생성되는 모든 저장소에도 자동으로 webhook이 적용됩니다.
4) 보안 및 검증
| 항목 | 설명 |
|---|---|
Private Key (.pem) |
앱 설정 페이지 하단에서 생성. 서버에서 GitHub API를 호출할 때 인증에 사용 |
| Recent Deliveries | 앱 설정 → Advanced 탭에서 전송된 webhook 페이로드 확인 및 Redeliver로 재전송 테스트 가능 |
4. .env 예시
SMEE_URL은 Smee.io에서 생성한 채널 URL, WEBHOOK_SECRET은 GitHub Webhook에서 입력한 Secret과 반드시 동일해야 합니다.
SMEE_URL=https://smee.io/AbCdEfGhIjKlMn
WEBHOOK_SECRET=your-webhook-secret-here
REPO_PATH=/path/to/your/repo
ALLOWED_BRANCHES=main,master
POST_PULL_COMMAND=
ALLOWED_REPOS=
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxx
NOTIFY_ON_START=true
POLL_INTERVAL=0
LOG_LEVEL=INFO
LOG_FILE=
SHOW_ALL_EVENTS=false
각 변수의 상세 설명은 환경변수 테이블을 참고하세요.
실행
기본 실행
# 방법 1: 모듈로 실행
python -m git_catcher.main
# 방법 2: 간편 실행 (권장)
python run.py
실행하면 Smee.io SSE 스트림에 연결되어 GitHub push 이벤트를 대기합니다. 허용된 브랜치에 push가 감지되면 자동으로 git fetch → git checkout → git pull → post-pull 명령을 순차 실행합니다.
시작 알림
NOTIFY_ON_START=true로 설정하면 git-catcher 시작 시 Slack에 알림을 전송합니다. 알림에는 다음 정보가 포함됩니다:
- 저장소명
- 허용 브랜치 목록
- 호스트명
- 외부 IP 주소
- 시작 시각 (UTC)
CLI 명령어
| 명령어 | 설명 |
|---|---|
git-catcher init |
Interactive 초기 설정 (.env 및 docker-compose.yml 생성) |
git-catcher run |
git-catcher 실행 (기본 동작) |
CLI 옵션 (run 명령어)
| 옵션 | 설명 |
|---|---|
-v |
git_catcher 모듈만 DEBUG 로그 출력 |
-vv |
전체 모듈 DEBUG 로그 출력 |
-vvvv |
raw webhook 페이로드까지 출력 |
--show-all-events |
모든 push 이벤트 로그 출력 (배포는 여전히 필터링 적용) |
--log-file PATH |
로그 파일 경로 (설정 시 파일에도 DEBUG 로그 기록) |
--log-level LEVEL |
로그 레벨 (DEBUG, INFO, WARNING, ERROR) |
# 기본 실행
python run.py
# git_catcher 모듈 DEBUG + 로그 파일 기록
python run.py -v --log-file deploy.log
# 모든 push 이벤트 확인 + 전체 DEBUG
python run.py -vv --show-all-events
# Interactive 초기 설정
python run.py init
주요 기능
- Interactive 초기 설정:
git-catcher init명령으로 대화형 질문에 답하면.env및docker-compose.yml자동 생성 - 간편 실행:
python run.py로 빠르게 실행 - 시작 알림:
NOTIFY_ON_START=true설정 시 Slack에 시작 알림 전송 (저장소, 브랜치, 호스트, IP 정보 포함) - 저장소 자동 감지:
ALLOWED_REPOS미설정 시REPO_PATH의 git remote origin URL에서owner/repo를 자동 추출 - Slack 배포 알림:
SLACK_WEBHOOK_URL설정 시 배포 성공/실패를 Slack 채널에 알림 - SSE 재연결 복구:
Last-Event-ID기반으로 연결 끊김 시 마지막 수신 이벤트 이후부터 재수신 - Rich 콘솔 로깅: 컬러 + 타임스탬프(시:분:초.ms) 포맷의 가독성 높은 콘솔 출력
동작 확인
-
Git Catcher를 실행합니다:
python run.py -
SSE 스트림 연결 성공로그가 출력되면 연결 성공입니다. -
NOTIFY_ON_START=true로 설정했다면 Slack에 시작 알림이 전송됩니다. -
허용된 브랜치에 커밋을 push합니다:
git add . git commit -m "test webhook" git push origin main
-
Git Catcher 터미널에서 다음 로그가 순서대로 출력되는지 확인합니다:
- Push 감지:
[main] test webhook git fetch→git checkout→git pull완료POST_PULL_COMMAND실행 (설정 시)- Slack 알림 전송 (설정 시)
- Push 감지:
설정에 문제가 있으면 GitHub Webhook 페이지의 Recent Deliveries 탭에서 전송 상태를 확인할 수 있습니다.
테스트
pytest tests/ -v
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file git_catcher-0.3.0.tar.gz.
File metadata
- Download URL: git_catcher-0.3.0.tar.gz
- Upload date:
- Size: 25.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49d25f7aa058bcd9b2e2a3436ef18396503ec94c1b4da590bd67cdfe0d1635d1
|
|
| MD5 |
e5eb665518f9c6a1f4b6a029c7506c98
|
|
| BLAKE2b-256 |
7d5bdf1a1c03c55c537baee89bf8801729b7bfa30d210ea5d356ffd1c5851aca
|
File details
Details for the file git_catcher-0.3.0-py3-none-any.whl.
File metadata
- Download URL: git_catcher-0.3.0-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70f9c6b608ebde424fd6e63c01811ae7e8cb7e227b88f606abfd5d2de8f1b718
|
|
| MD5 |
55906ae2dc3bbd6d17b5fa51bce4912e
|
|
| BLAKE2b-256 |
e1aa4da3283f2c0caab84e6c318c7316f2f92244c9e7f1ddc4a036b4ef37c544
|