pipeline { agent none options { timestamps() } environment { NODE_OPTIONS = '--max_old_space_size=2048' } stages { stage('Init') { agent any steps { script { env.COMMIT_AUTHOR = sh( script: "git show -s --format=%an HEAD", returnStdout: true ).trim() env.COMMIT_SHORT = sh( script: "git rev-parse --short HEAD", returnStdout: true ).trim() } echo "CI build for commit ${env.COMMIT_SHORT} by ${env.COMMIT_AUTHOR}" } } /* ========================= BACKEND CI ========================= */ stage('Backend: lint & test') { agent { docker { image 'python:3.11-slim' } } environment { HOME = "${WORKSPACE}" PIP_CACHE_DIR = "${WORKSPACE}/.cache/pip" PYTHONDONTWRITEBYTECODE = 1 } steps { dir('backend') { sh ''' set -e mkdir -p "$PIP_CACHE_DIR" "$WORKSPACE/.cache/pytest" python -m venv .venv . .venv/bin/activate pip install --upgrade pip pip install -r requirements-dev.txt ruff check app tests pytest -o cache_dir="$WORKSPACE/.cache/pytest" --junitxml=pytest.xml ''' } } } /* ========================= FRONTEND CI ========================= */ stage('Frontend: check & build') { agent { docker { image 'node:20-slim' } } environment { HOME = "${WORKSPACE}" NPM_CONFIG_CACHE = "${WORKSPACE}/.cache/npm" } steps { dir('frontend') { sh ''' set -e mkdir -p "$NPM_CONFIG_CACHE" npm install --no-progress --no-audit --prefer-offline npm run check npm test npm run build ''' } } } } post { always { script { node { junit testResults: 'backend/pytest.xml', allowEmptyResults: true if (env.CHANGE_ID) { def giteaBase = 'https://openbokeron.org' def owner = 'OpenBokeron' def repo = 'TallerCiCd' def pr = env.CHANGE_ID def result = currentBuild.currentResult def emoji = (result == 'SUCCESS') ? '✅' : (result == 'UNSTABLE') ? '⚠️' : '❌' def msg = "${emoji} Jenkins: **${result}**\\n\\n" + "- Job: `${env.JOB_NAME}`\\n" + "- Build: #${env.BUILD_NUMBER}\\n" + "- Commit: `${env.GIT_COMMIT?.take(7) ?: env.COMMIT_SHORT}`\\n" + "- URL: ${env.BUILD_URL}" def commentsUrl = "${giteaBase}/gitea/api/v1/repos/${owner}/${repo}/issues/${pr}/comments" withCredentials([string(credentialsId: 'jenkins-bot-api', variable: 'GITEA_TOKEN')]) { sh """ set -e curl -sS -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ --data @- \ '${commentsUrl}' <<'JSON' {"body":"${msg.replace('\\', '\\\\').replace('"','\\"')}"} JSON """ } } else { echo "No es build de PR (CHANGE_ID vacío); no comento." } cleanWs() } } } } }