feat: SFTP-деплой по size+SHA1 (не mtime), keepalive+таймаут канала, ретраи; apt python3-paramiko
deploy-dedinit / Build & SFTP Deploy (push) Successful in 12m41s

This commit is contained in:
2026-09-22 19:27:36 +00:00
parent 07ba1e427d
commit 92b7094fc7
4 changed files with 182 additions and 88 deletions
@@ -1,7 +1,20 @@
# Tasks: Инкрементальный SFTP-деплой
- [x] Обновить `tools/deploy_sftp.py`: сравнение (size + mtime с допуском 300с), пропуск неизменных, таймауты (banner_timeout/timeout + socket timeout)
- [x] `python3 tools/deploy_sftp.py --dry-run` — работает, выводит `+`/`=`
- [ ] Commit + push gitea main — запуск Gitea Actions
- [ ] Замер №2: время до видимости на проде; сравнить с эталоном (~36 мин)
- [ ] Прогнать openspec-archive-change / архивировать change
- [x] Обновить `tools/deploy_sftp.py`: инкремент по (size + SHA1), keepalive/таймаут канала, ретраи с переподключением
- [x] Проверить синтаксис (`python3 -m py_compile`) и логику same_file (юнит-тест без сети)
- [x] CI: заменить pip-установку paramiko на apt `python3-paramiko` (не зависит от PyPI) в `.gitea/workflows/deploy.yml`
- [x] Обновить openspec (spec/design/tasks) под SHA1-решение
- [ ] Замерить деплой №2 после запуска run на новом коде: сравнить с эталоном ~36 мин
- [ ] Прогнать openspec-archive-change (из прошлого change) — замер №1 зафиксирован в tasks.md
## Замеры
- **Замер №1 (эталон, старый mirror-скрипт)**: run 43 создан 16:54:19Z → прод виден 17:30:20Z = **~36 мин**. Полный job не завершился (завис на мёртвом SFTP).
- **Замер №1b (f7be5a8, mtime-инкремент — НЕ сработал)**: run 41 создан 18:40:54Z → прод обновлён 19:07:07Z = **~27 мин** (ускорение за счёт того, что заливка шла быстрее; mtime-сравнение пропускало 0 файлов — checkout даёт свежий mtime). Job завис на том же `2026/gotosocial-relay-match-by-default/hero.svg`.
- **Замер №2 (SHA1 + apt-paramiko)**: ожидается после освобождения runner'а (run 41 висит, run 42 не может стартовать).
## Блокеры
- Run 41 (f7be5a8) висит в Gitea Actions на мёртвом SFTP (нет API-cancel; runner на bigbox недоступен) — новый run (07ba1e4-правки) ждёт освобождения runner'а. По умолчанию Gitea ждёт до ~6ч.
- Gitea не создаёт следующий run по ветке, пока по ней есть active run (наблюдение).
- `socket.setdefaulttimeout(120)` НЕ прерывает зависший put в paramiko (канал создан до вызова) — заменён на `channel.settimeout(120)`.