Вопрос по build-automation, version-control, teamcity – Версии сборки с помощью TeamCity

18

Я работаю над проектом C # / VB.Net, который использует SVN и сервер сборки TeamCity. Десяток или около того сборок производится сборкой. Я хочу контролировать версии сборки, чтобы они все совпадали, а также соответствовали метке сборки TeamCity.

Я настроил TeamCity на использование метки сборки

Major.Minor.{Build}.{Revision}

Где Major и Minor - это константы, которые я установил вручную, {Revision} определяется версией хранилища SVN при оформлении заказа, а {Build} - счетчиком сборки TeamCity с автоматическим приращением. Таким образом, метка сборки примера будет

2.5.437.4423

Какие методы вы бы предложили, чтобы все версии сборки соответствовали метке сборки TeamCity?

Полагаю, мне следует также спросить: как вы управляете номерами версий для частных сборок, выполняемых отдельными разработчиками, по сравнению с автоматизированными сборками, выполняемыми TeamCity? Tim Long
[как обычно] мнения расходятся ... если разработчики просто строят из Visual Studio, они получают значения по умолчанию в файлах информации о сборке. Если разработчики используют скрипт сборки, у вас есть возможность сделать их другими. В одном проекте я настроил номера версий локальной сборки на 0.0.0.DaysSinceBeginningOfProject. Это было в первые дни ci и было сделано для того, чтобы я мог обнаружить любые локально собранные сборки, которые были вручную помещены в среду (вместо использования скрипта пакета сборки / развертывания). / JHD John Dhom

Ваш Ответ

4   ответа
5

Мы используем CruiseControl.net и SVN. Мы едем по-другому. Мы используемMSBuildCommunityTasks Задача версии в сценарии MSBuild, чтобы увеличить номер версии для сборок CI и использовать этот номер версии для тегирования исходного кода.

EDIT: Попросили более подробно о целях MSBuild ...
Мы используем отдельный скрипт, предназначенный для сборки CI и не используемый для сборок разработчика. Мы пытались использовать разные цели в файлах MSBuild, которые студия использует в качестве файлов проекта, но это было головной болью и требовало ручного редактирования файлов, которые создавала студия.
Структура файла MSBuild довольно проста:

  1. Import extra pieces

    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
    <!-- contains some variables that set project names, paths etc. -->
    <Import Project="Properties.msbuild"/>

  2. BeforeBuild: set new version number and rewrite the AssemblyInfo file

    <Version VersionFile="$(VersionFile)" BuildType="None" RevisionType="Increment">
    <Output TaskParameter="Major" PropertyName="Major" />
    <Output TaskParameter="Minor" PropertyName="Minor" />
    <Output TaskParameter="Build" PropertyName="Build" />
    <Output TaskParameter="Revision" PropertyName="Revision" />
    </Version>

    <!--Modify Assembly Info-->
    <AssemblyInfo CodeLanguage="CS"
    OutputFile="Properties\AssemblyInfo.cs"
    AssemblyTitle="$(TargetAssembly)"
    AssemblyDescription="$(AssemblyDescription) svn:@(SanitizedSvnUrl) revision:$(SvnRevision)"
    AssemblyCompany="Your company name"
    AssemblyProduct="Name of product"
    AssemblyCopyright="Copyright © your company 2009"
    ComVisible="false" Guid="$(WindowGuid)"
    AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)"
    AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)"
    Condition="$(Revision) != '0' " />

  3. Build: build the actual project file MSBuild script in release mode

  4. AfterBuild: we run our unit test projects (as a guard against creating tags for broken builds in the next steps), use the SvnInfo tasks and some RegexReplace tasks to set some variables up with paths and tag names, and use the SvnCopy task to create the tag.

<SvnCopy UserName="username"
Password="password"
SourcePath="@(SvnTrunkPath)"
DestinationPath="@(SvnTagsPath)/BUILD-$(TargetAssembly)-$(Major).$(Minor).$(Build).$(Revision)" Message="Tagging successful build" />

ИМХО, вопрос был не в том, какую систему CI использовать, а в том, как реализовать конкретную задачу в TeamCity.
@arconaut: спасибо. Ничто в моем ответе не говорит о том, что @Tim Long должен использовать CC.NET, я просто предварял ответ инструментами, которые я использую, чтобы было понятно, почему ответ не был конкретно о TeamCity.
Можно ли немного расширить этот ответ? Например, как выглядят цели MSBuild? Tim Long
7

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

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

  • The CI build has version numbers {Major.minor.BuildCounter.SvnRevision}
    • BuildCounter starts from 0
    • does not tag the svn repository
  • The Weekly/Release build has a similar versioning system, but
    • the build counter starts at (Major * 1000), so if Major is '8', the build counter starts from 8000.
    • Creates a tag called 'Build_{Version}' in the svn repository

Причина этого несколько произвольного выбора состоит в том, чтобы позволить нам четко и просто различать сборки CI и сборки Release.

У нас есть файл для решения под названием AssemblyVersionInfo, который включается (мягко связан) в каждый проект решения. Файл содержит (по сути) это:

using System.Reflection;
// Revision and Build both set to 9999 indicates a private build on a developer's private workstation.
[assembly: AssemblyFileVersion("6.0.9999.9999")]        // Win32 File Version (not used by .NET)

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

На сервере сборки мы используем задачи сообщества MSBuild для создания нового файла AssemblyVersionInfo, который перезаписывает содержимое по умолчанию. Мы используем строку сборки TeamCity в качестве новой версии. Таким образом, мы можем легко различить следующие 3 ситуации:

  • A private build performed on the developer's workstation
  • A CI build performed on the build server but which should not be released
  • An officially sanctioned release build, which is tagged in the Svn repository

В другом повороте обратите внимание, что я устанавливаюAssemblyFileVersionнеAssemblyVersion, Мы заставляем наши версии сборки быть статической фиксированной версией версии "Major.Minor.0.0". Мы делаем это так, чтобы мы могли выпускать исправления ошибок, не беспокоясь о проблемах с версиями. AssemblyFileVersion позволяет нам выяснить, какую сборку установил пользователь, не являясь частью идентификации сборки.

@TimLong как пометить код с обновленным AssemblyVersionInfo? Teamcity только метка из багажника.
@RobBird +1 за то, что вы комментируете этот совет AssemblyFileVersion;) В противном случае он пропустил бы его.
31

Я предлагаю использовать функцию сборки патча TeamInity:

http://confluence.jetbrains.net/display/TCD65/AssemblyInfo+Patcher

Просто создайте свои проекты из VisualStudio, настройте функцию сборки на странице BuildSteps (см.http://confluence.jetbrains.net/display/TCD65/Adding+Build+Features), и до тех пор, пока вы сохраняете файл AssemblyInfo.cs по умолчанию, он будет работать.

Этот подход отлично работает для меня.

Преимущества:

  • Developers can build the solution in their machines.
  • You don't need to touch the .sln or .csproj files. It just works.
  • By using TeamCity variables you can easily make the version number match some other project's version, etc.

Недостатки:

  • You can't easily switch to another CI server from TeamCity because you don't have a build script (but switching CI servers is like switching ORM or database: it is very unlikely and will require a lot of work anyway).
0

Even though this is already having an accepted answer, I would like to add an idea we have used.<,/p>

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

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

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

Похожие вопросы