Skip to main content

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 채널 생성

  1. https://smee.io/new에 접속합니다.
  2. 자동으로 고유한 채널 URL이 생성됩니다. (예: https://smee.io/AbCdEfGhIjKlMn)
  3. 이 URL을 복사해 둡니다. GitHub Webhook의 Payload URL과 .env 파일의 SMEE_URL에 동일한 값을 사용합니다.

참고: git-catcher init 명령을 사용하면 브라우저에서 자동으로 Smee.io를 열어줍니다.

3. GitHub Repository Webhook 추가

  1. GitHub 리포지토리 페이지에서 SettingsWebhooksAdd webhook을 클릭합니다.
  2. 아래와 같이 설정합니다:
항목
Payload URL Smee.io 채널 URL (예: https://smee.io/AbCdEfGhIjKlMn)
Content type application/json
Secret .envWEBHOOK_SECRET과 동일한 값
Which events? "Just the push event" 선택
Active 체크
  1. 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 .envWEBHOOK_SECRET과 동일한 값 서버-GitHub 간 페이로드 위변조 방지용 공유 키

2) 권한 및 이벤트 구독

생성 화면 하단에서 다음을 설정합니다:

  • Repository PermissionsContents: Read-only 이상으로 설정 (코드 변경 감지에 필요)
  • Subscribe to eventsPush 체크 (코드 push 시에만 webhook 발생)

3) 계정에 앱 설치

이 단계가 가장 중요합니다. 앱을 생성만 하면 webhook이 동작하지 않으며, 반드시 계정에 설치해야 합니다.

  1. 생성된 앱 페이지에서 Install App 메뉴를 클릭합니다.
  2. 본인 계정을 선택하고 All repositories를 선택합니다.
  3. 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 fetchgit checkoutgit pull → post-pull 명령을 순차 실행합니다.

시작 알림

NOTIFY_ON_START=true로 설정하면 git-catcher 시작 시 Slack에 알림을 전송합니다. 알림에는 다음 정보가 포함됩니다:

  • 저장소명
  • 허용 브랜치 목록
  • 호스트명
  • 외부 IP 주소
  • 시작 시각 (UTC)

CLI 명령어

명령어 설명
git-catcher init Interactive 초기 설정 (.envdocker-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 명령으로 대화형 질문에 답하면 .envdocker-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) 포맷의 가독성 높은 콘솔 출력

동작 확인

  1. Git Catcher를 실행합니다:

    python run.py
    
  2. SSE 스트림 연결 성공 로그가 출력되면 연결 성공입니다.

  3. NOTIFY_ON_START=true로 설정했다면 Slack에 시작 알림이 전송됩니다.

  4. 허용된 브랜치에 커밋을 push합니다:

    git add .
    git commit -m "test webhook"
    git push origin main
    
  5. Git Catcher 터미널에서 다음 로그가 순서대로 출력되는지 확인합니다:

    • Push 감지: [main] test webhook
    • git fetchgit checkoutgit pull 완료
    • POST_PULL_COMMAND 실행 (설정 시)
    • Slack 알림 전송 (설정 시)

설정에 문제가 있으면 GitHub Webhook 페이지의 Recent Deliveries 탭에서 전송 상태를 확인할 수 있습니다.

테스트

pytest tests/ -v

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

git_catcher-0.3.0.tar.gz (25.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

git_catcher-0.3.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

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

Hashes for git_catcher-0.3.0.tar.gz
Algorithm Hash digest
SHA256 49d25f7aa058bcd9b2e2a3436ef18396503ec94c1b4da590bd67cdfe0d1635d1
MD5 e5eb665518f9c6a1f4b6a029c7506c98
BLAKE2b-256 7d5bdf1a1c03c55c537baee89bf8801729b7bfa30d210ea5d356ffd1c5851aca

See more details on using hashes here.

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

Hashes for git_catcher-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 70f9c6b608ebde424fd6e63c01811ae7e8cb7e227b88f606abfd5d2de8f1b718
MD5 55906ae2dc3bbd6d17b5fa51bce4912e
BLAKE2b-256 e1aa4da3283f2c0caab84e6c318c7316f2f92244c9e7f1ddc4a036b4ef37c544

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page