pipeline { agent any environment { // Test database connections ORACLE_DSN = credentials('oracle-dsn') ORACLE_USER = credentials('oracle-user') ORACLE_PASSWORD = credentials('oracle-password') // Telegram Bot TELEGRAM_BOT_TOKEN = credentials('telegram-bot-token') // Git GITEA_URL = 'http://localhost:3000' GITEA_USER = 'joungmin' GITEA_TOKEN = credentials('gitea-token') } stages { stage('Checkout') { steps { checkout scm script { env.BUILD_ID = sh(returnStdout: true, script: 'git rev-parse HEAD').trim() } } } stage('Dependencies') { steps { echo 'Installing Python dependencies...' sh ''' python3 -m venv venv source venv/bin/activate pip install -q -r requirements.txt pip install -q -r test_requirements.txt ''' } } stage('Lint') { steps { echo 'Running linters...' sh ''' source venv/bin/activate # Python linting flake8 . --max-line-length=120 --exclude=venv,__pycache__ || true pylint --rcfile=.pylintrc *.py || true # Security scanning bandit -r . -f json -o bandit-report.json || true # Dead code detection vulture *.py --make-module || true ''' } post { always { recordIssues(tools: [flake8(pattern: 'flake-report.txt')]) recordIssues(tools: [bandit(pattern: 'bandit-report.json')]) } } } stage('Unit Tests') { steps { echo 'Running unit tests...' sh ''' source venv/bin/activate pytest tests/ -v --tb=short --cov=. --cov-report=html --cov-report=xml coverage xml -o coverage-report.xml ''' } post { always { junit 'test-results.xml' cobertura coberturaPackage: 'coverage.xml', failNoStubs: false } } } stage('Integration Tests') { steps { echo 'Running integration tests...' sh ''' source venv/bin/activate # Test Oracle connection python3 -c " import oracledb conn = oracledb.connect( user='${ORACLE_USER}', password='${ORACLE_PASSWORD}', dsn='${ORACLE_DSN}' ) cursor = conn.cursor() cursor.execute('SELECT 1 FROM DUAL') print('✅ Oracle connection successful') conn.close() " # Test Telegram bot (ping) curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe" # Test Gitea API curl -s -u "${GITEA_USER}:${GITEA_TOKEN}" "${GITEA_URL}/api/v1/user" ''' } } stage('Build') { steps { echo 'Building application...' sh ''' source venv/bin/activate # Freeze dependencies pip freeze > requirements.locked.txt # Create executable scripts chmod +x *.py # Build Docker images if applicable docker build -t openclaw-bot:${BUILD_ID} . || true ''' } } stage('Deploy to Staging') { when { branch 'main' } steps { echo 'Deploying to staging server...' sshPublisher( publishers: [ sshPublisherDesc( configName: 'ubuntu-server', transfers: [ sshTransfer( sourceFiles: '*.py', remoteDirectory: '/home/joungmin/openclaw', execCommand: 'cd /home/joungmin/openclaw && source venv/bin/activate && pip install -r requirements.txt && supervisorctl restart openclaw' ) ] ) ] ) } } stage('Deploy to Production') { when { branch 'production' } steps { echo 'Deploying to production...' // Manual approval required input message: 'Deploy to production?' sshPublisher( publishers: [ sshPublisherDesc( configName: 'production-server', transfers: [ sshTransfer( sourceFiles: '*.py', remoteDirectory: '/home/joungmin/production', execCommand: 'cd /home/joungmin/production && docker-compose pull && docker-compose up -d' ) ] ) ] ) } } } post { always { echo 'Pipeline completed' // Send notification script { def status = currentBuild.currentResult == 'SUCCESS' ? '✅' : '❌' sh """ curl -s -X POST "https://api.telegram.org/bot\${TELEGRAM_BOT_TOKEN}/sendMessage" \ -d "chat_id=@your_channel" \ -d "text=${status} Pipeline completed: ${env.JOB_NAME} #\${env.BUILD_NUMBER}" """ } } success { echo 'Build succeeded!' archiveArtifacts artifacts: '**/*.py', fingerprint: true } failure { echo 'Build failed!' mail to: 'joungmin@example.com', subject: "Failed Pipeline: ${env.JOB_NAME}", body: "Something is wrong with ${env.BUILD_URL}" } unstable { echo 'Build is unstable!' } } }