Деплой ассетов CI через sftp
Синопсис
На заключительном этапе подготовки верстки для сайта при запуске npm run build мой вебпак готовит папку dist следующим образом:
- assets - css • app.9a8dva.css - js • app.9a8dva.js
Затем я подключаюсь по ftp, закидываю в соотвествующие папки эти файлы. В админке MODx в расширении ClientConfig обновляю поле хэша, в данном случае "9a8dva". (в чанках ассеты используют настройку 22cee16c7130d01c668b и это решает проблему вредного кэша)
Все это занимает может минуту, но.
При переносе верстки на движок постоянно вылезают какие-то косячки. И процесс становится ощутимо болезненным по времени. Поэтому я решил его немного автоматизировать.
Нам понадобится:
- clean-webpack-plugin, если у вас webpack < 5
- webpack-shell-plugin
- кусочек putty под названием psftp, если у вас винда
Качаем, пачаны!
Поскольку у меня конфиг вебпака разбит на 2 части, для разработки и билда, то в последний под названием webpack.build.conf.js импортируем и используем плагины:
const WebpackShellPlugin = require('webpack-shell-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
new CleanWebpackPlugin(),
new WebpackShellPlugin({
onBuildStart:['echo • Start building awesome'],
onBuildEnd:['bash deploy/start.sh']})]
})
Итак, один плагин чистит папку билд перед билдом. Второй запускает скрипт bash после того как все сбилдилось.
Создадим папку deploy в корне проекта с такой структурой:
- psftp.exe - s.scr - start.sh
Где s.scr - файл с командами для psftp. Содержимое файлов:
start.sh
#!/usr/bin/env bash
p="/mnt/host/c/Users/user/Desktop/WEBPACK PROJECTS/site.local/deploy/"
s="C:\Users\user\Desktop\WEBPACK PROJECTS\site.local\deploy\\"
"${p}psftp.exe" -pw password user@by143.net -b "${s}s.scr" -be
c="/mnt/host/c/Program Files/Git/mingw64/bin/curl.exe"
"${c}" -k https://dev.site.by/assets/php/assets_hash_update.php
В переменные p,s,c я засунул пути. Обратите внимание, что у p есть некий префикс "/mnt/host/", думаю это из-за того, что внутри вэбпака код выполняется. При запуске этого же кода через обычную консоль, путь без этой приставки.
В переменной s путь в "виндовс стиле" с бэкслешем в конце.
По итогу мы запускаем утилиту psftp.exe, передаем ей пароль, пользователя и хост. -b говорит нам использовать файл с командами, а -be велит игнорировать ошибки, если что.
В переменной «с» путь к curl. Появляется после установки утилиты гита. И вебпак не может прочесть глобальную переменную curl во время процесса билда, поэтому мы указываем ту же приставку "/mnt/host/"
В последней строке мы дергаем php скрипт, который прочитает файлы в директории css, вытащит оттуда хэш и обновит поле hash в clientConfig-e
s.scrcd /home/user/www/dev.site.by/assets/ del css/* del js/* put -r "C:\Users\user\Desktop\WEBPACK PROJECTS\site.local\dist\assets\css" put -r "C:\Users\user\Desktop\WEBPACK PROJECTS\site.local\dist\assets\js" exitСначала мы переходим в папку ассетов сайта, удаляем их содержимое, затем копируем свежесобранные файлы командой put assets_hash_update.php
define('MODX_API_MODE', true);
require '../../index.php';
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$path = $modx->getOption('core_path') . 'components/clientconfig/processors/';
$props = array( 'processors_path' => $path);
$dir = $_SERVER["DOCUMENT_ROOT"]."/assets/css/";
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
if($file !== "." && $file !== ".."){
$hash = explode(".",$file)[1];
if(strlen($hash)){
$_POST = array('values' => '{"hash":"'.$hash.'"}' );
$modx->runProcessor('mgr/settings/save', $_POST, $props);
echo 'Hash '.$hash.' is applied';
} else {
echo 'Can not update hash';
}
}
}
closedir($dh);
}
}
На сервере мы будем использовать MODx API, чтобы ручками не подключаться к базе данных. Итак, еще раз - мы читаем файл в каталоге css, точнее бежим по всем файлам циклом. Берем попавшийся файл, бьем его имя по точкам, и первым элементом массива получаем искомую строку. В переменной с обязательным странным названием $_POST лежит строка типа json, где "hash" название поля в админке в дополнении ClientConfig, которое мы и будем обновлять выцепленной выше строкой, лежащей в переменной $hash.
Заключение
Собственно, все. Если у вас не будут выпадать сетевые ошибки, то каждый npm run build будет обновлять файлы и поле конфигурации в админки. Поздравляем! Вы великолепны!