Как стать автором
Обновить

Комментарии 46

По поводу миграций — рекомендую обратить внимание на штуку под названием FluentMigrator, позволяет писать миграции вида:
[MigrationDate (2013, 8, 17, 19, 50)]
public class MyMigration : Migration
{
	public override void Up ()
	{
		Create.Table ("GnsTags")
			.WithColumn ("EntryKind").AsEnum ("Merchandise", "Advertisement").NotNullable ()
			.WithColumn ("EntityId").AsUInt32 ().NotNullable ()
			.WithColumn ("Tag").AsString ().NotNullable ();
		Create.Column ("IsDeleted").OnTable ("GnsGoods").AsBoolean ().NotNullable ();
	}
	public override void Down ()
	{
		//Тут код отката в том же стиле
	}
}
Поддерживает несколько движков БД. Из минусов могу назвать только тот факт, что миграции всё же приходится писать вручную.
Есть программа, которая сама сгенерирует миграции по схеме бд (mssql — другие СУБД не проверял). Правда, я, как новичок в разработке, не могу сказать, насколько оптимально/оптимизировано происходит генерация.
Вообще, все предлагаемые структуры VCS преследуют одну цель: избежать ситуации, когда ветка разработки не стабильно, а совершенно необходимо что-то быстро «пофиксить» или «допилить» и выложиться.


Лично мне нравится, когда в VCS одна общая ветка, а бранчи создаются из истории при необходимости (а не сразу после релиза). Так значительно проще.
Да, я тоже против создания лишних веток. Где-то на хабре была статья, объясняющая почему Github не использует git workflow: как раз из-за оверхеда с бренчами. Принудительное создание веток хорошо работает, когда разграничены права на публикацию разных окружений или когда разработчиков очень много.
Мне вот интересно, почему в каждой статье про CI забывают упомянуть про то, что бывают gated checkins, когда код, который не проходит тесты, просто не попадает в репозиторий? Это (очень) резко уменьшает количество сломанных билдов в CI и вообще битого кода в репозитории.
Вы когда-нибудь видели GC в крупных проектах, а не коде с одной сборкой? :) Гораздо более распространенная практика — не давать деплоить куда-либо при непрохождении некоего code-quality билда.
Вот по этому и не упомянул.
я видел, на текущем проекте именно так и работаем.
это адъ.
Я не просто видел, я так работаю. И в чем проблема?

Как раз наоборот, на коде, где больше одной сборки, это становится критичным, потому что зависимостей больше, и учесть их все становится сложно.
Вижу у себя на работе. Что не так с крупными проектами?
Ну, с точки зрения разработчика все шикарно: пушнул и пол-часа куришь. Время адекватного реагирования на изменения в коде возрастает в разы. И смысла немного. С точки зрения безопасного кода на проде (тесте и и.п. ) гораздо лучше тот вариант, что я описал.
А что мешает мощности-то нарастить? Слава б-гу, билд-сервера дешевле разработчиков.

Ну и да, правило большого пальца: пречекин должен выполняться за пять минут. Если это не так — вы либо правите тесты, либо сокращаете тесты, либо наращиваете мощности. Либо комбинируете подходы.
Наше бух-приложение хреново работает на 32-процессорном сервере, что мы лохи, что ли, давайте затарим прайват клауд, да, слыхал такое. К успеху идете :)
Специально для таких комментариев был первый пункт: «правите тесты».
Обычно, при начальной оценке проекта, некоторая доля времени выделяется на не-функциональные риски и нужды(ну там, заболеет кто, инфраструктуру надо настроить, в конце-концов, никто в команде не работает 8 из 8 часов в день и т.п.), но вот правда, ни разу не слышал, чтобы кто-то закладывал время на правку юнит-тестов, потому что они сильно медленные или тяжелые. Какой в этом смысл? Зачем за это платить заказчику? Юнит тесты могут хоть 2 часа работать, главное, чтобы выполняли свою роль, а для долгих тестов всегда есть nightly builds.
Знаете, я тоже не слышал, чтобы при начальной оценке проекта закладывали время на правку производительности кода…

Ну и да, если вы считаете, что юнит-тесты могут хоть два часа работать — значит, вы не понимаете роли юнит-тестов. Никто не будет гонять тест-сьют, который идет два часа, а значит, весь смысл потерян.
Да, я дейтсвительно считаю, что если в проекте есть UT, их много и они в сумме работают 2 часа — то это ОК. Опять же, напомню, мы говорим о больших проектах. Обычный девелопер, работая с модулем ранит небольшой сьют, которые отрабатывает за 2-5 минут, после чего он спокойно может коммитать свои изменения. Ну ОК, про 2 часа я может переборщил, но доводилось видеть .Net проекты, на которых билд с юнит-интегрейшн-тестами длился 1.5 часа. Для других платформ просто билд может идти весьма долго ;)
Вот не надо путать юнит-тесты и интеграционные тесты? Если у вас все юнит-тесты на проекте идут два часа — выделяйте BVT и гоняйте только их.

