152 lines
5.8 KiB
Python
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=== 완료 ===')
|