Conversion, software version 7.0

Немного лирики.

Как и обещал занялся написанием пары топиков по оптимизации работы. Честно говоря серия должна была начаться отнюдь не с данной статьи, но так получилось что именно этот топик станет первым. Надеюсь у читателей есть представление о том, что такое SVN, если нет то лучше прочитать эту статью немного позже, так как немного позже будет опубликована статья под названием «Оптимизация работы или что нужно программистам для плодотворной работы» **(название взято из головы для раскрытия сути) в которой будет опубликовано мое мнение по тому, как оптимизировать работу работников небольшой компании которая только открылась. Ладно опустим лирику перейдем к теме топика.

Вам что-нибудь говорит название статьи? Нет это не относится к песне группы System Of A Down — Toxicity и сегодня мы будем говорить не об песнях, а о том зачем и что такое верисии(в дальнейшем тэги) и каким образом они относятся к оптимизации работы.

То с чего следовало начать.

Сразу хочу заметить к написанию данной статьи меня сподвигло то, что я встречал некоторые небольшие конторы которые занимаются довольно крупными интернет проектами, но на создание версий продукта они грубо говоря забивают. Прежде чем говорить «как лучше» давайте разберемся зачем все это:

  • Создавая версии продукта и переходя от тега к тегу мы будем знать какие баги закрыты, а какие еще весят.
  • Мы в любой момент сможем откатить продакшн версию назад к более стабильной версии(если проект уже функционирует и дописывается «по ходу»).
  • Замена старой версии проекта на новую и обратно будет происходить за считанные доли секунды и безболезненно.

Из написанного выше можно сделать вывод, что версия проекта это более менее стабильная копия проекта с закрытыми багами или с новыми «фичами». Версия проекта это обычно трех значное число разделенное точками например 3.1.2. Первая цифра изменяется при внесении в код больших изменений затрагивающих структуру проекта, вторая меняться при введении менее крупных изменения, но которые все же существенны и третья цифра меняется при закрытии багов или внесении правок. Обычно последняя цифра меняется при закрытии 10-15 багов **(так при использовании систем контроля версий мы всегда сможем узнать в каком тэге был закрыт баг).

Такое бывает?

Итак у нас уже во всю используется Subversion, но все выглядит примерно так: один сотрудник меняет код, потом в лучшем случае кто-то тестит и потом правки выкидываются на продакшн или просто делается update. Хочу заметить, что данная схема довольно опасна, тем что если были сделаны правки и появились новые баги мы не сможем безболезненно откатится назад, скорее всего будет тратится время на то, что-бы новые баги исправить, а в это время проект будет лежать, чего мы ну не как не хотим.

Как быть???

Итак смотрим какие существуют общепринятые «правила хорошего тона» для структуры директорий в файловой системе хранилища. В простейшем случае в корневой директории файловой системы имеются как минимум три директории:

/branches
/tags
/trunk

Директория trunk содержит «рабочую» версию проекта в которой и ведется вся разработка, branches содержит ветви проекта **(можно сказать, что тут создаются временные ветви которые перетекают потом в основную ветвь), tags содержит все метки. Такая структура удобна для хранилища, содержащего только один проект. Если проектов несколько, то более удобна следующая структура:

 /project1
   /branches
   /tags
   /trunk
 /project2
   /branches
   /tags
   /trunk

то есть в корневой директории находятся директории проектов, и в каждом из них есть свои trunkbranchestags, относящиеся только к этому проекту.  Хотя это все не является догмой и это все можно организовать как угодно **(только без лишнего фанатизма:)

Так вот нам в нашем случае нам интересны ветви trunk и branches, собственно мы и будем создавать тэги в branches из рабочей ветви trunk с помощью команды copy которую разработчики Subversion добавили в функционал svn. Синтаксис выглядит так:

svn copy http://server.my/svn/trunk http://server.my/svn/tags/tag_name -m "Наша первая стабильная версия 1.0.0!"

В результате мы получаем работающие копии проекта, которые мы можем выставить в качестве релиза.

Ха где гибкость?

Для того, чтобы все работало «как надо» следует перенастроить apache так что-бы DocumentRoot вел на симлинк, а последний в свою очередь на копию из ветки tags.

Например:

DocumentRoot /var/www/site.my/release/

release -> /var/www/site.my/1.0.1

Получается что бы заменить старую версию 1.0.1 на более новую 1.0.2 нужно всего то выполнить команду checkout и подменить симлинк

svn checkout http://server.my/svn/tags/1.0.2
rm /var/www/site.my/release
ln -s /var/www/site.my/1.0.2 /var/www/site.my/release

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

Много действий? :(

Как вариант можно сделать скрипт который будет делать выше описанные действия автоматически:) Привожу как пример bash скрипт который умеет создавать теги, делать чекаут, и менять симлинки

#!/bin/bash
# this properties should be change
# ########################
#каталог где будет установлен проект
PROJECT_INSTALL_ROOT=/var/www/site.my
#svn репозеторий тут!
SVN_REPOS=http://server.my/svn
function InstallFun {
echo «Введите версию проекта для установки:»
read version
echo «Вы действительно хотите установить версию $version? (y/n)»
read answer
if [ «$answer» = «y» ]; then
svn co «${SVN_REPOS}/tags/${version}»   «${PROJECT_INSTALL_ROOT}/${version}»
else
echo «Skip! Press Enter.»
read null
break
fi
echo «Press Enter that would see the menu.»
}
function TagsFun {
echo «Введите версию проекта для создания тэга:»
read version
echo «Вы действительно хотите создать тэг $version? (y/n)»
read answer
if [ «$answer» = «y» ]; then
svn copy «${SVN_REPOS}/trunk»  «${SVN_REPOS}/tags/${version}»
else
echo «Skip! Press Enter.»
read null
break
fi
echo «Press Enter that would see the menu.»
}
function Change_releaseFun {
echo «Введите версию релиза:»
read version
echo «Вы действительно хотите использовать версию из тэга $version? (y/n)»
read answer
if [ «$answer» = «y» ]; then
rm  «${PROJECT_INSTALL_ROOT}/release»
ln -s «${PROJECT_INSTALL_ROOT}/${version}» «${PROJECT_INSTALL_ROOT}/release»
else
echo «Skip! Press Enter.»
read null
break
fi
echo «Press Enter that would see the menu.»
}

echo «Project installer version 0.0.7»

echo «Выберите пункт меню:»

OPTIONS=»Install Tags Change_release Quit»

select opt in $OPTIONS; do

if [ «$opt» = «Quit» ]; then

exit 1

elif [ «$opt» = «Install» ]; then

InstallFun

elif [ «$opt» = «Tags» ]; then

TagsFun

elif [ «$opt» = «Change_release» ]; then

Change_releaseFun

else

echo «bad option»

fi

echo «»

done

На самом деле для своих целей использую ant в котором автоматически меняются конфиги, создаются нужные директории,  устанавливаются права и тп. Даже не потому, что нельзя повторить на bush, а потому, что так повелось:) и некоторые вещи делаются немного удобнее там.

Кто тут? ЧТо тут происходит??

Ну вот вроде изложил то, что хотел… Хочу заметить, что данную статью не следует расценивать как призыв к тому, как нужно жить, эта статья о том как можно было бы сделать если этого уже не сделано или не найден вариант лучше.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *