Принцип «в одну команду» в Evercode Lab мы впервые применили для настройки деплоймента проектов. Нашим инструментом для этого вопроса практически для всех проектов стала замечательная утилита capistrano (либо ее модификации, например, capifony для Symfony2). И вот уже два года, практически с самого начала существования компании, мы внимательно следим, чтобы для деплоймента любого нашего проекта достаточно было набрать в командной строке cap deploy или cap deploy:migrations.

Какое-то время назад, после просмотра презентации Зака Холмана (Zach Holman) про организацию работы в компании GitHub, мы решили, что деплоймент — не единственная частая задача, которая достойна применения этого принципа. Наша команда по-прежнему не очень большая, количество проектов при этом уже достаточно большое. По многим из них задачи появляются уже не так часто, конечно. Но каждый из нас так или иначе задействован на нескольких проектах. При таком положении дел неизбежно заметное количество времени тратится на переключение между проектами, обновление их локально до актуального состояния. Плюс к этому между проектами различаются и технологии: часть проектов на Symfony2, часть на Ruby on Rails, периодически появляются и другие фреймворки и технологии. Эту проблему мы и захотели решить.

В своем выступлении Зак рассказывал, что любой проект в GitHub имеет один простой скрипт bootstrap, который по сути выполняет абсолютно все действия по установке проекта: установка зависимостей, настройка баз данных, прогон миграций, установка фикстур и прочие необходимые действия.

Эта простая идея нам очень понравилась. И теперь почти для каждого проекта у нас есть специальный набор скриптов, который облегчает выполнение повторяющихся действий. Самые частые из них:

  • bit/setup — установка проекта начисто
  • bin/update — обновление проекта до актуального состояния
  • bin/start [—update] — запуск локального сервера, ключ —update позволяет автоматом сразу выполнить и bin/update

Из других популярных автоматизированных задач — проверка проекта на соответствие code standards, которая обычно зашита на bin/check_cs.

Примеры содержимого этих файлов для одного из наших проектов на Symfony2 приведены ниже. Наряду с полноценным README они существенно облегчают эпизодическую работу над проектом, либо переключение на него с другого. Стоит уточнить, что все мы работаем на маках, поэтому скрипты на данный момент проверены на совместимость только с OS X.

Следующим шагом автоматизации мы планируем также решить вопрос одинакового окружения, настроив для каждого проекта конфигурацию виртуальной машины с помощью vagrant, но над этим мы пока еще работаем.

Нам было бы интересно узнать, что и как делаете вы в контексте этой проблемы?

Пример bin/setup для Symfony2 проекта:


#!/bin/sh
cmd='php app/console'

# create necessary dirs
# and then set proper rights for created dirs
directories=(app/cache app/logs web/uploads)
USER=$(whoami)
APACHE_USER=$(ps axho user,comm|grep -E "httpd|apache"|uniq|grep -v "root"|awk 'END {print $1}')
createdir() {
mkdir -p $1
echo "- $1 has been created"
}
chcache () {
sudo chmod +a "$USER allow delete,write,append,file_inherit,directory_inherit" $1
sudo chmod +a "$APACHE_USER allow delete,write,append,file_inherit,directory_inherit" $1
echo "- $1 has been properly chmod'ed for $USER and $APACHE_USER"
}
for directory in directories; do
if [ ! -d $directory ]; then
createdir $directory
fi
if [ -d $directory ]; then
chcache $directory
fi
done

# set configuration
if [ ! -e app/config/parameters.yml ]; then
cp -n app/config/parameters.yml.dist app/config/parameters.yml
echo "- default config copied"
if [ ! "$EDITOR" ]; then
read -p "enter your favourite editor: " EDITOR
fi
$EDITOR app/config/parameters.yml
echo "- config is set"
fi

# composer stuff
COMPOSER_BIN=composer
command -v $COMPOSER_BIN >/dev/null 2>&1 || {
echo "system wide composer not found; installing local"
curl -s https://getcomposer.org/installer | php
COMPOSER_BIN="php composer.phar"
}
$COMPOSER_BIN install --dev
echo "- composer dependencies installed"

# databases stuff
$cmd doctrine:database:drop --force --quiet
$cmd doctrine:database:create
$cmd doctrine:migrations:migrate --no-interaction
$cmd doctrine:fixtures:load --no-interaction
$cmd assets:install
$cmd assetic:dump

Пример bin/update для Symfony2 проекта:


#!/bin/sh

cmd='php app/console'

git pull

# composer stuff
COMPOSER_BIN=composer
command -v $COMPOSER_BIN >/dev/null 2>&1 || {
COMPOSER_BIN="php composer.phar"
}
$COMPOSER_BIN install --dev

# databases stuff
$cmd doctrine:migrations:migrate --no-interaction
$cmd assets:install
$cmd assetic:dump

Пример bin/start для Symfony2 проекта:


#!/bin/sh

UPDATE_FLAG="--update"
if [ "$1" = "$UPDATE_FLAG" ]; then bin/update; fi

for port in {8000..8010}
do
result=`lsof -i :$port`
if [ -z "$result" ]; then break fi
done

app/console server:run -v localhost:$port