Выбор для инструмента построения: MSBuild, NANT или что-то еще?

Я занимаюсь автоматизацией в своей компании. Мы - семинар С#. В настоящее время я работаю над автоматической сборкой. NANT - это инструмент управления потоком. Хотя NANT активно не развивается (последняя бинарная версия выпущена на Июнь 2012 и github repo неактивна), MSBuild лучше. Поэтому я предпочитаю MSBuild, но уходящий в отставку NANT по-прежнему вызывает сомнения - какова стоимость?

Я придумал некоторые плюсы и минусы, но я знаю, что коллективный интеллект лучше. Спасибо за вашу помощь!


Обновление: Я прочитал вопрос, но второй ответ вызывает беспокойство для меня. На машине для сборки есть несколько .NET-фреймворков, неудобно ли это?


MSBuild

Pros

  • Коммерческая поддержка
  • Сообщество растет
  • Интегрировано с VS и TFS
  • Не отставайте от .Net

против

  • Повторить текущий script
  • Не знакомы людям

NANT

Pros

  • Уже используется
  • Знакомые люди

против

  • Не обновляется в течение длительного времени (с 2012 года)
  • Сообщество неактивно
  • Отсутствие новой поддержки .Net

Ответ 1

Мы писали FlubuCore (переписываем Flubu). Это библиотека С# с открытым исходным кодом для создания проектов и выполнения сценариев развертывания с использованием кода С#.

Основные преимущества flubu, которые я вижу:

  • Поддержка Net Core (работает также с linux и macOS).
  • Легко учиться и использовать, потому что вы полностью пишете build script на С#.
  • Довольно много встроенных задач (компиляция, запуск тестов, управление iis, создание пакета развертывания, публикация пакетов nuget, выполнение сценариев powershell...)
  • Напишите свой собственный код С# в script и выполните его.
  • Запустите любую внешнюю программу в script.
  • Ссылка на любую библиотеку .net или файл исходного кода С# в buildscript.
  • Свободный интерфейс и intelisense.
  • Запишите тесты, отлаживайте свою сборку script.
  • Используйте задачи flubu в любом другом .net(основном) приложении.
  • Web api доступен для flubu. Полезно для автоматического развертывания удаленно.
  • Напишите свои собственные задачи flubu и расширьте их интерфейс.

Вы можете найти flubu на nuget:

Искать FlubuCore.Runner, если это необходимо для проекта .net

Искать dotnet-flubu, если вам нужен основной проект for.net

Пример использования flubu в .net:

protected override void ConfigureBuildProperties(IBuildPropertiesContext context) {
 context.Properties.Set(BuildProps.NUnitConsolePath,
  @ "packages\NUnit.ConsoleRunner.3.6.0\tools\nunit3-console.exe");
 context.Properties.Set(BuildProps.ProductId, "FlubuExample");
 context.Properties.Set(BuildProps.ProductName, "FlubuExample");
 context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
 context.Properties.Set(BuildProps.BuildConfiguration, "Release");
}

protected override void ConfigureTargets(ITaskContext session) {
 var loadSolution = session.CreateTarget("load.solution")
  .SetAsHidden()
  .AddTask(x => x.LoadSolutionTask());

 var updateVersion = session.CreateTarget("update.version")
  .DependsOn(loadSolution)
  .SetAsHidden()
  .Do(TargetFetchBuildVersion);

 session.CreateTarget("generate.commonassinfo")
  .SetDescription("Generates common assembly info")
  .DependsOn(updateVersion)
  .TaskExtensions().GenerateCommonAssemblyInfo()

 var compile = session.CreateTarget("compile")
  .SetDescription("Compiles the solution.")
  .AddTask(x => x.CompileSolutionTask())
  .DependsOn("generate.commonassinfo");

 var unitTest = session.CreateTarget("unit.tests")
  .SetDescription("Runs unit tests")
  .DependsOn(loadSolution)
  .AddTask(x => x.NUnitTaskForNunitV3("FlubuExample.Tests"));

 session.CreateTarget("abc").AddTask(x => x.RunProgramTask(@ "packages\LibZ.Tool\1.2.0\tools\libz.exe"));

 session.CreateTarget("Rebuild")
  .SetDescription("Rebuilds the solution.")
  .SetAsDefault()
  .DependsOn(compile, unitTest);
}

