Add: Stock tracker, Jenkins CI/CD pipeline, linting config
- stock_tracker.py: Portfolio tracking with P&L calculations - Jenkinsfile: Full CI/CD with linting, testing, deployment - test_requirements.txt: Testing dependencies - .pylintrc: Linting configuration - requirements.txt: Production dependencies Features: - Stock & crypto portfolio tracking - Investment guideline checks - Unit tests & linting pipeline - Integration tests for Oracle/Telegram/Gitea - Staging & Production deployment stages
This commit is contained in:
209
Jenkinsfile
vendored
Normal file
209
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
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!'
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user