git-catcher 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- git_catcher-0.3.0/PKG-INFO +267 -0
- git_catcher-0.3.0/README.md +252 -0
- git_catcher-0.3.0/git_catcher/__init__.py +2 -0
- git_catcher-0.3.0/git_catcher/cli/__init__.py +1 -0
- git_catcher-0.3.0/git_catcher/cli/init.py +325 -0
- git_catcher-0.3.0/git_catcher/config.py +101 -0
- git_catcher-0.3.0/git_catcher/deployer.py +97 -0
- git_catcher-0.3.0/git_catcher/main.py +354 -0
- git_catcher-0.3.0/git_catcher/smee_client.py +188 -0
- git_catcher-0.3.0/git_catcher.egg-info/PKG-INFO +267 -0
- git_catcher-0.3.0/git_catcher.egg-info/SOURCES.txt +21 -0
- git_catcher-0.3.0/git_catcher.egg-info/dependency_links.txt +1 -0
- git_catcher-0.3.0/git_catcher.egg-info/entry_points.txt +2 -0
- git_catcher-0.3.0/git_catcher.egg-info/requires.txt +8 -0
- git_catcher-0.3.0/git_catcher.egg-info/top_level.txt +1 -0
- git_catcher-0.3.0/pyproject.toml +32 -0
- git_catcher-0.3.0/setup.cfg +4 -0
- git_catcher-0.3.0/tests/test_backoff.py +35 -0
- git_catcher-0.3.0/tests/test_config.py +155 -0
- git_catcher-0.3.0/tests/test_deployer.py +182 -0
- git_catcher-0.3.0/tests/test_parse_push_event.py +84 -0
- git_catcher-0.3.0/tests/test_sse_handler.py +102 -0
- git_catcher-0.3.0/tests/test_verify_signature.py +90 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: git-catcher
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Smee.io 기반 GitHub push webhook 자동 배포 CLI 도구
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: httpx>=0.27.0
|
|
9
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
10
|
+
Requires-Dist: InquirerPy>=0.3.4
|
|
11
|
+
Requires-Dist: rich>=13.0.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: hypothesis>=6.100.0; extra == "dev"
|
|
14
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
15
|
+
|
|
16
|
+
# Git Catcher
|
|
17
|
+
|
|
18
|
+
Smee.io SSE proxy를 활용하여 GitHub push webhook을 실시간 수신하고, 허용된 브랜치에 대해 자동으로 `git pull` 및 사용자 정의 배포 명령을 실행하는 Python CLI 도구입니다.
|
|
19
|
+
|
|
20
|
+
방화벽/NAT 환경에서도 동작하며, 연결 끊김 시 exponential backoff 기반 자동 재연결을 지원합니다.
|
|
21
|
+
|
|
22
|
+
## 설치
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -r git_catcher/requirements.txt
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 의존성
|
|
29
|
+
|
|
30
|
+
| 패키지 | 용도 |
|
|
31
|
+
|--------|------|
|
|
32
|
+
| `httpx` | SSE 스트림 HTTP 클라이언트 |
|
|
33
|
+
| `rich` | 컬러 콘솔 로깅 |
|
|
34
|
+
| `python-dotenv` | `.env` 파일 환경변수 로드 |
|
|
35
|
+
| `InquirerPy` | Interactive CLI 질문 (init 명령어) |
|
|
36
|
+
| `hypothesis` | Property-based testing (개발용) |
|
|
37
|
+
| `pytest` | 테스트 프레임워크 (개발용) |
|
|
38
|
+
|
|
39
|
+
## 빠른 시작
|
|
40
|
+
|
|
41
|
+
### 1. Interactive 초기 설정 (권장)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
python -m git_catcher.main init
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
또는 간편 실행:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
python run.py init
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
대화형 질문에 답하면 `.env` 파일과 `docker-compose.yml`이 자동 생성됩니다.
|
|
54
|
+
|
|
55
|
+
- Smee.io URL 자동 생성 (브라우저 열기)
|
|
56
|
+
- Webhook Secret 랜덤 생성
|
|
57
|
+
- 저장소 경로, 허용 브랜치 선택
|
|
58
|
+
- Slack 알림 설정
|
|
59
|
+
|
|
60
|
+
### 2. 수동 설정
|
|
61
|
+
|
|
62
|
+
`.env.example` 파일을 복사하여 `.env` 파일을 생성하고 값을 수정합니다.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cp git_catcher/.env.example git_catcher/.env
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| 변수 | 기본값 | 설명 |
|
|
69
|
+
|------|--------|------|
|
|
70
|
+
| `SMEE_URL` | `https://smee.io/YOUR_CHANNEL_ID` | Smee.io 채널 URL ([smee.io/new](https://smee.io/new)에서 생성) |
|
|
71
|
+
| `WEBHOOK_SECRET` | `""` | GitHub Webhook Secret (미설정 시 서명 검증 스킵) |
|
|
72
|
+
| `REPO_PATH` | `/path/to/your/repo` | 배포 대상 Git 저장소 로컬 경로 |
|
|
73
|
+
| `ALLOWED_BRANCHES` | `main,master` | 배포 허용 브랜치 (쉼표 구분) |
|
|
74
|
+
| `POST_PULL_COMMAND` | `""` | `git pull` 후 실행할 shell 명령어 |
|
|
75
|
+
| `RECONNECT_DELAY` | `1` | 초기 재연결 대기 시간 (초) |
|
|
76
|
+
| `MAX_RECONNECT_DELAY` | `300` | 최대 재연결 대기 시간 (초) |
|
|
77
|
+
| `ALLOWED_REPOS` | `""` | 허용할 저장소 목록 (`owner/repo` 형식, 쉼표 구분). 빈 문자열이면 `REPO_PATH`의 git remote origin에서 자동 감지 |
|
|
78
|
+
| `SLACK_WEBHOOK_URL` | `""` | Slack Incoming Webhook URL. 빈 문자열이면 알림 스킵 |
|
|
79
|
+
| `NOTIFY_ON_START` | `true` | 시작 시 Slack 알림 전송 여부 (`true`/`false`) |
|
|
80
|
+
| `POLL_INTERVAL` | `0` | Git 상태 폴링 간격 (초, 0이면 비활성) |
|
|
81
|
+
| `LOG_LEVEL` | `INFO` | 로그 레벨 (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
|
82
|
+
| `LOG_FILE` | `""` | 로그 파일 경로 (빈 문자열이면 파일 로그 비활성) |
|
|
83
|
+
| `SHOW_ALL_EVENTS` | `false` | 모든 push 이벤트 로그 출력 (`true`/`false`) |
|
|
84
|
+
|
|
85
|
+
### 2. Smee.io 채널 생성
|
|
86
|
+
|
|
87
|
+
1. [https://smee.io/new](https://smee.io/new)에 접속합니다.
|
|
88
|
+
2. 자동으로 고유한 채널 URL이 생성됩니다. (예: `https://smee.io/AbCdEfGhIjKlMn`)
|
|
89
|
+
3. 이 URL을 복사해 둡니다. GitHub Webhook의 Payload URL과 `.env` 파일의 `SMEE_URL`에 동일한 값을 사용합니다.
|
|
90
|
+
|
|
91
|
+
> **참고:** `git-catcher init` 명령을 사용하면 브라우저에서 자동으로 Smee.io를 열어줍니다.
|
|
92
|
+
|
|
93
|
+
### 3. GitHub Repository Webhook 추가
|
|
94
|
+
|
|
95
|
+
1. GitHub 리포지토리 페이지에서 **Settings** → **Webhooks** → **Add webhook**을 클릭합니다.
|
|
96
|
+
2. 아래와 같이 설정합니다:
|
|
97
|
+
|
|
98
|
+
| 항목 | 값 |
|
|
99
|
+
|------|-----|
|
|
100
|
+
| Payload URL | Smee.io 채널 URL (예: `https://smee.io/AbCdEfGhIjKlMn`) |
|
|
101
|
+
| Content type | `application/json` |
|
|
102
|
+
| Secret | `.env`의 `WEBHOOK_SECRET`과 동일한 값 |
|
|
103
|
+
| Which events? | "Just the push event" 선택 |
|
|
104
|
+
| Active | 체크 |
|
|
105
|
+
|
|
106
|
+
3. **Add webhook** 버튼을 클릭하여 저장합니다.
|
|
107
|
+
|
|
108
|
+
> **참고:** Secret을 비워두면 Git Catcher도 서명 검증을 스킵합니다. 보안을 위해 Secret 설정을 권장합니다.
|
|
109
|
+
|
|
110
|
+
### 3-1. GitHub App으로 전체 저장소 Webhook 수신 (선택)
|
|
111
|
+
|
|
112
|
+
> 단일 저장소만 필요하면 위의 [3. GitHub Repository Webhook 추가](#3-github-repository-webhook-추가)를 사용하세요.
|
|
113
|
+
> 개인 계정의 **모든 저장소**(향후 생성 포함)에서 push webhook을 수신하려면 GitHub App을 생성합니다.
|
|
114
|
+
|
|
115
|
+
#### 1) GitHub App 생성
|
|
116
|
+
|
|
117
|
+
[GitHub Settings → Developer settings → GitHub Apps → New GitHub App](https://github.com/settings/apps/new)에서 앱을 생성합니다.
|
|
118
|
+
|
|
119
|
+
| 항목 | 값 | 설명 |
|
|
120
|
+
|------|-----|------|
|
|
121
|
+
| App name | 임의의 이름 | 예: `my-git-catcher` |
|
|
122
|
+
| Homepage URL | `https://github.com/본인계정` | 앱 식별용 필수 항목 |
|
|
123
|
+
| Webhook URL | Smee.io 채널 URL | 실제 webhook 데이터를 수신할 목적지 |
|
|
124
|
+
| Webhook Secret | `.env`의 `WEBHOOK_SECRET`과 동일한 값 | 서버-GitHub 간 페이로드 위변조 방지용 공유 키 |
|
|
125
|
+
|
|
126
|
+
#### 2) 권한 및 이벤트 구독
|
|
127
|
+
|
|
128
|
+
생성 화면 하단에서 다음을 설정합니다:
|
|
129
|
+
|
|
130
|
+
- **Repository Permissions** → **Contents**: `Read-only` 이상으로 설정 (코드 변경 감지에 필요)
|
|
131
|
+
- **Subscribe to events** → **Push** 체크 (코드 push 시에만 webhook 발생)
|
|
132
|
+
|
|
133
|
+
#### 3) 계정에 앱 설치
|
|
134
|
+
|
|
135
|
+
이 단계가 가장 중요합니다. 앱을 생성만 하면 webhook이 동작하지 않으며, 반드시 계정에 **설치**해야 합니다.
|
|
136
|
+
|
|
137
|
+
1. 생성된 앱 페이지에서 **Install App** 메뉴를 클릭합니다.
|
|
138
|
+
2. 본인 계정을 선택하고 **All repositories**를 선택합니다.
|
|
139
|
+
3. **Install** 버튼을 클릭합니다.
|
|
140
|
+
|
|
141
|
+
> **All repositories**를 선택하면 현재 존재하는 저장소뿐 아니라, 향후 생성되는 모든 저장소에도 자동으로 webhook이 적용됩니다.
|
|
142
|
+
|
|
143
|
+
#### 4) 보안 및 검증
|
|
144
|
+
|
|
145
|
+
| 항목 | 설명 |
|
|
146
|
+
|------|------|
|
|
147
|
+
| Private Key (`.pem`) | 앱 설정 페이지 하단에서 생성. 서버에서 GitHub API를 호출할 때 인증에 사용 |
|
|
148
|
+
| Recent Deliveries | 앱 설정 → **Advanced** 탭에서 전송된 webhook 페이로드 확인 및 **Redeliver**로 재전송 테스트 가능 |
|
|
149
|
+
|
|
150
|
+
### 4. .env 예시
|
|
151
|
+
|
|
152
|
+
`SMEE_URL`은 Smee.io에서 생성한 채널 URL, `WEBHOOK_SECRET`은 GitHub Webhook에서 입력한 Secret과 반드시 동일해야 합니다.
|
|
153
|
+
|
|
154
|
+
```dotenv
|
|
155
|
+
SMEE_URL=https://smee.io/AbCdEfGhIjKlMn
|
|
156
|
+
WEBHOOK_SECRET=your-webhook-secret-here
|
|
157
|
+
REPO_PATH=/path/to/your/repo
|
|
158
|
+
ALLOWED_BRANCHES=main,master
|
|
159
|
+
POST_PULL_COMMAND=
|
|
160
|
+
ALLOWED_REPOS=
|
|
161
|
+
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxx
|
|
162
|
+
NOTIFY_ON_START=true
|
|
163
|
+
POLL_INTERVAL=0
|
|
164
|
+
LOG_LEVEL=INFO
|
|
165
|
+
LOG_FILE=
|
|
166
|
+
SHOW_ALL_EVENTS=false
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
각 변수의 상세 설명은 [환경변수 테이블](#2-수동-설정)을 참고하세요.
|
|
170
|
+
|
|
171
|
+
## 실행
|
|
172
|
+
|
|
173
|
+
### 기본 실행
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# 방법 1: 모듈로 실행
|
|
177
|
+
python -m git_catcher.main
|
|
178
|
+
|
|
179
|
+
# 방법 2: 간편 실행 (권장)
|
|
180
|
+
python run.py
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
실행하면 Smee.io SSE 스트림에 연결되어 GitHub push 이벤트를 대기합니다. 허용된 브랜치에 push가 감지되면 자동으로 `git fetch` → `git checkout` → `git pull` → post-pull 명령을 순차 실행합니다.
|
|
184
|
+
|
|
185
|
+
### 시작 알림
|
|
186
|
+
|
|
187
|
+
`NOTIFY_ON_START=true`로 설정하면 git-catcher 시작 시 Slack에 알림을 전송합니다. 알림에는 다음 정보가 포함됩니다:
|
|
188
|
+
|
|
189
|
+
- 저장소명
|
|
190
|
+
- 허용 브랜치 목록
|
|
191
|
+
- 호스트명
|
|
192
|
+
- 외부 IP 주소
|
|
193
|
+
- 시작 시각 (UTC)
|
|
194
|
+
|
|
195
|
+
### CLI 명령어
|
|
196
|
+
|
|
197
|
+
| 명령어 | 설명 |
|
|
198
|
+
|--------|------|
|
|
199
|
+
| `git-catcher init` | Interactive 초기 설정 (`.env` 및 `docker-compose.yml` 생성) |
|
|
200
|
+
| `git-catcher run` | git-catcher 실행 (기본 동작) |
|
|
201
|
+
|
|
202
|
+
### CLI 옵션 (run 명령어)
|
|
203
|
+
|
|
204
|
+
| 옵션 | 설명 |
|
|
205
|
+
|------|------|
|
|
206
|
+
| `-v` | `git_catcher` 모듈만 DEBUG 로그 출력 |
|
|
207
|
+
| `-vv` | 전체 모듈 DEBUG 로그 출력 |
|
|
208
|
+
| `-vvvv` | raw webhook 페이로드까지 출력 |
|
|
209
|
+
| `--show-all-events` | 모든 push 이벤트 로그 출력 (배포는 여전히 필터링 적용) |
|
|
210
|
+
| `--log-file PATH` | 로그 파일 경로 (설정 시 파일에도 DEBUG 로그 기록) |
|
|
211
|
+
| `--log-level LEVEL` | 로그 레벨 (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# 기본 실행
|
|
215
|
+
python run.py
|
|
216
|
+
|
|
217
|
+
# git_catcher 모듈 DEBUG + 로그 파일 기록
|
|
218
|
+
python run.py -v --log-file deploy.log
|
|
219
|
+
|
|
220
|
+
# 모든 push 이벤트 확인 + 전체 DEBUG
|
|
221
|
+
python run.py -vv --show-all-events
|
|
222
|
+
|
|
223
|
+
# Interactive 초기 설정
|
|
224
|
+
python run.py init
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 주요 기능
|
|
228
|
+
|
|
229
|
+
- **Interactive 초기 설정**: `git-catcher init` 명령으로 대화형 질문에 답하면 `.env` 및 `docker-compose.yml` 자동 생성
|
|
230
|
+
- **간편 실행**: `python run.py`로 빠르게 실행
|
|
231
|
+
- **시작 알림**: `NOTIFY_ON_START=true` 설정 시 Slack에 시작 알림 전송 (저장소, 브랜치, 호스트, IP 정보 포함)
|
|
232
|
+
- **저장소 자동 감지**: `ALLOWED_REPOS` 미설정 시 `REPO_PATH`의 git remote origin URL에서 `owner/repo`를 자동 추출
|
|
233
|
+
- **Slack 배포 알림**: `SLACK_WEBHOOK_URL` 설정 시 배포 성공/실패를 Slack 채널에 알림
|
|
234
|
+
- **SSE 재연결 복구**: `Last-Event-ID` 기반으로 연결 끊김 시 마지막 수신 이벤트 이후부터 재수신
|
|
235
|
+
- **Rich 콘솔 로깅**: 컬러 + 타임스탬프(시:분:초.ms) 포맷의 가독성 높은 콘솔 출력
|
|
236
|
+
|
|
237
|
+
## 동작 확인
|
|
238
|
+
|
|
239
|
+
1. Git Catcher를 [실행](#실행)합니다:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
python run.py
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
2. `SSE 스트림 연결 성공` 로그가 출력되면 연결 성공입니다.
|
|
246
|
+
3. `NOTIFY_ON_START=true`로 설정했다면 Slack에 시작 알림이 전송됩니다.
|
|
247
|
+
4. 허용된 브랜치에 커밋을 push합니다:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
git add .
|
|
251
|
+
git commit -m "test webhook"
|
|
252
|
+
git push origin main
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
5. Git Catcher 터미널에서 다음 로그가 순서대로 출력되는지 확인합니다:
|
|
256
|
+
- Push 감지: `[main] test webhook`
|
|
257
|
+
- `git fetch` → `git checkout` → `git pull` 완료
|
|
258
|
+
- `POST_PULL_COMMAND` 실행 (설정 시)
|
|
259
|
+
- Slack 알림 전송 (설정 시)
|
|
260
|
+
|
|
261
|
+
설정에 문제가 있으면 GitHub Webhook 페이지의 **Recent Deliveries** 탭에서 전송 상태를 확인할 수 있습니다.
|
|
262
|
+
|
|
263
|
+
## 테스트
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
pytest tests/ -v
|
|
267
|
+
```
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Git Catcher
|
|
2
|
+
|
|
3
|
+
Smee.io SSE proxy를 활용하여 GitHub push webhook을 실시간 수신하고, 허용된 브랜치에 대해 자동으로 `git pull` 및 사용자 정의 배포 명령을 실행하는 Python CLI 도구입니다.
|
|
4
|
+
|
|
5
|
+
방화벽/NAT 환경에서도 동작하며, 연결 끊김 시 exponential backoff 기반 자동 재연결을 지원합니다.
|
|
6
|
+
|
|
7
|
+
## 설치
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install -r git_catcher/requirements.txt
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### 의존성
|
|
14
|
+
|
|
15
|
+
| 패키지 | 용도 |
|
|
16
|
+
|--------|------|
|
|
17
|
+
| `httpx` | SSE 스트림 HTTP 클라이언트 |
|
|
18
|
+
| `rich` | 컬러 콘솔 로깅 |
|
|
19
|
+
| `python-dotenv` | `.env` 파일 환경변수 로드 |
|
|
20
|
+
| `InquirerPy` | Interactive CLI 질문 (init 명령어) |
|
|
21
|
+
| `hypothesis` | Property-based testing (개발용) |
|
|
22
|
+
| `pytest` | 테스트 프레임워크 (개발용) |
|
|
23
|
+
|
|
24
|
+
## 빠른 시작
|
|
25
|
+
|
|
26
|
+
### 1. Interactive 초기 설정 (권장)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
python -m git_catcher.main init
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
또는 간편 실행:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python run.py init
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
대화형 질문에 답하면 `.env` 파일과 `docker-compose.yml`이 자동 생성됩니다.
|
|
39
|
+
|
|
40
|
+
- Smee.io URL 자동 생성 (브라우저 열기)
|
|
41
|
+
- Webhook Secret 랜덤 생성
|
|
42
|
+
- 저장소 경로, 허용 브랜치 선택
|
|
43
|
+
- Slack 알림 설정
|
|
44
|
+
|
|
45
|
+
### 2. 수동 설정
|
|
46
|
+
|
|
47
|
+
`.env.example` 파일을 복사하여 `.env` 파일을 생성하고 값을 수정합니다.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cp git_catcher/.env.example git_catcher/.env
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
| 변수 | 기본값 | 설명 |
|
|
54
|
+
|------|--------|------|
|
|
55
|
+
| `SMEE_URL` | `https://smee.io/YOUR_CHANNEL_ID` | Smee.io 채널 URL ([smee.io/new](https://smee.io/new)에서 생성) |
|
|
56
|
+
| `WEBHOOK_SECRET` | `""` | GitHub Webhook Secret (미설정 시 서명 검증 스킵) |
|
|
57
|
+
| `REPO_PATH` | `/path/to/your/repo` | 배포 대상 Git 저장소 로컬 경로 |
|
|
58
|
+
| `ALLOWED_BRANCHES` | `main,master` | 배포 허용 브랜치 (쉼표 구분) |
|
|
59
|
+
| `POST_PULL_COMMAND` | `""` | `git pull` 후 실행할 shell 명령어 |
|
|
60
|
+
| `RECONNECT_DELAY` | `1` | 초기 재연결 대기 시간 (초) |
|
|
61
|
+
| `MAX_RECONNECT_DELAY` | `300` | 최대 재연결 대기 시간 (초) |
|
|
62
|
+
| `ALLOWED_REPOS` | `""` | 허용할 저장소 목록 (`owner/repo` 형식, 쉼표 구분). 빈 문자열이면 `REPO_PATH`의 git remote origin에서 자동 감지 |
|
|
63
|
+
| `SLACK_WEBHOOK_URL` | `""` | Slack Incoming Webhook URL. 빈 문자열이면 알림 스킵 |
|
|
64
|
+
| `NOTIFY_ON_START` | `true` | 시작 시 Slack 알림 전송 여부 (`true`/`false`) |
|
|
65
|
+
| `POLL_INTERVAL` | `0` | Git 상태 폴링 간격 (초, 0이면 비활성) |
|
|
66
|
+
| `LOG_LEVEL` | `INFO` | 로그 레벨 (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
|
67
|
+
| `LOG_FILE` | `""` | 로그 파일 경로 (빈 문자열이면 파일 로그 비활성) |
|
|
68
|
+
| `SHOW_ALL_EVENTS` | `false` | 모든 push 이벤트 로그 출력 (`true`/`false`) |
|
|
69
|
+
|
|
70
|
+
### 2. Smee.io 채널 생성
|
|
71
|
+
|
|
72
|
+
1. [https://smee.io/new](https://smee.io/new)에 접속합니다.
|
|
73
|
+
2. 자동으로 고유한 채널 URL이 생성됩니다. (예: `https://smee.io/AbCdEfGhIjKlMn`)
|
|
74
|
+
3. 이 URL을 복사해 둡니다. GitHub Webhook의 Payload URL과 `.env` 파일의 `SMEE_URL`에 동일한 값을 사용합니다.
|
|
75
|
+
|
|
76
|
+
> **참고:** `git-catcher init` 명령을 사용하면 브라우저에서 자동으로 Smee.io를 열어줍니다.
|
|
77
|
+
|
|
78
|
+
### 3. GitHub Repository Webhook 추가
|
|
79
|
+
|
|
80
|
+
1. GitHub 리포지토리 페이지에서 **Settings** → **Webhooks** → **Add webhook**을 클릭합니다.
|
|
81
|
+
2. 아래와 같이 설정합니다:
|
|
82
|
+
|
|
83
|
+
| 항목 | 값 |
|
|
84
|
+
|------|-----|
|
|
85
|
+
| Payload URL | Smee.io 채널 URL (예: `https://smee.io/AbCdEfGhIjKlMn`) |
|
|
86
|
+
| Content type | `application/json` |
|
|
87
|
+
| Secret | `.env`의 `WEBHOOK_SECRET`과 동일한 값 |
|
|
88
|
+
| Which events? | "Just the push event" 선택 |
|
|
89
|
+
| Active | 체크 |
|
|
90
|
+
|
|
91
|
+
3. **Add webhook** 버튼을 클릭하여 저장합니다.
|
|
92
|
+
|
|
93
|
+
> **참고:** Secret을 비워두면 Git Catcher도 서명 검증을 스킵합니다. 보안을 위해 Secret 설정을 권장합니다.
|
|
94
|
+
|
|
95
|
+
### 3-1. GitHub App으로 전체 저장소 Webhook 수신 (선택)
|
|
96
|
+
|
|
97
|
+
> 단일 저장소만 필요하면 위의 [3. GitHub Repository Webhook 추가](#3-github-repository-webhook-추가)를 사용하세요.
|
|
98
|
+
> 개인 계정의 **모든 저장소**(향후 생성 포함)에서 push webhook을 수신하려면 GitHub App을 생성합니다.
|
|
99
|
+
|
|
100
|
+
#### 1) GitHub App 생성
|
|
101
|
+
|
|
102
|
+
[GitHub Settings → Developer settings → GitHub Apps → New GitHub App](https://github.com/settings/apps/new)에서 앱을 생성합니다.
|
|
103
|
+
|
|
104
|
+
| 항목 | 값 | 설명 |
|
|
105
|
+
|------|-----|------|
|
|
106
|
+
| App name | 임의의 이름 | 예: `my-git-catcher` |
|
|
107
|
+
| Homepage URL | `https://github.com/본인계정` | 앱 식별용 필수 항목 |
|
|
108
|
+
| Webhook URL | Smee.io 채널 URL | 실제 webhook 데이터를 수신할 목적지 |
|
|
109
|
+
| Webhook Secret | `.env`의 `WEBHOOK_SECRET`과 동일한 값 | 서버-GitHub 간 페이로드 위변조 방지용 공유 키 |
|
|
110
|
+
|
|
111
|
+
#### 2) 권한 및 이벤트 구독
|
|
112
|
+
|
|
113
|
+
생성 화면 하단에서 다음을 설정합니다:
|
|
114
|
+
|
|
115
|
+
- **Repository Permissions** → **Contents**: `Read-only` 이상으로 설정 (코드 변경 감지에 필요)
|
|
116
|
+
- **Subscribe to events** → **Push** 체크 (코드 push 시에만 webhook 발생)
|
|
117
|
+
|
|
118
|
+
#### 3) 계정에 앱 설치
|
|
119
|
+
|
|
120
|
+
이 단계가 가장 중요합니다. 앱을 생성만 하면 webhook이 동작하지 않으며, 반드시 계정에 **설치**해야 합니다.
|
|
121
|
+
|
|
122
|
+
1. 생성된 앱 페이지에서 **Install App** 메뉴를 클릭합니다.
|
|
123
|
+
2. 본인 계정을 선택하고 **All repositories**를 선택합니다.
|
|
124
|
+
3. **Install** 버튼을 클릭합니다.
|
|
125
|
+
|
|
126
|
+
> **All repositories**를 선택하면 현재 존재하는 저장소뿐 아니라, 향후 생성되는 모든 저장소에도 자동으로 webhook이 적용됩니다.
|
|
127
|
+
|
|
128
|
+
#### 4) 보안 및 검증
|
|
129
|
+
|
|
130
|
+
| 항목 | 설명 |
|
|
131
|
+
|------|------|
|
|
132
|
+
| Private Key (`.pem`) | 앱 설정 페이지 하단에서 생성. 서버에서 GitHub API를 호출할 때 인증에 사용 |
|
|
133
|
+
| Recent Deliveries | 앱 설정 → **Advanced** 탭에서 전송된 webhook 페이로드 확인 및 **Redeliver**로 재전송 테스트 가능 |
|
|
134
|
+
|
|
135
|
+
### 4. .env 예시
|
|
136
|
+
|
|
137
|
+
`SMEE_URL`은 Smee.io에서 생성한 채널 URL, `WEBHOOK_SECRET`은 GitHub Webhook에서 입력한 Secret과 반드시 동일해야 합니다.
|
|
138
|
+
|
|
139
|
+
```dotenv
|
|
140
|
+
SMEE_URL=https://smee.io/AbCdEfGhIjKlMn
|
|
141
|
+
WEBHOOK_SECRET=your-webhook-secret-here
|
|
142
|
+
REPO_PATH=/path/to/your/repo
|
|
143
|
+
ALLOWED_BRANCHES=main,master
|
|
144
|
+
POST_PULL_COMMAND=
|
|
145
|
+
ALLOWED_REPOS=
|
|
146
|
+
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxx
|
|
147
|
+
NOTIFY_ON_START=true
|
|
148
|
+
POLL_INTERVAL=0
|
|
149
|
+
LOG_LEVEL=INFO
|
|
150
|
+
LOG_FILE=
|
|
151
|
+
SHOW_ALL_EVENTS=false
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
각 변수의 상세 설명은 [환경변수 테이블](#2-수동-설정)을 참고하세요.
|
|
155
|
+
|
|
156
|
+
## 실행
|
|
157
|
+
|
|
158
|
+
### 기본 실행
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# 방법 1: 모듈로 실행
|
|
162
|
+
python -m git_catcher.main
|
|
163
|
+
|
|
164
|
+
# 방법 2: 간편 실행 (권장)
|
|
165
|
+
python run.py
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
실행하면 Smee.io SSE 스트림에 연결되어 GitHub push 이벤트를 대기합니다. 허용된 브랜치에 push가 감지되면 자동으로 `git fetch` → `git checkout` → `git pull` → post-pull 명령을 순차 실행합니다.
|
|
169
|
+
|
|
170
|
+
### 시작 알림
|
|
171
|
+
|
|
172
|
+
`NOTIFY_ON_START=true`로 설정하면 git-catcher 시작 시 Slack에 알림을 전송합니다. 알림에는 다음 정보가 포함됩니다:
|
|
173
|
+
|
|
174
|
+
- 저장소명
|
|
175
|
+
- 허용 브랜치 목록
|
|
176
|
+
- 호스트명
|
|
177
|
+
- 외부 IP 주소
|
|
178
|
+
- 시작 시각 (UTC)
|
|
179
|
+
|
|
180
|
+
### CLI 명령어
|
|
181
|
+
|
|
182
|
+
| 명령어 | 설명 |
|
|
183
|
+
|--------|------|
|
|
184
|
+
| `git-catcher init` | Interactive 초기 설정 (`.env` 및 `docker-compose.yml` 생성) |
|
|
185
|
+
| `git-catcher run` | git-catcher 실행 (기본 동작) |
|
|
186
|
+
|
|
187
|
+
### CLI 옵션 (run 명령어)
|
|
188
|
+
|
|
189
|
+
| 옵션 | 설명 |
|
|
190
|
+
|------|------|
|
|
191
|
+
| `-v` | `git_catcher` 모듈만 DEBUG 로그 출력 |
|
|
192
|
+
| `-vv` | 전체 모듈 DEBUG 로그 출력 |
|
|
193
|
+
| `-vvvv` | raw webhook 페이로드까지 출력 |
|
|
194
|
+
| `--show-all-events` | 모든 push 이벤트 로그 출력 (배포는 여전히 필터링 적용) |
|
|
195
|
+
| `--log-file PATH` | 로그 파일 경로 (설정 시 파일에도 DEBUG 로그 기록) |
|
|
196
|
+
| `--log-level LEVEL` | 로그 레벨 (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# 기본 실행
|
|
200
|
+
python run.py
|
|
201
|
+
|
|
202
|
+
# git_catcher 모듈 DEBUG + 로그 파일 기록
|
|
203
|
+
python run.py -v --log-file deploy.log
|
|
204
|
+
|
|
205
|
+
# 모든 push 이벤트 확인 + 전체 DEBUG
|
|
206
|
+
python run.py -vv --show-all-events
|
|
207
|
+
|
|
208
|
+
# Interactive 초기 설정
|
|
209
|
+
python run.py init
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 주요 기능
|
|
213
|
+
|
|
214
|
+
- **Interactive 초기 설정**: `git-catcher init` 명령으로 대화형 질문에 답하면 `.env` 및 `docker-compose.yml` 자동 생성
|
|
215
|
+
- **간편 실행**: `python run.py`로 빠르게 실행
|
|
216
|
+
- **시작 알림**: `NOTIFY_ON_START=true` 설정 시 Slack에 시작 알림 전송 (저장소, 브랜치, 호스트, IP 정보 포함)
|
|
217
|
+
- **저장소 자동 감지**: `ALLOWED_REPOS` 미설정 시 `REPO_PATH`의 git remote origin URL에서 `owner/repo`를 자동 추출
|
|
218
|
+
- **Slack 배포 알림**: `SLACK_WEBHOOK_URL` 설정 시 배포 성공/실패를 Slack 채널에 알림
|
|
219
|
+
- **SSE 재연결 복구**: `Last-Event-ID` 기반으로 연결 끊김 시 마지막 수신 이벤트 이후부터 재수신
|
|
220
|
+
- **Rich 콘솔 로깅**: 컬러 + 타임스탬프(시:분:초.ms) 포맷의 가독성 높은 콘솔 출력
|
|
221
|
+
|
|
222
|
+
## 동작 확인
|
|
223
|
+
|
|
224
|
+
1. Git Catcher를 [실행](#실행)합니다:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
python run.py
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
2. `SSE 스트림 연결 성공` 로그가 출력되면 연결 성공입니다.
|
|
231
|
+
3. `NOTIFY_ON_START=true`로 설정했다면 Slack에 시작 알림이 전송됩니다.
|
|
232
|
+
4. 허용된 브랜치에 커밋을 push합니다:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
git add .
|
|
236
|
+
git commit -m "test webhook"
|
|
237
|
+
git push origin main
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
5. Git Catcher 터미널에서 다음 로그가 순서대로 출력되는지 확인합니다:
|
|
241
|
+
- Push 감지: `[main] test webhook`
|
|
242
|
+
- `git fetch` → `git checkout` → `git pull` 완료
|
|
243
|
+
- `POST_PULL_COMMAND` 실행 (설정 시)
|
|
244
|
+
- Slack 알림 전송 (설정 시)
|
|
245
|
+
|
|
246
|
+
설정에 문제가 있으면 GitHub Webhook 페이지의 **Recent Deliveries** 탭에서 전송 상태를 확인할 수 있습니다.
|
|
247
|
+
|
|
248
|
+
## 테스트
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
pytest tests/ -v
|
|
252
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# CLI commands
|