pipeline { agent none options { timestamps() } environment { CI = 'true' NODE_OPTIONS = '--max_old_space_size=2048' APP_VERSION = "1.0.${BUILD_NUMBER}" } 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 "Last commit: ${env.COMMIT_AUTHOR}" } } /* ========================= BACKEND (Python) ========================= */ stage('Backend: deps') { agent { docker { image 'python:3.12' args '-u root' } } steps { dir('backend') { sh ''' set -e python --version python -m venv .venv . .venv/bin/activate pip install --upgrade pip pip install -r requirements-dev.txt ''' } } } stage('Backend: lint & test') { agent { docker { image 'python:3.12' args '-u root' } } steps { dir('backend') { sh ''' set -e . .venv/bin/activate ruff check app tests pytest ''' } } } /* ========================= FRONTEND (Node) ========================= */ stage('Frontend: deps') { agent { docker { image 'node:20' } } steps { dir('frontend') { sh ''' set -e node --version npm --version npm install --no-progress --no-audit --prefer-offline ''' } } } stage('Frontend: check & test') { agent { docker { image 'node:20' } } steps { dir('frontend') { sh ''' set -e npm run check ''' } } } stage('Frontend: build') { agent { docker { image 'node:20' } } steps { dir('frontend') { sh ''' set -e npm run build ''' } } } /* ========================= DOCKER ========================= */ stage('Docker: build images') { when { expression { fileExists('backend/Dockerfile') && fileExists('frontend/Dockerfile') } } agent any steps { sh ''' set -e docker version docker build \ --build-arg APP_VERSION=${APP_VERSION} \ --build-arg GIT_COMMIT=${COMMIT_SHORT} \ --build-arg COMMIT_AUTHOR="${COMMIT_AUTHOR}" \ --build-arg BUILD_NUMBER=${BUILD_NUMBER} \ -t cafeteria-backend:${BUILD_NUMBER} ./backend docker build \ -t cafeteria-frontend:${BUILD_NUMBER} ./frontend ''' } } stage('Deploy frontend & backend') { agent any environment { JENKINS_BASE_URL = 'http://jenkins:8080' JENKINS_JOB_NAME = 'Espetos' } steps { withCredentials([ usernamePassword( credentialsId: 'jenkins-api-token', usernameVariable: 'JENKINS_USER', passwordVariable: 'JENKINS_TOKEN' ) ]) { sh ''' set -e echo "Deploying build ${BUILD_NUMBER}" docker rm -f cafeteria-backend cafeteria-frontend 2>/dev/null || true docker run -d \ --name cafeteria-backend \ -e JENKINS_BASE_URL \ -e JENKINS_JOB_NAME \ -e JENKINS_USER \ -e JENKINS_TOKEN \ -p 8000:8000 \ cafeteria-backend:${BUILD_NUMBER} docker run -d \ --name cafeteria-frontend \ -p 3000:80 \ cafeteria-frontend:${BUILD_NUMBER} ''' } } } } post { always { script { node { cleanWs() } } } } }