deploy – Stepan Suvorov Blog https://stepansuvorov.com/blog Release 2.0 Thu, 22 Oct 2015 08:02:05 +0000 en-US hourly 1 https://wordpress.org/?v=6.3.1 Git pre-push hook https://stepansuvorov.com/blog/2015/03/git-pre-push-hook/ https://stepansuvorov.com/blog/2015/03/git-pre-push-hook/#respond Fri, 13 Mar 2015 19:40:07 +0000 http://stepansuvorov.com/blog/?p=2166 Continue reading ]]> Я уже писал о том как можно использовать git хуки для запуска grunt команд и делать предварительную проверку перед заливкой кода в главный репозиторий. В этой заметке я покажу, как можно избежать проверки не закомиченных изменений.

Git pre-push hook будет выглядеть вот так:

[shell]
#!/bin/sh
grunt test
RETVAL=$?
if [ $RETVAL -ne 0 ]
then
echo "Grunt task failed, exiting…"
exit 1
fi

echo "Complete."
[/shell]

Как видите ничего сложного. Теперь при каждом пуше будет вызываться “grunt test“. Важно не забыть сделать этот файл исполняемым (chmod +x pre-push)

Есть еще один момент: когда вы попытались запушить поломанный код – тесты не прошли – вы починили код, но при этом забыли закоммитить – тесты прошли – и поломанный код попал на сервер (так как фикс не был закоммичен).

Поэтому перед началом тестов прячем все незакоммиченные изменения (git stash), а потом возвращаем их назад:

[shell]
#!/bin/sh
CHANGES=$(git diff –numstat | wc -l)
CHANGES_CACHED=$(git diff –cached –numstat | wc -l)
TOTAL_CHANGES=$(($CHANGES + $CHANGES_CACHED))

git stash -k
grunt test

RETVAL=$?

if [ $TOTAL_CHANGES -ne "0" ]
then
echo "Popping" $TOTAL_CHANGES "changes off the stack…"
git stash pop -q
fi

if [ $RETVAL -ne 0 ]
then
echo "Grunt task failed, exiting…"
exit 1
fi

echo "Complete."
[/shell]

Полный код тут. Идея взята от сюда.

]]>
https://stepansuvorov.com/blog/2015/03/git-pre-push-hook/feed/ 0
В поисках сервиса для деплоя https://stepansuvorov.com/blog/2015/03/deploy-service/ https://stepansuvorov.com/blog/2015/03/deploy-service/#comments Tue, 03 Mar 2015 19:18:11 +0000 http://stepansuvorov.com/blog/?p=2143 Continue reading ]]> semaphore-logo  dploy-logo  ftploy-logo  codeship-logo

На данным момент мы для своего проекта используем semaphore. Этот же сервис я использую и для своих личный проектов. Задача на него ставиться простая: при каждом пуше в мастер – выливаем код в продакшен, предварительно выполнив тесты и подготовив билд.

Из-за периодических тормозов, отсутствия возможности создания общей конфигурации для нескольких приложений (в нашем случае у нас 7 разных приложений, которые собираются и деплоятся одними и теме же командами, через один и тот же распределяющий сервер) и не совсем интуитивного интерфейса, задался вопросом: есть ли что-то более интересное, при этом по прежнему легкое и дружелюбное (читать бесплатное) по отношению к опенсорс.

Попробовали как альтернативу использовать Codeship – не понравилось.

Потом еще наткнулся на dploy и ftploy – не впечатлило.

Если у вас есть опыт успешного использования какого-либо подобного сервиса – поделитесь пожалуйста в комментариях.

 

UPD: после того как узнал, что в semaphore можно делать даже так:

[shell]sudo apt-get install -yqq ftp[/shell]

решил пока остаться на нем.

]]>
https://stepansuvorov.com/blog/2015/03/deploy-service/feed/ 3
Разворачиваем базу проекта на JavaScript https://stepansuvorov.com/blog/2014/04/%d1%80%d0%b0%d0%b7%d0%b2%d0%be%d1%80%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%b1%d0%b0%d0%b7%d1%83-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0-%d0%bd%d0%b0-javascript/ https://stepansuvorov.com/blog/2014/04/%d1%80%d0%b0%d0%b7%d0%b2%d0%be%d1%80%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%b1%d0%b0%d0%b7%d1%83-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0-%d0%bd%d0%b0-javascript/#comments Wed, 09 Apr 2014 19:59:28 +0000 http://stepansuvorov.com/blog/?p=1607 Continue reading ]]> Растут JavaScript проекты и соответственно становятся лучше инструменты сборки. Самое время задуматься о разворачивании базы своего проекта на JavaScript. А ведь и правда: если проект написан 100% на одной технологии (да, и сервер тоже), зачем думать о другой технологии для разворачивания базы?

Вот с такими мыслями я и начал исследовать данный вопрос с целью найти удобное решение для своего пэт-проектика (стек: JavaScript/AngularJs – JavaScript/Express – MySql). JavaScript сообщество (а точнее Андрей Листочкин), посоветовало обратить внимание на модуль для ноды db-migrate и плагин для гранта grunt-db-migrate. Пост является набором заметок по ходу внедрения модуля в проект.

