def execute_commands(commands, os_name, recommended_os) { if("${os_name}" == "linux") { if("${recommended_os}" == "only_linux" || "${recommended_os}" == "all_distros") { sh "${commands}" } } if("${os_name}" == "windows") { if("${recommended_os}" == "only_windows" || "${recommended_os}" == "all_distros") { powershell "${commands}" } } } def delete_directory(directory, os_name) { execute_commands( """ if [ -d "./${directory}" ] then rm -r ./${directory}; fi """, "${os_name}", "only_linux" ) execute_commands( """ if(Test-Path -Path .\\${directory}\\) { Remove-Item -Force -Recurse -Path .\\${directory}\\ } """, "${os_name}", "only_windows" ) } def fetch_git_repository(APPLICATION_NAME, JENKINS_REPO_DIR, DATA_SOURCE_BRANCH, DATA_SOURCE_URL) { echo """ Fetch ${APPLICATION_NAME} """ try { sh """ git config --global --add safe.directory '*'; """ dir("${JENKINS_REPO_DIR}") { git credentialsId: 'git-gitea-tbs093a', branch: "${DATA_SOURCE_BRANCH}", url: "${DATA_SOURCE_URL}" sh """ ls -la """ } } catch(error) { throw(error) } } def set_env_vars(JENKINS_REPO_DIR, GIT_REPO_URL, DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, VARS) { echo """ Set Env Vars """ try { dir("${JENKINS_REPO_DIR}") { withCredentials( [ usernamePassword( credentialsId: 'git-gitea-tbs093a', passwordVariable: 'GIT_TOKEN', usernameVariable: 'GIT_USERNAME' ), usernamePassword( credentialsId: 'telegram-video-summary-bot-credentials', passwordVariable: 'TELETHON_BOT_TOKEN', usernameVariable: 'TELETHON_BOT_NAME' ), usernamePassword( credentialsId: 'openai-video-summary-bot-credentials', passwordVariable: 'OPENAI_API_KEY', usernameVariable: 'OPENAI_USERNAME' ), usernamePassword( credentialsId: 'youtube-transcript-api-credentials', passwordVariable: 'TRANSCRIPT_API_TOKEN', usernameVariable: 'TRANSCRIPT_API_USERNAME' ), usernamePassword( credentialsId: 'postgresql-video-summary-bot-credentials', passwordVariable: 'DATABASE_PASSWORD', usernameVariable: 'DATABASE_USERNAME' ), ] ) { GIT_REPO_URL = GIT_REPO_URL.replace('https://', '') sh "./set.envs.sh ${VARS} --set repo.url='https://${GIT_USERNAME}:${GIT_TOKEN}@${GIT_REPO_URL}' --set telegram.bot.token='${TELETHON_BOT_TOKEN}' --set OPENAI_API_KEY='${OPENAI_API_KEY}' --set DATABASE_URL='postgresql://${DATABASE_USERNAME}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}' --dir ./ --exclude 'Jenkinsfile' --exclude '*.md' --exclude '*.sh' --exclude '*.py' --exclude '*.ini' --exclude '*.example' --exclude '*.session'" // if you have $ inside password - just use \$ (dolar escape) inside this var at editing credentials in jenkins! } } } catch(error) { throw(error) } } def test(JENKINS_REPO_DIR) { echo """ Test Pump Bot On K8S """ try { dir("${JENKINS_REPO_DIR}") { sh """ export KUBECONFIG="/home/jenkins/.kube/config"; kubectl apply -f ./k8s.manifests/config.yml; kubectl apply -f ./k8s.manifests/job.test.yml; """ // Wait until the pod in the deployment is running the tests waitUntil { def podName = sh(script: "export KUBECONFIG=\"/home/jenkins/.kube/config\"; kubectl get pods -l app=pump-bot-api-tests -o jsonpath='{.items[0].metadata.name}'", returnStdout: true).trim() def status = sh(script: "export KUBECONFIG=\"/home/jenkins/.kube/config\"; kubectl get pod ${podName} -o jsonpath='{.status.phase}'", returnStdout: true).trim() return status == 'Running' || status == 'Succeeded' || status == 'Failed' } // Capture the pod name after it’s up and running def podName = sh(script: "export KUBECONFIG=\"/home/jenkins/.kube/config\"; kubectl get pods -l app=pump-bot-api-tests -o jsonpath='{.items[0].metadata.name}'", returnStdout: true).trim() // Wait until the tests are finished by checking container logs waitUntil { // Sleep for 1 minute before the next check sleep time: 1, unit: 'MINUTES' def testLogs = sh(script: "export KUBECONFIG=\"/home/jenkins/.kube/config\"; kubectl logs ${podName} -c pump-bot-api-tests", returnStdout: true).trim() echo "Test Logs:\n${testLogs}" return testLogs.contains("summary") || testLogs.contains("tox") // assuming `tox` will indicate completion } // After tests, check if logs contain failure keywords def finalLogs = sh(script: "export KUBECONFIG=\"/home/jenkins/.kube/config\"; kubectl logs ${podName} -c pump-bot-api-tests", returnStdout: true).trim() if (finalLogs.contains("FAILED")) { error("TESTS FAILED.") } sh """ export KUBECONFIG="/home/jenkins/.kube/config"; kubectl delete -f ./k8s.manifests/job.test.yml; """ } } catch(error) { throw(error) } } def deploy(JENKINS_REPO_DIR) { echo """ Deploy Bot On K8S """ try { dir("${JENKINS_REPO_DIR}") { sh """ export KUBECONFIG="/home/jenkins/.kube/config"; kubectl apply -f ./k8s.manifests/config.yml; kubectl apply -f ./k8s.manifests/deployment.yml; """ } } catch(error) { throw(error) } } pipeline { agent { node { label "docker-builder && linux" } } environment { OS_NAME="" JENKINS_REPO_BOT_DIR = "${JENKINS_AGENT_WORKDIR}/telegram.video.summary.bot" GIT_BOT_REPO_URL="https://git.00x097.com/tbs093a/telegram.video.summary.bot.git" JENKINS_USER_ID = 1000 JENKINS_GROUP_ID = 1000 } triggers { GenericTrigger( genericVariables: [ [ key: 'DATA_SOURCE_BRANCH', value: '$.DATA_SOURCE_BRANCH' ], [ key: 'DATABASE_HOST', value: '$.DATABASE_HOST' ], [ key: 'DATABASE_PORT', value: '$.DATABASE_PORT' ], [ key: 'TESTS', value: '$.TESTS' ], [ key: 'DEPLOY', value: '$.DEPLOY' ], ], token: '077ff7e0-8460-4a63-9a33-71503bbad374' ) } stages { stage('Setup Parameters') { steps { script { if ("${NODE_NAME}".contains("windows")) { OS_NAME = "windows" } else { OS_NAME = "linux" } properties([ parameters([ string( defaultValue: 'master', description: 'Select Pump Bot data source branch for the build & deploy', name: 'DATA_SOURCE_BRANCH' ), string( defaultValue: 'localhost', description: 'Select Pump Bot data source branch for the build & deploy', name: 'DATABASE_HOST' ), string( defaultValue: '5432', description: 'Select Pump Bot data source branch for the build & deploy', name: 'DATABASE_PORT' ), string( defaultValue: 'video_summary_bot', description: 'Select Pump Bot data source branch for the build & deploy', name: 'DATABASE_NAME' ), booleanParam( defaultValue: false, description: 'Enable if you want run Pump Bot tests only.', name: 'TESTS' ), booleanParam( defaultValue: true, description: 'Enable if you want run Pump Bot for capture pump singnals from telegram and invest automatically', name: 'DEPLOY' ) ]) ]) } } } stage('Clean Workspace') { steps { script { catchError( buildresult: 'SUCCESS', stageresult: 'UNSTABLE' ) { delete_directory( "${JENKINS_REPO_PUMP_SCRIPT_DIR}", OS_NAME ) } } } } stage('Fetch Script Repositories') { steps { script { parallel( pump_bot_script: { fetch_git_repository( "Pump Bot (on VM - ${NODE_NAME})", "${JENKINS_REPO_PUMP_SCRIPT_DIR}", "${DATA_SOURCE_BRANCH}", "${GIT_REPO_PUMP_SCRIPT_URL}" ) } ) } } } stage('Set Env Vars') { steps { script { catchError( buildresult: 'FAILURE', stageresult: 'FAILURE' ) { set_env_vars( "${JENKINS_REPO_PUMP_SCRIPT_DIR}", "${GIT_REPO_PUMP_SCRIPT_URL}", "" ) } } } } stage('Test Pump Bot On K8S') { when { expression { "${TESTS}" == "true" } } steps { echo """ Test Pump Bot On K8S """ catchError( buildResult: 'SUCCESS', stageResult: 'UNSTABLE' ) { test( "${JENKINS_REPO_PUMP_SCRIPT_DIR}" ) } } } stage('Deploy Pump Bot On K8S') { when { expression { "${DEPLOY}" == "true" } } steps { echo """ Deploy Pump Bot On K8S """ catchError( buildResult: 'FAILURE', stageResult: 'FAILURE' ) { deploy( "${JENKINS_REPO_PUMP_SCRIPT_DIR}" ) } } } } }