(а вообще это все прекрасно описано что у Мезароса, что у Хамбла/Фарли)
Да что же Вы все передергиваете? :) Где я по-вашему спутал U|I tests? Верификейшн тесты естественно выделяются и естественно именно они ранятся на code-quality builds. Но, я пытаюсь Вам сказать, что не всегда даже билд укладывается в 5 минут (просто билд без всяких bvt). Если, конечно, у Вас некомпилируемый язык, то тут гораздо все проще.
Не укладывается именно билд — ищите железо, ищите способы оптимизации.

(знаете, наверное, поговорку про «кто хочет»?)

Тут, как бы, очередные весы — либо вы тратите силы на то, чтобы сделать работающий пречекин, либо вы тратите силы на поиск багов на этап позже, чем могли бы. Выбор ваш.

Главное — не говорить, что если у вас пречекины не работают, то они нигде не заработают.
Заработают, да, на небольшом коде, либо на python'e/php. А по-поводу железа, мне было бы интересно посмотреть за просьбами выделить новый сервер под билд-машину, вернее, посмотреть на лицо ПМа/заказчика в этот момент.

ОК, ладно, не буду спорить, я Вашу точку зрения понял.
Заказчику до этого вообще дела нет, РП — тоже. Это обычно проблемы собственного инфраструктурного отдела компании, приблизительно того же, где «нам не хватает места на сервере БД» и «дайте сервер под VCS».

Когда нам понадобилось, мы сравнительного легко нашли не один, а четыре билд-агента.
А можете поделиться, на каком стеке вы работаете, сколько проектов в солюшне, сколько тестов, сколько агентов, сколько разработчиков, одна ветка разработки или бренч на фичу/команду?
.net, 35 проектов, 34 тестовых проекта, порядка тысячи тестов, гоняется две трети. Разработка на мейнлайне. Четыре или пять билд-агентов с разными задачами.

Остальное, извините, NDA.
Что-ж, здорово, что есть позитивный пример такого сетапа. Мне больше нравится подход, когда команда комитит в свой бренч, дальше тимлид/другое ответственное за ревью лицо ревьюирует код только потом идет мерж.
Со временем стал приходить к мысли, что никакие технические ограничения не смогут сделать команду лучше. Если разработчики заливают битый код и уходят домой, то это должно решаться не техническими средствами, а увольнением таких «специалистов».
К сожалению, ревью кода и мерж — это боттлнек перед релизом. Именно поэтому мы отказались от этой практики.
Что-то вы все в кучу валите. С двух часов только юнит-тестов (это их тысяч сто должно быть) перескакиваете на полуторачасовой полный билд. Вы уж определитесь ;).
Наш ночной билд исполняется 5 часов (он действительно дофига большой и страшный). При этом GC билд исполняется 7-8 минут (из них юнит-тесты — это пара минут). Зачекинил и работаешь дальше.
Юнит тесты могут хоть 2 часа работать

Ключевое слово выделил.

ОК, какой смысл вашего GC в таком случае? Просто проверить, что код собирается?
В минимальном случае — да. При наличии юнит-тестов — проверить, что тесты проходят. Про 2 часа я повторюсь — чтобы юнит-тесты ранались 2 часа, их должно быть ооооочень много (так много, что фактически эти 2 часа становятся нереальными).
1) Если компиляция продукта и прогон юнит-тестов (быстрых!) у вас занимает полчаса, то вы что-то делаете не так.
2) Курить не нужно. Просто продолжаешь работать дальше.
Бывает, тесты падают случайно, для selenium тестов через интерфейс это вообще не редкость. Так что на GC будет тратится слишком много времени разработчиков.
Во-первых, если тест падает случайно, это плохой тест (потому что ложные срабатывания — это время того, кто с тестом работает, не важно, разработчик это или программист).

А во-вторых, интерфейсные тесты в пречекин (обычно) не ставятся, потому что медленные.
Во первых, про плохой тест объясните отвалившемуся браузеру, или БД, или неожиданно долгому коннекту, прерванному по таймауту.

А во-вторых, если тестов мало — разработчик может прогнать локально, а если много, то «потому что медленные», не вижу тогда большого смысла.
Во первых, про плохой тест объясните отвалившемуся браузеру, или БД, или неожиданно долгому коннекту, прерванному по таймауту.

Если у вас отваливается БД — значит, у вас упал тест. Все нормально, так и должно быть. Следите за своей БД, это помогает.

Локальный прогон — это совсем не то же самое, что прогон на репозитории, он помогает только при идеальной дисциплине.
В одной компании, где я работал проблема со слишком часто сломанным билдом была решена правилом: сломал билд – принеси тортик. Сначала торты ели каждый день, потом перестали.


Как-то так…

Я предпочитаю большинство действий делать при помощи MSBuild'a, а TeamCity только запускает нужный таргет.
Таким образом, я могу из командной строки сделать любое действие над проектом — прогнать тесты, сделать бекап базы, обновить базу, обновить сайт в ИИСе,…
Я тоже так делаю. Заодно и отладить локально можно. Но вот тесты проще билд-степом запускать.
Статья очень, очень хорошая, но не могу не вставить свои пять копеек.

