#!/usr/bin/env python3 """GUARDiA Messenger Gitea 저장소 생성 + 코드 Push + Webhook 설정""" import paramiko, time, sys, os, io, zipfile, urllib.request, json, base64 HOST = '101.79.17.164'; USER = 'root'; PASS = '1q2w3e!Q' LOCAL_APP = 'C:/GUARDiA/app' SEP = chr(92) GITEA = 'http://localhost:3000' GIT_USER = 'zio' GIT_PASS = 'Zio@Admin2026!' cred = base64.b64encode(f'{GIT_USER}:{GIT_PASS}'.encode()).decode() headers = {'Content-Type': 'application/json', 'Authorization': f'Basic {cred}'} client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(HOST, username=USER, password=PASS, timeout=15) sftp = client.open_sftp() def run(label, cmd, timeout=60): print(f'\n[{label}]') chan = client.get_transport().open_session() chan.set_combine_stderr(True) chan.exec_command(cmd) start = time.time() while not chan.exit_status_ready(): if chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)); sys.stdout.flush() if time.time()-start > timeout: print('[TIMEOUT]'); break time.sleep(0.3) while chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)) sys.stdout.flush() rc = chan.recv_exit_status() print(f'exit={rc}'); return rc def gitea_api(method, path, data=None): url = f'{GITEA}/api/v1{path}' body = json.dumps(data).encode() if data else None req = urllib.request.Request(url, data=body, method=method, headers=headers) try: resp = urllib.request.urlopen(req, timeout=10) return json.loads(resp.read()), resp.status except urllib.error.HTTPError as e: body = e.read() try: return json.loads(body), e.code except: return {'error': body.decode()[:200]}, e.code # 1. 저장소 생성 print('=== 1. Gitea 저장소 생성 ===') d, s = gitea_api('POST', '/user/repos', { 'name': 'guardia-messenger', 'description': 'GUARDiA Messenger — React Native + Expo SDK 51 모바일 앱', 'private': False, 'auto_init': False, }) print(f'HTTP {s}: {d.get("full_name", d.get("message", d))}') # 2. 소스 zip 생성 (node_modules, .git, android, ios 제외) print('\n=== 2. 소스 패키징 ===') SKIP_DIRS = {'node_modules', '.git', 'android', 'ios', '__pycache__', '.expo'} SKIP_EXTS = ('.pyc', '.log') zip_buf = io.BytesIO(); count = 0 with zipfile.ZipFile(zip_buf, 'w', zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(LOCAL_APP): dirs[:] = [d for d in dirs if d not in SKIP_DIRS] rel = os.path.relpath(root, LOCAL_APP).replace(SEP, '/') for f in files: if f.endswith(SKIP_EXTS): continue arc = f if rel == '.' else f'{rel}/{f}' zf.write(os.path.join(root, f), arc); count += 1 zip_buf.seek(0) with sftp.open('/tmp/messenger-src.zip', 'wb') as f: f.write(zip_buf.read()) print(f' {count}개 파일 업로드') # 3. 서버에서 git push print('\n=== 3. Gitea Push ===') push_script = f"""#!/bin/bash rm -rf /tmp/messenger-push mkdir /tmp/messenger-push cd /tmp/messenger-push unzip -q /tmp/messenger-src.zip git init -q git config user.email ci@zioinfo.co.kr git config user.name ZioCI git add -A git commit -q -m "feat: GUARDiA Messenger v1.0.0 초기 커밋 - React Native + Expo SDK 51 + TypeScript - 6개 화면: 로그인·대시보드·SR·AI챗봇·알림·설정 - EAS Build (APK 성공: 51096ada) - .easignore: android/ios 제외 - plugins/withGradleProps: PNG Crunching 비활성화" git remote add origin http://zio:Zio%40Admin2026%21@localhost:3000/zio/guardia-messenger.git git push -f origin HEAD:main 2>&1 echo "PUSH_DONE" """ with sftp.open('/tmp/push_messenger.sh', 'w') as f: f.write(push_script) sftp.close() run('Git Push', 'bash /tmp/push_messenger.sh', 60) # 4. Webhook 등록 (Deploy Webhook) print('\n=== 4. Webhook 등록 ===') wh, ws = gitea_api('POST', '/repos/zio/guardia-messenger/hooks', { 'type': 'gitea', 'active': True, 'config': { 'url': 'http://localhost:9999/', 'content_type': 'json', 'secret': 'zioinfo-deploy-2026', }, 'events': ['push'], }) print(f'Webhook HTTP {ws}: ID={wh.get("id", wh.get("message", "?"))}') # 5. 브랜치 확인 print('\n=== 5. 저장소 확인 ===') repo, _ = gitea_api('GET', '/repos/zio/guardia-messenger') print(f'저장소: {repo.get("full_name")}') print(f'브랜치: {repo.get("default_branch")}') print(f'URL: {repo.get("html_url")}') client.close() print('\n=== 완료 ===') print('Gitea: http://101.79.17.164:3000/zio/guardia-messenger')