diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..c092bed --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,146 @@ +// Деплой Home AI Assistant на grigosserver. +// +// Jenkins: New Item → Pipeline → Pipeline script from SCM → этот репозиторий. +// Агент: хост с Docker, где лежит ~/to_services/Home_assistant (label ниже). +// +// Один раз на сервере: +// git clone ~/to_services/Home_assistant +// cp .env.example .env # OPENROUTER_API_KEY и прочее +// mkdir -p data + +pipeline { + agent { + label 'grigosserver' + } + + options { + buildDiscarder(logRotator(numToKeepStr: '25')) + timeout(time: 45, unit: 'MINUTES') + disableConcurrentBuilds() + timestamps() + } + + parameters { + string( + name: 'GIT_BRANCH', + defaultValue: 'main', + description: 'Ветка: git reset --hard origin/' + ) + string( + name: 'DEPLOY_DIR', + defaultValue: '/home/grigo/to_services/Home_assistant', + description: 'Каталог с .env, data/ и docker-compose.yml' + ) + string( + name: 'BACKEND_HEALTH_URL', + defaultValue: 'http://127.0.0.1:8080/api/v1/health', + description: 'Проверка после деплоя' + ) + booleanParam( + name: 'RUN_TESTS', + defaultValue: true, + description: 'npm run build + compileall в workspace Jenkins' + ) + booleanParam( + name: 'DOCKER_PULL', + defaultValue: true, + description: 'docker compose build --pull' + ) + } + + environment { + GIT_BRANCH = "${params.GIT_BRANCH}" + DEPLOY_DIR = "${params.DEPLOY_DIR}" + BACKEND_HEALTH_URL = "${params.BACKEND_HEALTH_URL}" + DOCKER_PULL = "${params.DOCKER_PULL}" + RUN_TESTS = "${params.RUN_TESTS}" + } + + stages { + stage('Preflight') { + steps { + sh ''' + set -euxo pipefail + command -v docker + docker compose version + test -d "${DEPLOY_DIR}" + test -f "${DEPLOY_DIR}/.env" + test -f "${DEPLOY_DIR}/docker-compose.yml" + ''' + } + } + + stage('Test') { + when { + expression { return params.RUN_TESTS } + } + steps { + sh ''' + set -euxo pipefail + cd frontend + if [ -f package-lock.json ]; then + npm ci + else + npm install + fi + npm run build + cd .. + python3 -m compileall -q backend/app + ''' + } + } + + stage('Deploy') { + steps { + dir("${DEPLOY_DIR}") { + sh ''' + set -euxo pipefail + git fetch --prune origin + git reset --hard "origin/${GIT_BRANCH}" + git clean -fd -e .env -e data -e 'data/**' + + if [ "${DOCKER_PULL}" = "true" ]; then + docker compose build --pull + else + docker compose build + fi + docker compose up -d + docker compose ps + ''' + } + } + } + + stage('Healthcheck') { + steps { + sh ''' + set -euxo pipefail + for i in $(seq 1 30); do + if curl -fsS "${BACKEND_HEALTH_URL}" >/dev/null; then + echo "OK: ${BACKEND_HEALTH_URL}" + exit 0 + fi + sleep 2 + done + echo "Healthcheck failed: ${BACKEND_HEALTH_URL}" + exit 1 + ''' + } + } + } + + post { + success { + echo "Deployed ${DEPLOY_DIR} @ origin/${GIT_BRANCH}" + } + failure { + dir("${DEPLOY_DIR}") { + sh ''' + docker compose ps || true + docker compose logs --tail=100 backend || true + docker compose logs --tail=50 frontend || true + ''' + } + } + } +}