pipeline { agent none options { timestamps() } environment { CI = 'true' NODE_OPTIONS = '--max_old_space_size=2048' APP_VERSION = "1.0.${BUILD_NUMBER}" DOCKER_BUILDKIT = '1' } 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() } } } stage('Backend: lint & test') { agent { docker { image 'python:3.11-slim' args '-u root' } } steps { dir('backend') { sh ''' set -e python -m venv .venv . .venv/bin/activate pip install --upgrade pip pip install -r requirements-dev.txt ruff check app tests pytest ''' } } } stage('Frontend: check & build') { agent { docker { image 'node:20-slim' } } steps { dir('frontend') { sh ''' set -e npm install --no-progress --no-audit --prefer-offline npm run check npm run build ''' } } } stage('Docker: build images') { agent any steps { sh ''' set -e 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:latest \ -t cafeteria-backend:${BUILD_NUMBER} \ ./backend docker build \ -t cafeteria-frontend:latest \ -t cafeteria-frontend:${BUILD_NUMBER} \ ./frontend ''' } } stage('Deploy frontend & backend') { when { branch 'main' } agent any steps { sh ''' set -e docker rm -f cafeteria-backend cafeteria-frontend 2>/dev/null || true docker run -d \ --name cafeteria-backend \ -p 8000:8000 \ cafeteria-backend:latest docker run -d \ --name cafeteria-frontend \ -p 3000:80 \ cafeteria-frontend:latest ''' } } } post { always { sh ''' docker image prune -a -f || true docker builder prune -a -f || true ''' cleanWs() } } }