nuckty-ext-command-deploy-ftp
Публикация собранного артефакта на виртуальный хостинг по FTP. Команда nuckty deploy-ftp [target] синхронизирует файлы по манифесту: отправляет на сервер только изменившиеся и удаляет лишние.
Тип
command — добавляет команду deploy-ftp через env.commands.
Что делает
Команда читает manifest.json из собранного артефакта, сравнивает манифест с файлами на сервере и передаёт только нужные изменения:
- Список файлов — рекурсивный запрос
LISTвозвращает соответствие «путь → размер», по которому команда сверяет файлы. - Манифест сервера — без
--forceсуществующийmanifest.jsonскачивается для сравнения хэшей. Если его нет, загружаются все локальные файлы;--forceпропускает скачивание. - Расчёт изменений — команда находит новые, изменённые и удалённые файлы. Хэши сравниваются только при совпадении размеров.
- Защита от случайной очистки — если доля удаляемых файлов превышает порог (по умолчанию 30%), команда останавливается и подсказывает воспользоваться
--force. - Загрузка — только изменившиеся файлы. Пассивный режим; по умолчанию обычный FTP, при включении — явный FTPS. После каждой загрузки команда пробует сохранить время изменения через
MFMT; отсутствие поддержки этой команды не останавливает публикацию. - Удаление лишних файлов на сервере — файлы, которых больше нет в артефакте, команда удаляет (
manifest.jsonне трогает). - Проверка и повтор — после передачи команда снова выполняет
LISTи при сбое повторяет загрузку. - Манифест — последним —
manifest.jsonзагружается после того, как все файлы успешно переданы.
Опции
nuckty deploy-ftp [target] [--force] [--dry-run]
| Опция | Действие |
|---|---|
target | Имя таргета из config-nuckty.ts. Без аргумента — первый таргет. |
--force | Загрузить все локальные файлы и обойти защиту от массового удаления; удаление лишних файлов сохраняется. |
--dry-run | Показать, что было бы загружено или удалено, без реальных действий. |
--dry-run подключается к серверу и читает его состояние, но не меняет файлы. Публикация не атомарна: переданные файлы могут остаться при последующей ошибке; итоговый манифест передаётся только после успешных операций.
Аутентификация
Учётные данные берутся из config/auth-ftp.json или полного набора FTP_HOST, FTP_USER, FTP_PASSWORD, FTP_PATH; необязательны FTP_PORT и FTP_SECURE. Полный набор окружения имеет приоритет. Файл с секретами исключают из репозитория. Пример:
{
"host": "ftp.example.ru",
"user": "user",
"password": "...",
"remote_path": "/public_html",
"port": 21,
"secure": true
}
В CI передавайте учётные данные через переменные окружения. Если используете auth-ftp.json, исключите его из контроля версий: файл содержит настоящие учётные данные.
Ограничения целевого хостинга
Сервер должен предоставлять доступ по FTP или FTPS. SSH, rsync и Git на сервере не нужны. Расширение использует:
- basic-ftp — клиент с поддержкой пассивного режима и TLS (FTPS), без SSH.
- MFMT — восстановление времени изменения через команду FTP, а не через SSH.
- Синхронизация по манифесту — сравнение по хэшам вместо rsync.
Совместимость определяется протоколом передачи, а не классом сервера. Подробнее — в решении о хостинге.
Установка
Пример продолжает быстрый старт со стандартным обработчиком nuckty-ext-block-root. Добавьте новое расширение в ext глобального config/config-nuckty.ts, сохранив остальные записи. Если обработчик документа собственный, оставьте его вместо nuckty-ext-block-root.
Команда ниже выполняется из распакованного стартового проекта: готовые архивы расширений находятся в packages/.
npm install ./packages/nuckty-ext-command-deploy-ftp-1.0.0-beta1.tgz
import { defineNucktyConfig } from 'nuckty';
export default defineNucktyConfig({
targets: { main: { configDir: 'config/', outDir: 'site/' } },
ext: ['nuckty-ext-block-root', 'nuckty-ext-command-deploy-ftp'],
});
Ядро не зависит от basic-ftp — зависимость живёт только в этом расширении.
Перед соединением команда сверяет размер и MD5 каждого локального файла с манифестом. Перед последней отправкой манифеста она повторяет проверку и отклоняет изменившийся артефакт. Проверка на сервере использует LIST и размер; независимого подтверждения удалённого хеша нет. Во время публикации артефакт менять нельзя.
secure: true или FTP_SECURE=true включает FTPS с проверкой сертификата; ошибка TLS не вызывает переход к обычному FTP.