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 1: CODE QUALITY (LINT & SECURITY) // Runs BEFORE build - gates quality // ===================================================== stage('Code Quality Gates') { steps { echo '๐Ÿ” Running code quality gates...' sh ''' source venv/bin/activate # Python linting flake8 . --max-line-length=120 \ --exclude=venv,__pycache__,node_modules,build,dist \ --format=json --output-file=flake-report.json || true # Security scanning bandit -r . -f json -o bandit-report.json || true # Type checking mypy *.py --ignore-missing-imports || true # Dead code detection vulture *.py --make-module || true ''' } post { always { recordIssues(tools: [ flake8(pattern: 'flake-report.json'), bandit(pattern: 'bandit-report.json') ]) echo 'โœ… Code quality gates completed' } failure { error 'โŒ Code quality gates failed!' } } } // ===================================================== // STAGE 2: UNIT TESTS // Runs DURING build - validates functionality // ===================================================== stage('Unit Tests') { steps { echo '๐Ÿงช Running unit tests...' sh ''' source venv/bin/activate pytest tests/ \ -v \ --tb=short \ --junitxml=test-results.xml \ --cov=. \ --cov-report=html \ --cov-report=xml \ --cov-report=term-missing ''' } post { always { junit 'test-results.xml' cobertura coberturaPackage: 'coverage.xml', failNoStubs: false publishHTML([ reportDir: 'htmlcov', reportFiles: 'index.html', reportName: 'Coverage Report' ]) echo 'โœ… Unit tests completed' } failure { error 'โŒ Unit tests failed!' } } } // ===================================================== // STAGE 3: INTEGRATION TESTS // Runs AFTER unit tests - validates connections // ===================================================== 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() " || echo "โš ๏ธ Oracle connection failed (expected if no creds)" # Test Telegram bot (ping) curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe" || echo "โš ๏ธ Telegram test skipped" # Test Gitea API curl -s -u "${GITEA_USER}:${GITEA_TOKEN}" "${GITEA_URL}/api/v1/user" || echo "โš ๏ธ Gitea test skipped" ''' } post { always { echo 'โœ… Integration tests completed' } } } // ===================================================== // STAGE 4: BUILD // Runs AFTER all tests pass // ===================================================== stage('Build') { steps { echo '๐Ÿ“ฆ Building application...' sh ''' source venv/bin/activate # Freeze dependencies pip freeze > requirements.locked.txt # Create executable scripts chmod +x *.py # Verify all files are present ls -la *.py ls -la tests/ ''' } post { success { archiveArtifacts artifacts: '*.py,tests/**,requirements*.txt,.pylintrc,Jenkinsfile', fingerprint: true echo 'โœ… Build completed' } } } // ===================================================== // STAGE 5: DEPLOY TO STAGING // Only on main branch // ===================================================== stage('Deploy to Staging') { when { branch 'main' } steps { echo '๐Ÿš€ Deploying to staging...' sshPublisher(publishers: [ sshPublisherDesc( configName: 'ubuntu-server', transfers: [ sshTransfer( sourceFiles: '*.py,tests/,requirements*.txt,.pylintrc,Jenkinsfile', remoteDirectory: '/home/joungmin/openclaw', execCommand: ''' cd /home/joungmin/openclaw source venv/bin/activate pip install -r requirements.txt pytest tests/ --tb=short supervisorctl restart openclaw ''' ) ] ) ]) } } } 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 \${env.JOB_NAME} #\${env.BUILD_NUMBER}: \${currentBuild.currentResult}" """ } } success { echo '๐ŸŽ‰ Build succeeded!' } failure { echo '๐Ÿ’ฅ Build failed!' mail to: 'joungmin@example.com', subject: "Failed Pipeline: ${env.JOB_NAME}", body: "Check ${env.BUILD_URL}" } unstable { echo 'โš ๏ธ Build is unstable!' } } }