# Spec: Инкрементальный SFTP-деплой ## MODIFIED Requirements ### Requirement: Скрипт заливает только изменившиеся файлы Скрипт сравнивает каждый локальный файл с удалённым и заливает только те, что отсутствуют на сервере или отличаются. Сравнение — по размеру и SHA1-хешу содержимого (mtime не используется: в CI после checkout он всегда свежий, что делает mtime-сравнение бесполезным). #### Scenario: Файл уже есть на сервере и не менялся Given сервер содержит файл `X` с тем же размером и SHA1, что локальный And локальный файл `X` существует When выполняется `tools/deploy_sftp.py` Then файл `X` НЕ заливается на сервер #### Scenario: Файла нет на сервере Given сервер НЕ содержит файл `X` And локальный файл `X` существует When выполняется `tools/deploy_sftp.py` Then файл `X` заливается на сервер #### Scenario: Файл изменился (другой размер) Given сервер содержит файл `X` с размером 100 And локальный файл `X` имеет размер 125 When выполняется `tools/deploy_sftp.py` Then файл `X` заливается на сервер #### Scenario: Файл изменился (тот же размер, другое содержимое) Given сервер содержит файл `X` того же размера, но с другим SHA1 And локальный файл `X` имеет другой SHA1 When выполняется `tools/deploy_sftp.py` Then файл `X` заливается на сервер ### Requirement: Скрипт не виснет при обрыве соединения Скрипт использует keepalive (15с) и таймаут канала (120с), а также переподключение с ретраями (до 3 попыток), чтобы при обрыве канала завершиться с ошибкой или продолжить, а не висеть бесконечно. #### Scenario: Соединение с сервером оборвалось Given SFTP-соединение с Jino работает And соединение обрывается во время `put()` When выполняется `tools/deploy_sftp.py` Then скрипт переподключается и повторяет операцию; если все попытки исчерпаны — завершается с ненулевым кодом и сообщением об ошибке ### Requirement: Удаление лишних файлов сохранено Скрипт продолжает удалять с сервера файлы, которых нет в локальном `public/` (mirror-поведение). #### Scenario: На сервере есть файл, которого нет локально Given сервер содержит файл `Y` And локальный каталог `public/` не содержит `Y` When выполняется `tools/deploy_sftp.py` Then файл `Y` удаляется с сервера