Files
openclaw-workspace/Jenkinsfile
2026-02-19 13:49:35 +09:00

135 lines
4.9 KiB
Groovy

pipeline {
agent any
environment {
// Credentials
ORACLE_DSN = credentials('oracle-dsn')
ORACLE_USER = credentials('oracle-user')
ORACLE_PASSWORD = credentials('oracle-password')
TELEGRAM_BOT_TOKEN = credentials('telegram-bot-token')
GITEA_URL = 'https://gittea.cloud-handson.com'
GITEA_USER = 'joungmin'
GITEA_TOKEN = credentials('gitea-token')
}
stages {
// =====================================================
// STAGE 0: PREPARATION (가상환경 생성 및 패키지 설치)
// =====================================================
stage('Preparation') {
steps {
echo '📦 Preparing Python environment...'
sh '''
python3 -m venv venv
. venv/bin/activate
pip install --upgrade pip
pip install pylint flake8 black isort bandit semgrep safety detect-secrets pytest pytest-cov oracledb
'''
}
}
// =====================================================
// STAGE 1: CODE QUALITY
// =====================================================
stage('Code Quality: Linting') {
steps {
echo '📋 Running linters...'
sh '''
. venv/bin/activate
pylint --rcfile=.pylintrc *.py --output-format=json > pylint-report.json || true
flake8 . --max-line-length=120 --exclude=venv,__pycache__ --format=default --output-file=flake8-report.txt || true
black --check . || true
isort --check-only --profile=black . || true
'''
}
post {
always {
// Warnings Next Generation 플러그인이 설치되어 있어야 합니다.
recordIssues(
tools: [
pyLint(pattern: 'pylint-report.json'),
flake8(pattern: 'flake8-report.txt')
]
)
}
}
}
stage('Security: Static Analysis') {
steps {
echo '🔒 Running static security analysis...'
sh '''
. venv/bin/activate
bandit -r . -f json -o bandit-report.json || true
semgrep --config=auto --json --output=semgrep-report.json || true
safety check -r requirements.txt --json --output=safety-report.json || true
detect-secrets scan --exclude-files '.git/.*' --output-format=json > secrets-report.json || true
'''
}
}
stage('Unit Tests') {
steps {
echo '🧪 Running unit tests...'
sh '''
. venv/bin/activate
pytest tests/ -v --junitxml=test-results.xml --cov=. --cov-report=xml || true
'''
}
post {
always {
junit 'test-results.xml'
}
}
}
stage('Build') {
steps {
echo '📦 Building application...'
sh '''
. venv/bin/activate
pip freeze > requirements.locked.txt
'''
}
post {
success {
archiveArtifacts artifacts: '*.py,requirements*.txt', allowEmptyArchive: true
}
}
}
stage('Deploy to Staging') {
when { branch 'main' }
steps {
echo '🚀 Deploying to staging...'
// SSH 설정이 되어 있는 경우에만 작동합니다.
echo 'Deployment steps would go here.'
}
}
}
post {
always {
echo '📊 Pipeline completed'
script {
def statusIcon = currentBuild.currentResult == 'SUCCESS' ? '✅' : '❌'
// 텔레그램 메시지 전송 (Bad Substitution 방지를 위해 홑따옴표 사용)
sh """
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d "chat_id=@your_channel" \
-d "text=${statusIcon} Pipeline: ${env.JOB_NAME} #${env.BUILD_NUMBER} completed."
"""
cleanWs()
}
}
failure {
echo '💥 Build failed!'
// 로컬 메일 서버가 없으면 이 부분에서 에러가 날 수 있으므로 주의하세요.
// mail to: 'joungmin@example.com', subject: "Failed: ${env.JOB_NAME}", body: "Check ${env.BUILD_URL}"
}
}
}