--- id: deploy-sftp-incremental created: 2026-09-22 schema: spec-driven --- # Proposal: Инкрементальный SFTP-деплой (только изменившиеся файлы) ## Problem `tools/deploy_sftp.py` при каждом деплое заливает ВСЕ файлы из `public/` (524 файла, 66M) через `sftp.put()` без проверки, изменился ли файл на сервере. Из них ~40M — тяжёлые неизменные файлы (PDF 21M, M4V 11M×2 и др.), которые льются повторно каждый раз. Результат (замер №1, 2026-09-22): деплой через Gitea Actions занял **~36 минут** до видимости на проде. Плюс скрипт не имеет таймаутов: при обрыве SFTP-соединения `paramiko.Transport` висит в `sftp.put()` бесконечно (наблюдали на run 40: лог замер на 17:22:54, файл hero.svg 1.7KB не залит, job не завершился). ## Goal - Заливать только файлы, которых нет на сервере или которые изменились (size+mtime). - Не висеть вечно: таймауты на соединение и на операцию, явная ошибка при обрыве. - Сократить время деплоя в разы (цель: < 5 мин до видимости на проде). ## Non-goals - Не трогаем способ вызова (по-прежнему `gitea-main push` → Gitea Actions → `tools/deploy_sftp.py`). - Не трогаем содержание сайта / архив / темы. - Не добавляем rsync (на Jino SFTP-only, удалённый exec запрещён).