//// Some custom code
public static void TargetFetchBuildVersion(ITaskContext context) {
 var version = context.Tasks().FetchBuildVersionFromFileTask().Execute(context);

 int svnRevisionNumber = 0; //in real scenario you would fetch revision number from subversion.
 int buildNumber = 0; // in real scenario you would fetch build version from build server.
 version = new Version(version.Major, version.Minor, buildNumber, svnRevisionNumber);
 context.Properties.Set(BuildProps.BuildVersion, version);
}

Пример использования flubu в ядре .net

public class MyBuildScript : DefaultBuildScript
{
    protected override void ConfigureBuildProperties(IBuildPropertiesContext context)
    {
        context.Properties.Set(BuildProps.CompanyName, "Flubu");
        context.Properties.Set(BuildProps.CompanyCopyright, "Copyright (C) 2010-2016 Flubu");
        context.Properties.Set(BuildProps.ProductId, "FlubuExample");
        context.Properties.Set(BuildProps.ProductName, "FlubuExample");
        context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
        context.Properties.Set(BuildProps.BuildConfiguration, "Release");
    }

    protected override void ConfigureTargets(ITaskContext context)
    {
        var buildVersion = context.CreateTarget("buildVersion")
            .SetAsHidden()
            .SetDescription("Fetches flubu version from FlubuExample.ProjectVersion.txt file.")
            .AddTask(x => x.FetchBuildVersionFromFileTask());

        var compile = context
            .CreateTarget("compile")
            .SetDescription("Compiles the VS solution and sets version to FlubuExample.csproj")
            .AddCoreTask(x => x.UpdateNetCoreVersionTask("FlubuExample/FlubuExample.csproj"))
            .AddCoreTask(x => x.Restore())
            .AddCoreTask(x => x.Build())
            .DependsOn(buildVersion);

        var package = context
            .CreateTarget("Package")
            .CoreTaskExtensions()
            .DotnetPublish("FlubuExample")
            .CreateZipPackageFromProjects("FlubuExample", "netstandard2.0", "FlubuExample")
            .BackToTarget();

    //// Can be used instead of CreateZipPackageFromProject. See MVC_NET4.61 project for full example of PackageTask
    //// context.CreateTarget("Package2").AddTask(x =>   
             x.PackageTask("FlubuExample"));

         var test = context.CreateTarget("test")
            .AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests"))
            .AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests2"));   

         context.CreateTarget("Rebuild")
             .SetAsDefault()                 
             .DependsOn(compile, test, package);
}

}

Здесь вы можете найти полные примеры: https://github.com/flubu-core/examples

Wiki можно найти здесь: https://github.com/flubu-core/flubu.core/wiki

Ответ 2

Существует свойство nant.settings.currentframework, которое используется для установки целевой структуры в случае, если у вас есть несколько инфраструктур .net

<property name="nant.settings.currentframework" value="net-2.0" />

Согласно .92 build:

  • nant.settings.currentframework Текущая целевая структура, например. 'Сеть-1,0'.
  • nant.settings.currentframework.description Устарело. Описание текущей целевой структуры.
  • nant.settings.currentframework.frameworkdirectory Устаревший. Каталог фреймов текущей целевой структуры.
  • nant.settings.currentframework.sdkdirectory Устаревший. Каркас SDK каталога текущей целевой структуры.
  • nant.settings.currentframework.frameworkassemblydirectory Устаревший. Каталог сборки фреймов текущей целевой структуры.
  • nant.settings.currentframework.runtimeengine Устаревший. Механизм выполнения текущей целевой структуры, если используется, например. mono.exe.