Итак, это вторая часть моего взаимодействия с Glitch.com и в этой части пойдет речь уже о способах деплоя, как о стандартном, так и о не стандартном (который мне больше подошел, чем стандартный способ).
Историю моего знакомства с этим сервисом, вы можете почитать тут.
Импорт и экспорт из/в Git репозиторий
Очень крутая возможность, которая дает вам быстрый способ поставки на glitch.com
Привязать ваш репо можно также из Tools -> Git,Import, and Export
Ведь каждый проект на glitch.com — это тоже репозиторий, который можно скачать.
А так же мы видим возможность скачать проект в этом меню. А доступ к гит репозиторию возможен через следующий url https://api.glitch.com/git/your-project-name
Тоже очень удобно!
Но в моем случае, этот способ не работает, так как нужно установить разные настройки и пропатчить несколько файлов. Как я организовал не стандартный деплой на glitch.com— об этом, я и расскажу далее.
Нестандартный деплой на glitch.com
В любой нестандартной обстановке, вроде бы удобные возможности становятся бесполезными. И в любом таком случае, всегда стоит писать команду для package.json. И тут всегда встает вопрос — “На чем же писать данный скрипт? bash? Может сторонняя библиотека? Может make файл?”.
Но ответ на данный вопрос очень прост. Если язык программирования позволяет написать необходимый для вас скрипт, с удовлетворяющей функциональностью, то всегда предпочитайте написать скрипт на языке программирования вашего проекта. Это даст вам, в первую очередь, возможность без изучения дополнительного материала вникнуть в работу скрипта. И это очень удобно!
Я собственно так и сделал. Написал скрипт glitch.js для формирования архива с нужными файлами для поставки. Всегда удобнее собрать только необходимые файлы, откорректировать нужные настройки и создать один архив, в моем случае zip . Zip универсален и прост.
В скрипте, для сборки архива поставки, я использовал библиотеку archiver — что предоставляет удобный интерфейс для манипуляции с данными.
Ниже привожу стандартную часть для любого скрипта, использующего archiver .
const fs = require('fs');const archiver = require('archiver');const output = fs.createWriteStream(`glitch_release_${+new Date()}.zip`);const archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
});const DomainHost = 'your-project-host.glitch.me';output.on('close', () => {
// eslint-disable-next-line no-console
console.log(`${archive.pointer()} total bytes`);// eslint-disable-next-line no-console
console.log('archiver has been finalized and the output file descriptor has closed.');
});output.on('end', () => {
// eslint-disable-next-line no-console
console.log('Data has been drained');
});archive.on('warning', (err) => {
if (err.code === 'ENOENT') {
// log warning
// eslint-disable-next-line no-console
console.warn(err);
} else {
// throw error
throw err;
}
});archive.on('error', (err) => {
throw err;
});archive.pipe(output);
В данной части скрипта производится настройка вывода информации о процессе архивирования и названия файла для перенаправления потока, формируемого архиватором в этот файл. Для того, чтобы случаем не перезаписать какой-либо ранее созданный архив, я добавил отпечаток времени в название. Что добавило уникальности каждому создаваемому архиву.
Теперь перейдем к самому интересному — к возможностям archiver , которыми я незамедлительно воспользовался.
Возможности archiver
Теперь можно перейти к полезной нагрузке:
- Включить папкуviews
archive.directory('views/', 'views') — эта команда дает возможность добавить в архив папку со всем ее содержимым, и если нужно, еще и переименовать ее во втором параметре. Я не стал переименовывать и указал исходное имя.
- Включить файлы папки db за исключением файла db/teams.json так как в нем, нужно будет сделать некоторые твики.
archive.glob('db/**/*, { ignore: ['db/teams.json'] });
В данном случае, я использовал уже не directory , а glob, что позволяет без проблем указать какие файлы нужно исключить. Все опции библиотеки glob поддерживаются.
- Включить папку public
archive.directory('public/', 'public')
- Включить папку routes
archive.directory('routes/', 'routes')
- Включить файл бота — для того, чтобы можно было его запустить вместе с экспресс сервером.
archive.file('examples/rtmbot/index.js', { name: 'bot.js' });
Для добавления файла, используется метод file куда передается путь до него и если нужно переименовать, то и опции для файла, в данном случае { name: 'bot.js' } . Соответственно данный трюк, переносит файл index.js из подпапок в корень архива.
- Аналогичным образом включить еще несколько файлов
archive.file('package-lock.json', { name: 'package-lock.json' });
archive.file('README.md', { name: 'README.md' });
archive.file('server.js', { name: 'server.js' });
archive.file('helpers.js', { name: 'helpers.js' });
- Теперь нужно включить ранее исключенный файл db/teams.json в папку db . Для чего был произведен такой кульбит? Все из-за особенности работы архиватора, я не могу заменить уже включенный в архив файл. По этой причине приходится исключать файл из первичного добавления и затем отдельно обрабатывать и закидывать в нужное место в архиве.
const teams = JSON.parse(fs.readFileSync('./db/teams.json', 'utf8'));
teams[0].domain = DomainHost;
teams[0].email_domain = DomainHost;
archive.append(JSON.stringify(teams, ' ', 2), { name: 'db/teams.json' });
И получается, я читаю файл, изменяю необходимые значения в памяти и записываю изменения в текстовом виде в файл под названием { name: 'db/teams.json' }. Для записи любого текстового содержимого, необходимо использовать метод append с параметрами.
- Аналогичным образом я исправляю команду start в пакете package.json для того чтобы не добавлять туда ничего.
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
packageJson.scripts.start = `URL_SCHEMA=https ${packageJson.scripts.start}`;
archive.append(JSON.stringify(packageJson, ' ', 2), { name: 'package.json' });
- Указать архиватору, что мы завершили формирование содержимого архива.
archive.finalize();
Теперь наш архив для поставки готов и содержит только нужные файлы и ничего лишнего.
Процесс поставки созданного архива
Теперь нужно локально или в докере, воспользоваться запуском скрипта и создать файл архива для поставки.
- Добавим соответствующие команды в package.json
"glitch:pack": "node ./scripts/glitch.js",
"glitch:unpack": "unzip -o glitch_release_*.zip -d . && rm glitch_release_*.zip && refresh",
- Выполним команду npm run glitch:pack
В итоге у нас появится архив в корне проекта
У нас есть архив для поставки и для того, чтобы не использовать промежуточные хостинги для файла, воспользуемся встроенной возможностью glitch.com. И это папка assets.
Перейдем к странице нашего проекта и перетащим созданный архив в assets, что через drag-n-drop позволит загрузить файл.
Теперь мы можем наблюдать архив в папке assets
И теперь нужно перейти в консоль, но перед этим, нужно скопировать путь для архива в assets .
Для копирования URL нужно кликнуть на изображении архива и во всплывающем окне нажать на кнопку Copy. Все — теперь url до архива в памяти.
Переходим в консоль!
Действия в консоле
Нам понадобится wget для скачивания архива в докер из папки assets.
Переходим в Tools -> Full Page Console
Открывается консоль и мы вводим команду
wget -O glitch_release_1567145124325.zip https://cdn.glitch.com/b8270189-9c01-441b-9193-4f09ed636e4b%2Fglitch_release_1567145124325.zip?v=1567145294956
Что позволяет скачать файл архива внутрь контейнера
И теперь нам нужно выполнить команду
unzip -o glitch_release_*.zip -d . && rm glitch_release_*.zip && refresh
Для того, чтобы распаковать архив в корень папки проекта с заменой файлов, а также с удалением закаченного архива и выполнением команды refresh чтобы изменения были отражены в UI
Но эта большая команда нам понадобится только при первой развертке архива. В последующие разы нам поможет команда
npm run glitch:unpack
Которая выполнит вышеуказанную команду.
Таким образом произошла поставка! Теперь можно воспользоваться меню Show -> In New Window или Show -> Next to The Code
Заключение
Таким вот простым способом, вы можете создавать спец пакеты поставки, которые в отличии от экспорта репозитория, не внесут лишних файлов и позволяют изменить настройки без затрагивания исходных файлов. Так как не всегда есть возможность изменять какие либо настройки через переменные окружения.
Надеюсь в этой статье вы почерпнете что-то новое и полезное для применения в своей работе.
Ранее статья была опубликована тут.