pipeline { agent { label 'docker' } environment { DOCKER_BUILDKIT = '1' IMAGE_NAME = 'registry.myinstalink.ru/docbot' } stages { stage('Checkout'){ steps { checkout scm } } stage('Lint/Test/Sec'){ agent { docker { image 'python:3.12-slim' args '-u root' } } steps { sh ''' apt-get update && apt-get install -y build-essential libpq-dev curl jq pip install -U pip poetry safety bandit poetry install --no-interaction --no-root poetry run ruff check . poetry run mypy src poetry run pytest -q --maxfail=1 --disable-warnings poetry export -f requirements.txt | safety check --stdin || true ''' } } stage('Build & Push'){ steps { script { def sha = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() def tag = (env.GIT_BRANCH == 'origin/main') ? "main-${sha}" : "dev-${sha}" sh """ echo ${REGISTRY_PASS} | docker login registry.myinstalink.ru -u ${REGISTRY_USER} --password-stdin docker build --target runtime -t ${IMAGE_NAME}:${tag} -t ${IMAGE_NAME}:latest . docker push ${IMAGE_NAME}:${tag} docker push ${IMAGE_NAME}:latest """ } } } stage('Deploy Dev'){ when { branch 'develop' } steps { sh ''' ssh -o StrictHostKeyChecking=no deploy@dev-host \ "docker pull ${IMAGE_NAME}:latest && docker compose -f /srv/docbot/docker-compose.dev.yml up -d --remove-orphans" ''' } } stage('Deploy Prod'){ when { buildingTag() } steps { sh ''' ssh -o StrictHostKeyChecking=no deploy@prod-host ' set -euo pipefail ACTIVE=$(readlink /srv/docbot/current || true) TARGET=$([ "$ACTIVE" = "/srv/docbot/blue" ] && echo "green" || echo "blue") docker pull ${IMAGE_NAME}:${GIT_TAG_NAME} sed -e "s|__IMAGE__|${IMAGE_NAME}:${GIT_TAG_NAME}|g" /srv/docbot/${TARGET}/docker-compose.prod.yml.tpl > /srv/docbot/${TARGET}/docker-compose.prod.yml docker compose -f /srv/docbot/${TARGET}/docker-compose.prod.yml up -d --remove-orphans docker compose -f /srv/docbot/${TARGET}/docker-compose.prod.yml run --rm app alembic upgrade head curl -fsS http://127.0.0.1:8080/healthz ln -sfn /srv/docbot/${TARGET} /srv/docbot/current systemctl reload nginx || true ' ''' } } } post { always { junit 'reports/**/*.xml'; } } }