На данный момент db-migrate поддерживает Mysql,  PostgreSQLsqlite3. Поэтому, если вы хотите мигрировать другую базу – придется либо писать самому скрипт миграции либо использовать другое решение.

Установка

Устанавливаем модуль ноды и плагин гранта:

$ npm install db-migrate
$ npm install grunt-db-migrate

Настраиваем grunt

В grunt файле добавляем блок:

[javascript]migrate:{
options:{
env: {
DATABASE_URL: databaseUrl
}
}
}[/javascript]

databaseUrl – строка подключения к базе, например:

[javascript]
databaseUrl = ‘mysql://root:@localhost/mypetdb’;
[/javascript]

Создаем файл миграции

Чтобы создать файл миграции(с шаблоном внутри) выполняем команду:

$ grunt migrate:create:migrate_name

После чего у нас в проекте появится директория “migrations”, и файл в ней с таким содержимым:

[javascript]var dbm = require(‘db-migrate’);
var type = dbm.dataType;

exports.up = function(db, callback) {

};

exports.down = function(db, callback) {

};[/javascript]

exports.up – инструкции для наката изменений, export.down – соответственно для отката сделанных изменений.

Разберем пример предложенный на офсайте:

[javascript]
exports.up = function (db, callback) {
db.createTable(‘pets’, {
id: { type: ‘int’, primaryKey: true },
name: ‘string’
}, callback);
};

exports.down = function (db, callback) {
db.dropTable(‘pets’, callback);
};
[/javascript]

Вроде бы все просто: db.createTable() – добавляем таблицу, db.dropTable() – удаляем.

Свойства, который можно определять для полей:

  • type – тип данный, полный список поддерживаемых типов тут
  • length – размерность (там где поддерживается)
  • primaryKey [true/false]
  • autoIncrement [true/false]
  • notNull [true/false]
  • unique [true/false]
  • defaultValue

Список поддерживаемых методов:

  • createTable(tableName, columnSpec, callback)
  • dropTable(tableName, [options,] callback)
  • renameTable(tableName, newTableName, callback)
  • addColumn(tableName, columnName, columnSpec, callback)
  • removeColumn(tableName, columnName, callback)
  • renameColumn(tableName, oldColumnName, newColumnName, callback)
  • changeColumn(tableName, columnName, columnSpec, callback)
  • addIndex(tableName, indexName, columns, [unique], callback)
  • insert(tableName, columnNameArray, valueArray, callback)
  • removeIndex([tableName], indexName, callback)
  • runSql(sql, [params,] callback)
  • all(sql, [params,] callback)

Запуск

Теперь grunt может выполнить задачу:

$ grunt migrate:up

и чтобы откатить изменения:

$ grunt migrate:down

создать новый файл миграции:

$ grunt migrate:create:migration_name

Дополнительно

Когда нам нужно создать несколько таблиц, удобно использовать модуль async:

[javascript]
var async = require(‘async’);

exports.up = function (db, callback) {
async.series([
db.createTable.bind(db, ‘pets’, {
id: { type: ‘int’, primaryKey: true },
name: ‘string’
}),
db.createTable.bind(db, ‘owners’, {
id: { type: ‘int’, primaryKey: true },
name: ‘string’
});
], callback);
};
[/javascript]

метод async.series позволит избежать вложенности

Пример из реальной жизни

Вот файл миграции, который я создал для своего пет-проектика:

[javascript]
var dbm = require(‘db-migrate’);
var async = require(‘async’);

exports.up = function (db, callback) {
async.series([
db.createTable.bind(db, ‘marks’, {
user_id: {
type: ‘int’,
notNull: true
},
release_id: {
type: ‘int’,
notNull: true
},
feed: {
type:’string’,
notNull: true
}
})
], function(){
db.addIndex(‘marks’, ‘usermark’, [‘user_id’, ‘release_id’], true);
callback();
});
};

exports.down = function (db, callback) {
async.series([
db.dropTable.bind(db, ‘marks’, {
ifExists: true
}),
db.removeIndex(‘marks’, ‘usermark’),
], callback);
};
[/javascript]

Проект портировался с локальной mysql базы на postgress, которая стояла на сервере. Особых косяков модуля db-migrate замечено не было. Можно отметить только мелкие неудобства, которых характерны для любых универсальных (кросс-субд) систем миграции – отсутствие реализации специфических типов: у меня изначально был тип ENUM, который пришлось перевести в STRING. Для личного проекта это нормальная замена, но для продакшена пришлось бы писать отдельный дополнительный конвертер.

Более подробно можно почитать на офсайте либо покопать код.

]]>
https://stepansuvorov.com/blog/2014/04/%d1%80%d0%b0%d0%b7%d0%b2%d0%be%d1%80%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%b1%d0%b0%d0%b7%d1%83-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0-%d0%bd%d0%b0-javascript/feed/ 1