Как я могу заставить 2010 TFS разрабатывать каждый проект к отдельному каталогу?

В нашем проекте мы хотели бы иметь нашу сборку TFS, помещает каждый проект в его собственную папку под папкой отбрасывания, вместо того, чтобы бросить все файлы в одну плоскую структуру. Для иллюстрирования мы хотели бы видеть что-то вроде этого:

DropFolder/
  Foo/
    foo.exe
  Bar/
    bar.dll
  Baz
    baz.dll

Это - в основном тот же вопрос, как был спрошен здесь, но теперь, когда мы используем основанные на рабочем процессе сборки, те решения, кажется, не работают. Решение с помощью свойства CustomizableOutDir было похоже на него, будет работать лучше всего на нас, но я не могу заставить то свойство быть распознанным. Я настроил наш рабочий процесс для передачи его в MSBuild как параметр командной строки (/p:CustomizableOutDir=true), но кажется, что MSBuild просто игнорирует его и помещает вывод в OutDir, данный рабочим процессом.

Я посмотрел на журналы сборки, и я вижу, что свойства CustomizableOutDir и OutDir оба становятся установленными в командной строке args к MSBuild. Мне все еще нужен OutDir, который будет передан в том, так, чтобы я мог скопировать свои файлы в TeamBuildOutDir в конце.

Какая-либо идея, почему мой параметр CustomizableOutDir не становится распознанным, или если существует лучший способ достигнуть этого?

22
задан Community 23 May 2017 в 11:58
поделиться

3 ответа

Я придумал хороший способ сделать это. Оказывается, поскольку вы можете установить для OutDir все, что захотите в рабочем процессе, если вы установите для него пустую строку, MSBuild вместо этого будет использовать OutputPath для конкретного проекта. Это позволяет нам быть более гибкими. Вот мое полное решение (основанное на рабочем процессе сборки по умолчанию):

В задаче «Выполнить MSBuild» установите для OutDir пустую строку. В той же задаче установите для CommandLineArguments примерно следующее. Это позволит вам иметь ссылку на OutDir TFS по умолчанию из вашего проекта:

String.Format("/p:CommonOutputPath=""{0}\\""", outputDirectory)

В каждом проекте, который вы хотите скопировать в папку drop, установите OutputPath следующим образом:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <OutputPath Condition=" '$(CommonOutputPath)'=='' ">bin\Release\</OutputPath>
    <OutputPath Condition=" '$(CommonOutputPath)'!='' ">$(CommonOutputPath)YourProjectName\bin\Release\</OutputPath>
</PropertyGroup>

Отметьте все, и у вас должен быть рабочий build, которая развертывает каждый из ваших проектов в отдельной папке в папке drop.

14
ответ дан 29 November 2019 в 05:16
поделиться

Я не пробовал заставить TFS / MSBuild помещать выходные файлы в отдельные папки, поэтому не могу дать прямого ответа. Однако вот несколько предложений, которые я не заметил в вашей ссылке:

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

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

0
ответ дан 29 November 2019 в 05:16
поделиться

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

Я использовал ответ Джонатана и пост Джима Лэмба, но обнаружил, что вам также нужно установить OutDir пустым.

Итак, вам нужно сделать эти параметры для деятельности MSBuild (если вы используете следующий макрос, вам нужно установить параметры деятельности для Clean тоже, иначе вы получите предупреждения, что OutputPath не установлен):

  • Set CommandLineArguments to String.Format("/p:SkipInvalidConfigurations=true;TeamBuildOutDir=""{0}"" {1}", BinariesDirectory, MSBuildArguments)
  • Set OutDir to empty (was BinariesDirectory)

Я также создал макрос, который можно запустить в visual studio, который удаляет OutputPath из конфигураций, и добавляет PropertyGroup, которая содержит OutputPath для всех конфигов, как показано ниже:

<PropertyGroup Label="OutputPathLabel">
  <OutputPath Condition="'$(TeamBuildOutDir)'=='' ">bin\$(Configuration)\</OutputPath>
  <OutputPath Condition="'$(TeamBuildOutDir)'!='' ">$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)\</OutputPath>
</PropertyGroup>

Вот макрос:

Public Sub SetTeamBuildOutDir()

    Dim projectObjects = DTE.Solution.Projects

    For Each project In projectObjects

        If project.ProjectItems IsNot Nothing Then
            SetTeamBuildOutDirRecursive(project)
        End If
    Next

End Sub

Sub SetTeamBuildOutDirRecursive(ByVal proj As Project)
    If proj.ConfigurationManager Is Nothing Then
        For Each subProj As ProjectItem In proj.ProjectItems
            If subProj.SubProject IsNot Nothing Then
                SetTeamBuildOutDirRecursive(subProj.SubProject)
            End If
        Next
    Else
        SetTeamBuildOutDir(proj)
    End If

End Sub

Sub SetTeamBuildOutDir(ByVal project As Project)
    'Do not handle .vdproj
    If project.FullName.ToLower().EndsWith(".vdproj") Then
        Exit Sub
    End If

    Dim needToSave = False
    Dim msproject = ProjectRootElement.Open(project.FullName)
    Dim outputPathGroupExists = False
    Dim outputPropertyGroup As ProjectPropertyGroupElement = Nothing
    Dim lastConfigPropertyGroup As ProjectPropertyGroupElement = Nothing

    For Each propertyGroup In msproject.PropertyGroups

        If propertyGroup.Label = "OutputPathLabel" Then
            outputPathGroupExists = True
            outputPropertyGroup = propertyGroup
        End If

        If Not String.IsNullOrEmpty(propertyGroup.Condition) AndAlso _
            propertyGroup.Condition.TrimStart().StartsWith("'$(Configuration)") Then

            lastConfigPropertyGroup = propertyGroup
        End If

        'Remove the OutputPath from the configurations
        Dim outputPathElement As ProjectPropertyElement = Nothing
        For Each element As ProjectPropertyElement In propertyGroup.Children
            If element.Name = "OutputPath" Then
                outputPathElement = element
            End If
        Next
        If outputPathElement IsNot Nothing Then
            propertyGroup.RemoveChild(outputPathElement)
            needToSave = True
        End If
    Next

    'If we want to always remove the group and add it back (in case of modifications to the group)
    'If outputPathGroupExists Then
    '    msproject.RemoveChild(outputPropertyGroup)
    '    outputPathGroupExists = False
    'End If

    If Not outputPathGroupExists Then
        Dim propertyGroup = msproject.CreatePropertyGroupElement()
        propertyGroup.Label = "OutputPathLabel"
        'Need to insert the PropertyGroup before the CSharp targets are included
        msproject.InsertAfterChild(propertyGroup, lastConfigPropertyGroup)

        Dim isDbProject = project.FullName.ToLower().EndsWith(".dbproj")

        Dim outputEmpty = propertyGroup.AddProperty("OutputPath", IIf(Not isDbProject, "bin\$(Configuration)\", "sql\$(Configuration)\"))
        outputEmpty.Condition = "'$(TeamBuildOutDir)'=='' "

        Dim outputTeamBuild = propertyGroup.AddProperty("OutputPath", "$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)\")
        outputTeamBuild.Condition = "'$(TeamBuildOutDir)'!='' "

        needToSave = True
    End If

    If needToSave Then
        'checkout the project file with tfs
        Shell("C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe checkout " & project.FullName, , True)

        'Save the project file
        msproject.Save()
    End If
End Sub

Надеюсь, это поможет!!!

4
ответ дан 29 November 2019 в 05:16
поделиться