zioinfo-mail/scripts/push/push_jenkinsfiles_via_server.py
DESKTOP-TKLFCPR\ython 5561d0d050 feat(cicd): fix webhook server, git URLs, push Jenkinsfiles to all 5 Gitea repos
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 19:55:19 +09:00

152 lines
5.8 KiB
Python

"""서버에서 직접 각 Gitea repo에 Jenkinsfile 추가 push"""
import paramiko, sys
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
sftp = client.open_sftp()
def run(label, cmd, timeout=60):
print(f' [{label}]')
_, o, e = client.exec_command(cmd, timeout=timeout)
out = o.read().decode('utf-8', 'replace').strip()
err = e.read().decode('utf-8', 'replace').strip()
if out: print(f' {out[:300]}')
if err:
bad = [l for l in err.splitlines() if not any(k in l.lower() for k in ['warn','hint','note','already'])]
if bad: print(f' ERR: {bad[-1][:200]}')
return out
GITEA = "http://zio:Zio%40Admin2026%21@localhost:3000/zio"
# Jenkinsfile 내용 정의
JENKINSFILES = {
"guardia-manager": """pipeline {
agent any
environment {
STATIC = '/var/www/manager'
NOTIFY = "${ITSM_BASE_URL}/api/messenger/webhook"
}
options { buildDiscarder(logRotator(numToKeepStr: '5')); timeout(time: 15, unit: 'MINUTES') }
stages {
stage('Checkout') { steps { checkout scm } }
stage('Build') {
steps {
dir('frontend') {
sh 'npm ci 2>/dev/null || npm install'
sh 'npm run build'
}
}
}
stage('Deploy') {
when { branch 'main' }
steps {
sh \"\"\"
cp -r frontend/dist/. ${STATIC}/
systemctl restart guardia-manager 2>/dev/null || true
\"\"\"
}
}
}
post {
success { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":true,\\\"result_summary\\\":\\\"✅ guardia-manager 배포 완료\\\"}' 2>/dev/null || true" }
failure { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":false,\\\"result_summary\\\":\\\"❌ guardia-manager 빌드 실패\\\"}' 2>/dev/null || true" }
}
}""",
"guardia-messenger": """pipeline {
agent any
environment {
NOTIFY = "${ITSM_BASE_URL}/api/messenger/webhook"
}
options {
buildDiscarder(logRotator(numToKeepStr: '5'))
timeout(time: 10, unit: 'MINUTES')
timestamps()
}
stages {
stage('Checkout') { steps { checkout scm } }
stage('Validate') {
steps {
sh 'node --version || true'
sh "grep -E '\\\"expo\\\"' package.json | head -1 || true"
}
}
stage('Install') {
steps { sh 'npm ci --legacy-peer-deps 2>/dev/null || npm install --legacy-peer-deps' }
}
stage('Type Check') {
when { expression { fileExists('tsconfig.json') } }
steps { sh 'npx tsc --noEmit 2>/dev/null || true' }
}
stage('EAS Build Trigger') {
when {
allOf {
branch 'main'
expression { return env.EXPO_TOKEN?.trim() }
}
}
steps {
sh '''
npm install -g @expo/eas-cli 2>/dev/null || true
eas build --platform android --non-interactive --no-wait --profile production 2>/dev/null || echo "EAS 빌드 큐 등록됨"
'''
}
}
}
post {
success { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":true,\\\"result_summary\\\":\\\"✅ guardia-messenger 검증 완료 #${BUILD_NUMBER}\\\"}' 2>/dev/null || true" }
failure { sh "curl -sf -X POST ${NOTIFY} -H 'Content-Type:application/json' -d '{\\\"event\\\":\\\"build_result\\\",\\\"room\\\":\\\"ops\\\",\\\"success\\\":false,\\\"result_summary\\\":\\\"❌ guardia-messenger 빌드 실패 #${BUILD_NUMBER}\\\"}' 2>/dev/null || true" }
}
}""",
"guardia-docs": """pipeline {
agent any
environment { DOCS = '/var/www/docs' }
options { buildDiscarder(logRotator(numToKeepStr: '3')) }
stages {
stage('Checkout') { steps { checkout scm } }
stage('Deploy') {
when { branch 'main' }
steps { sh 'mkdir -p ${DOCS} && cp -r . ${DOCS}/' }
}
}
}""",
}
print('[서버에서 Gitea repo Jenkinsfile push]')
for repo, content in JENKINSFILES.items():
print(f'\n=== {repo} ===')
# 임시 디렉토리에 clone
tmp = f'/tmp/jf_{repo}'
run(f'clone {repo}', f"""
rm -rf {tmp}
git clone {GITEA}/{repo}.git {tmp} 2>&1 | tail -2
""")
# Jenkinsfile 작성
with sftp.open(f'{tmp}/Jenkinsfile', 'w') as f:
f.write(content)
print(f' Jenkinsfile 작성됨')
# commit + push
run(f'push {repo}', f"""
cd {tmp}
git config user.email "ci@zioinfo.co.kr"
git config user.name "CI Bot"
git add Jenkinsfile
git diff --cached --stat
git commit -m "ci: add Jenkinsfile for CI/CD pipeline" 2>/dev/null || echo "already committed"
git push origin main 2>&1 | tail -3
rm -rf {tmp}
""", timeout=30)
# zioinfo-web, guardia-itsm 도 Jenkinsfile 확인
print('\n[기존 repo Jenkinsfile 존재 확인]')
for repo in ['zioinfo-web', 'guardia-itsm']:
run(f'{repo} Jenkinsfile', f"""
curl -sf '{GITEA.replace("http://zio:Zio%40Admin2026%21@localhost", "http://localhost")}:3000/api/v1/repos/zio/{repo}/contents/Jenkinsfile' \
-u 'zio:Zio@Admin2026!' 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK size:', d.get('size',0))" 2>/dev/null || echo "없음"
""")
sftp.close()
client.close()
print('\n=== 완료 ===')