ci: workflow деплоя dedinit.ru через SFTP при пуше в main (Gitea Actions)

This commit is contained in:
2026-09-19 18:51:08 +00:00
parent f714b9180b
commit 39f29cc897
5 changed files with 259 additions and 0 deletions
@@ -0,0 +1,74 @@
# 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 маскирует секрет в выводе (не появляется открытым текстом)