— Про версии сборок. Хочу обратить внимание, что у Microsoft термины Revision и Build поменяны местами. То есть семантически всё верно: закоммитил исходники — изменилась третья цифра, сбилдил на CI — изменилась четвёртая цифра. В документации с точки зрения смысла всё правильно, но названия параметров поменяны местами. Начинающему CI-мастеру легко запутаться.

— Про миграции базы данных. Если используется SQL Server (что для .NET частое явление), то можно использовать SMO. Через SMO можно управлять всем функционалом SQL Server, а не только alter на таблички делать. В статье упомянуть об SMO стоило.

— Про публикацию служб. Для доставки бинарников на сервер подходит тот же MSDeploy. Если в проекте уже используется MSDeploy для публикации web-приложений, то одной командой sync в MSDeploy можно скопировать все бинарники сервиса на целевой сервер. Шаред-папка и FTP это уже не модно :).

— Параметры в TeamCity. Учите людей плохому. Кучу аргуметов через /P указывать в TeamCity не надо — работать будет, но будут warnings. Специально для этого есть Build Parameters, они прозрачно транслируются в MSBuild скрипт.

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

Я больше склоняюсь к использованию PowerShell и конкретно psake. Это императивные скрипты, а не декларативный XML как в MSBuild, их не надо компилировать, можно легко править и можно отдать поддержку этих скриптов админам (от них сейчас знание PowerShell стали требовать).

Что думаете по этому поводу?
Здорово, что разворачивается дискуссия в комментах.
Про публикацию служб. Для доставки бинарников на сервер подходит тот же MSDeploy. Если в проекте уже используется MSDeploy для публикации web-приложений, то одной командой sync в MSDeploy можно скопировать все бинарники сервиса на целевой сервер. Шаред-папка и FTP это уже не модно :)
На целевой машине может не быть IIS

— Параметры в TeamCity. Учите людей плохому. Кучу аргументов через /P указывать в TeamCity не надо — работать будет, но будут warnings. Специально для этого есть Build Parameters, они прозрачно транслируются в MSBuild скрипт

Может у нас разные настройки TeamCity, я не видел ворнингов, хотя последние большие сборки у меня публиковались с помощью кастомного мсбилда, в который передается только конфигурация и никаких параметров нет.
Я больше склоняюсь к использованию PowerShell и конкретно psake. Это императивные скрипты, а не декларативный XML как в MSBuild, их не надо компилировать, можно легко править и можно отдать поддержку этих скриптов админам (от них сейчас знание PowerShell стали требовать).

Никто же не мешает использовать и то и другое или что-то одно по вкусу. Главное, чтобы работало и было просто поддерживать. например, поэтому я чаще всего не пишу отдельные таски, чтобы не тащить за собой бинарники.
Достаточно много разработчиков, к сожалению, никогда не заглядывает в файл проекта. Я думаю, что важно научиться пользоваться msbuild и редактировать проект не только из студии, но и «ручками», потому что многих вещей из студии просто не сделать.
Версионирование продукта
На мой взгляд удобнее всего использовать msbuild и проставлять значение с помощью CI-сервера:

Как решается обратная задача? Пользователь репортит о проблеме, указывает версию продукта (скажем, посмотрев свойства dll'ки в Проводнике): 3.14.159.2. Как узнать, какой ревизии в репозитории соответствует эта версия сборки? Используется DVCS, где для идентификации ревизий применяется 1) немонотонный 20-байтный уникальный идентификатор, и 2) автоинкрементный, но неоднозначный номер (может различаться для одной и той же ревизии в разных клонах репозитория).
Ну, «правильный» способ — это использовать билд-репозиторий, где по версии можно получить бинарники, информацию о билд-процессе (а так же тестах и продвижении), ну и информацию о том, из чего именно эта версия была собрана.
Это означает выделение «избранного» репозитория. Хотелось бы, чтобы клоны были по возможности равноправны, чтобы каждый клон имел всю необходимую информацию, чтобы локального репозитория было достаточно для определения ревизии по версии.
Я, наверное, не очень понятно выразился: билд-репозиторий — это не репозиторий кода, это специальный репозиторий артефактов, к VCS имеющий только то отношение, что он из нее берет исходники.
Идете в TeamCity или в другое CI-решение, которое используете. Находите билд, соответствующий вашей сборке. Для того, чтобы иметь какое-то соответствие, TeamCity предлагает BuildNumberFormat. Вы можете настроить его в соответствие с версионированием вашего приложения.
Не могу не упомянуть опенсорсный CI-сервер CruiseControl.NET. У нас он работает в связке с Redmine.
Для автоматического изменения версий сборок есть еще подход, описанный здесь (основан на использовании build feature «AssemblyInfo patcher»).
Из преимуществ — сам изменяет номера сборок во всех AssemblyInfo.cs в солюшене, не надо править .csproj как описано в этой статье. Из недостатков — изменяет номера сборок для всех проектов в солюшене, т.е. не позволяет для разных проектов вести различное версионирование.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации