diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index fd9631a..1af3d60 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -37,9 +37,15 @@ jobs: steps: - uses: actions/checkout@v4 - name: Prepare release + id: prepare shell: bash run: | set -euo pipefail + backend_version="$(sed -n 's/^BACKEND_VERSION = "\(.*\)"$/\1/p' app/version.py)" + case "$backend_version" in + ''|*[!0-9.]*) exit 1 ;; + esac + echo "backend_version=$backend_version" >> "$GITHUB_OUTPUT" tar --exclude=.git --exclude=.env -cf "$RUNNER_TEMP/$RELEASE_NAME" . printf '%s\n' "$PROD_SSH_KEY" > "$RUNNER_TEMP/deploy_key" printf '%s\n' "$PROD_KNOWN_HOSTS" > "$RUNNER_TEMP/known_hosts" @@ -67,10 +73,13 @@ jobs: -o BatchMode=yes \ -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" \ "$PROD_USER@$PROD_HOST" \ - "PROD_PATH='$PROD_PATH' RELEASE_NAME='$RELEASE_NAME' bash -s" <<'REMOTE' + "PROD_PATH='$PROD_PATH' RELEASE_NAME='$RELEASE_NAME' EXPECTED_BACKEND_VERSION='$EXPECTED_BACKEND_VERSION' bash -s" <<'REMOTE' set -euo pipefail cd "$PROD_PATH" release="$HOME/$RELEASE_NAME" + test -f "$release" + archive_version="$(tar -xOf "$release" ./app/version.py | sed -n 's/^BACKEND_VERSION = "\(.*\)"$/\1/p')" + test "$archive_version" = "$EXPECTED_BACKEND_VERSION" mkdir -p "$HOME/backups/miem_workers" backup="$HOME/backups/miem_workers/miem_workers-$(date +%Y%m%d-%H%M%S).sql" docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > "$backup" @@ -79,7 +88,13 @@ jobs: -v "$PROD_PATH":/dst \ alpine:3.20 sh -c 'tar -xf /src/release.tar -C /dst' docker compose up -d --build - curl --fail --silent --show-error http://127.0.0.1:8000/api/health + runtime_version="$(docker compose exec -T api python -c 'from app.version import BACKEND_VERSION; print(BACKEND_VERSION)')" + test "$runtime_version" = "$EXPECTED_BACKEND_VERSION" + health="$(curl --fail --silent --show-error http://127.0.0.1:8000/api/health)" + case "$health" in + *"\"status\":\"ok\""*"\"backend_version\":\"$EXPECTED_BACKEND_VERSION\""*) ;; + *) echo "Unexpected health response: $health" >&2; exit 1 ;; + esac find "$HOME/backups/miem_workers" -maxdepth 1 -type f -name 'miem_workers-*.sql' ! -path "$backup" -delete docker compose ps rm -f "$release" @@ -87,3 +102,4 @@ jobs: env: PROD_HOST: ${{ secrets.PROD_HOST }} PROD_USER: ${{ secrets.PROD_USER }} + EXPECTED_BACKEND_VERSION: ${{ steps.prepare.outputs.backend_version }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 361b1b3..3253066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.8.12 + +- Передача версии в production deploy ограничена безопасным форматом. + +## 0.8.11 + +- CSS-ассеты админки получают версию в URL и обновляются после релиза без ручной очистки кэша браузера. + +## 0.8.10 + +- Production deploy проверяет совпадение версии release-архива и запущенного API. + ## 0.8.9 - Контейнеры API, worker и PostgreSQL автоматически перезапускаются после остановки или перезагрузки хоста. diff --git a/README.md b/README.md index 00c16ad..40f0eaa 100644 --- a/README.md +++ b/README.md @@ -135,4 +135,4 @@ node --check app/static/admin.js Тесты с данными используют временную SQLite; отдельные API smoke-тесты запускают приложение с его текущей конфигурацией. Браузерная проверка: `pip install playwright`, `python -m playwright install chromium`, затем `python tests/browser_admin.py`. Она проверяет реальный рендеринг страниц, клавиатуру, диалог, фильтры и восстановление прогресса после ошибки. Скриншоты сохраняются во временную папку; путь выводится в конце. -Версия сервиса: `0.8.9`. Админка всегда показывает версии backend и frontend в footer. +Версия сервиса: `0.8.12`. Админка всегда показывает версии backend и frontend в footer. diff --git a/app/templates/base.html b/app/templates/base.html index c7c70e7..bf76f81 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -4,7 +4,7 @@ {% block title %}MIEM Employees{% endblock %} - + Перейти к содержимому diff --git a/app/templates/login.html b/app/templates/login.html index 8192c12..1623a3f 100644 --- a/app/templates/login.html +++ b/app/templates/login.html @@ -4,7 +4,7 @@ Вход · MIEM Employees - +
diff --git a/app/version.py b/app/version.py index 794937e..d496d48 100644 --- a/app/version.py +++ b/app/version.py @@ -1,3 +1,3 @@ -APP_VERSION = "0.8.9" -FRONTEND_VERSION = "0.8.9" -BACKEND_VERSION = "0.8.9" +APP_VERSION = "0.8.12" +FRONTEND_VERSION = "0.8.12" +BACKEND_VERSION = "0.8.12" diff --git a/pyproject.toml b/pyproject.toml index eed873f..1e43d03 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "miem-workers" -version = "0.8.9" +version = "0.8.12" description = "MIEM employees parser, admin API, and web admin" requires-python = ">=3.11" dependencies = [ diff --git a/tests/test_api.py b/tests/test_api.py index 1db517d..4321576 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -18,7 +18,7 @@ def test_health_returns_versions(): response = TestClient(app).get("/api/health") assert response.status_code == 200 - assert response.json()["backend_version"] == "0.8.9" + assert response.json()["backend_version"] == "0.8.12" def test_api_employees_and_stats_require_admin_session():