Files
openclaw-workspace/Jenkinsfile
Joungmin ceb52b2146 Add: Unit tests for habit_bot and stock_tracker
- tests/test_habit_bot.py: Habit tracking, food logging, keto guidance
- tests/test_stock_tracker.py: Portfolio management, P&L calculation
- pytest.ini: Pytest configuration
- Updated Jenkinsfile: Emphasized testing stages before build

Pipeline stages:
1. Code Quality Gates (lint + security)
2. Unit Tests (pytest with coverage)
3. Integration Tests (Oracle, Telegram, Gitea)
4. Build (only after tests pass)
5. Deploy to Staging
2026-02-19 03:32:43 +09:00

229 lines
8.2 KiB
Groovy

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!'
}
}
}