# dedinit-deploy Specification (delta) ## ADDED Requirements ### Requirement: Автоматический деплой при пуше в основную ветку Система SHALL запускать workflow деплоя при каждом push в основную ветку (`main`) репозитория `estorozhenko/dedinit.ru` на gitea.nixg.ru. #### Scenario: Пуш в main запускает деплой - **GIVEN** репозиторий `estorozhenko/dedinit.ru` имеет Actions и раннер `bigbox-runner` online - **WHEN** пользователь пушит коммит в ветку `main` - **THEN** Gitea создаёт workflow-run вида `hugo build + sftp deploy`, который завершается успехом, а `https://dedinit.ru/` обновляется без ручных действий #### Scenario: Ветка не-main не деплоит - **GIVEN** push в любую другую ветку - **WHEN** workflow запускается - **THEN** deploy-шаг пропускается (условие `if: github.ref == 'refs/heads/main'`) ### Requirement: Деплой через SFTP Jino средствами репозитория Система SHALL выполнять сборку `hugo --minify` и зеркалирование `public/` на `kpa39l.myjino.ru:2222:/dedinit.ru/` через существующий `tools/deploy_sftp.py` (SFTP-only, пароль из env `SSHPASS`). #### Scenario: Успешный деплой - **GIVEN** раннер может запускать job-контейнеры (docker27-bash) - **WHEN** workflow выполняется - **THEN** в логе видно `hugo --minify` (build), затем `deploy_sftp.py`, завершившийся `Done.` без ошибок #### Scenario: Пароль из Gitea secrets - **GIVEN** секрет `SSHPASS` задан в настройках репозитория Gitea - **WHEN** deploy-шаг стартует - **THEN** пароль берётся из переменной окружения, а не из файла `docs/DEPLOY_INSTRUCTIONS.md` ### Requirement: Репозиторий не является mirror-репозиторием Система SHALL иметь репозиторий `estorozhenko/dedinit.ru` в Gitea без статуса mirror (`mirror:false`, `has_actions:true`), иначе Gitea не выполняет Actions. #### Scenario: Снятие mirror-статуса - **GIVEN** `PATCH /api/v1/repos/estorozhenko/dedinit.ru` с `{"mirror": false}` - **WHEN** запрос успешен - **THEN** `GET /repos/estorozhenko/dedinit.ru` возвращает `"mirror":false`, `"has_actions":true` ### Requirement: Синхронизация gitverse → gitea без mirror-интервала Система SHALL продолжать получать изменения из gitverse.ru (источника истины) в gitea.nixg.ru, но не через встроенный mirror-интервал, а через крон-скрипт `git fetch origin && git push` (чтобы репозиторий не был зеркалом). #### Scenario: Крон синхронизирует - **GIVEN** крон-джоб на bigbox, запускающий скрипт синхронизации - **WHEN** в gitverse появился новый коммит в main - **THEN** скрипт приносит его в gitea `estorozhenko/dedinit.ru`, и (при пуше в gitea) Actions деплоят ### Requirement: Секрет деплоя не светится Система SHALL хранить пароль SFTP Jino только в Gitea Actions secrets (переменная `SSHPASS`), не в git-истории и не в логах workflow. #### Scenario: Секрет маскируется - **GIVEN** workflow использует `${{ secrets.SSHPASS }}` - **WHEN** runner печатает лог - **THEN** Gitea/runner маскирует секрет в выводе (не появляется открытым текстом)