Konfigurowanie przywracania pakietów za pomocą kompilacji Team Foundation

Ten artykuł zawiera szczegółowy przewodnik dotyczący sposobu przywracania pakietów w ramach kompilacji usług Team Services zarówno w przypadku kontroli wersji usług Git, jak i Team Services.

Chociaż ten przewodnik jest specyficzny dla scenariusza korzystania z usług Visual Studio Team Services, koncepcje dotyczą również innych systemów kontroli wersji i kompilacji.

Dotyczy:

  • Niestandardowe projekty MSBuild uruchomione w dowolnej wersji serwera TFS
  • Team Foundation Server 2012 lub starszy
  • Niestandardowe szablony procesów kompilacji programu Team Foundation zmigrowane do serwera TFS 2013 lub nowszego
  • Kompilowanie szablonów procesów z usuniętą funkcją przywracania nuget

Jeśli używasz usług Visual Studio Team Services lub Team Foundation Server 2013 z szablonami procesów kompilacji, automatyczne przywracanie pakietów odbywa się w ramach procesu kompilacji.

Ogólne podejście

Zaletą korzystania z narzędzia NuGet jest to, że można go użyć, aby uniknąć ewidencjonowania plików binarnych w systemie kontroli wersji.

Jest to szczególnie interesujące, jeśli używasz rozproszonego systemu kontroli wersji, takiego jak git, ponieważ deweloperzy muszą sklonować całe repozytorium, w tym pełną historię, zanim będą mogli rozpocząć pracę lokalnie. Ewidencjonowanie plików binarnych może spowodować znaczne wdęcie repozytorium, ponieważ pliki binarne są zwykle przechowywane bez kompresji różnicowej.

Pakiet NuGet od dawna obsługuje przywracanie pakietów w ramach kompilacji. Poprzednia implementacja miała problem z kurczakiem i jajkiem dla pakietów, które chcą rozszerzyć proces kompilacji, ponieważ pakiety NuGet przywrócone podczas kompilowania projektu. Jednak program MSBuild nie zezwala na rozszerzanie kompilacji podczas kompilacji; można argumentować, że jest to problem w MSBuild, ale twierdzę, że jest to nieodłączny problem. W zależności od tego, który aspekt należy rozszerzyć, może być za późno, aby zarejestrować się w czasie przywracania pakietu.

Rozwiązanie tego problemu polega na upewnieniu się, że pakiety są przywracane jako pierwszy krok w procesie kompilacji:

nuget restore path\to\solution.sln

Gdy proces kompilacji przywraca pakiety przed utworzeniem kodu, nie trzeba ewidencjonować .targets plików

Uwaga

Pakiety muszą być tworzone, aby umożliwić ładowanie w programie Visual Studio. W przeciwnym razie nadal możesz zaewidencjonować .targets pliki, aby inni deweloperzy mogli po prostu otworzyć rozwiązanie bez konieczności wcześniejszego przywracania pakietów.

W poniższym projekcie pokazowym pokazano, jak skonfigurować kompilację w taki sposób, że packages foldery i .targets pliki nie muszą być zaewidencjonowane. Pokazano również, jak skonfigurować zautomatyzowaną kompilację w usłudze Team Foundation Service dla tego przykładowego projektu.

Struktura repozytorium

Nasz projekt demonstracyjny to proste narzędzie wiersza polecenia, które używa argumentu wiersza polecenia do wykonywania zapytań w usłudze Bing. Jest przeznaczony dla programu .NET Framework 4 i używa wielu pakietów BCL (Microsoft.Net.Http, Microsoft.Bcl, Microsoft.Bcl, Microsoft.Bcl.Async i Microsoft.Bcl.Build).

Struktura repozytorium wygląda następująco:

<Project>
    │   .gitignore
    │   .tfignore
    │   build.proj
    │
    ├───src
    │   │   BingSearcher.sln
    │   │
    │   └───BingSearcher
    │       │   App.config
    │       │   BingSearcher.csproj
    │       │   packages.config
    │       │   Program.cs
    │       │
    │       └───Properties
    │               AssemblyInfo.cs
    │
    └───tools
        └───NuGet
                nuget.exe

Widać, że nie zaewidencjonowaliśmy packages folderu ani żadnych .targets plików.

Jednak zaewidencjonowaliśmy nuget.exe element , ponieważ jest potrzebny podczas kompilacji. Zgodnie z powszechnie używanymi konwencjami zaewidencjonowaliśmy je w folderze udostępnionym tools .

Kod źródłowy znajduje się w folderze src . Chociaż nasze pokazy używają tylko jednego rozwiązania, można łatwo sobie wyobrazić, że ten folder zawiera więcej niż jedno rozwiązanie.

Pliki ignorowanych

Uwaga

Obecnie element [known bug in the NuGet client](https://nuget.codeplex.com/workitem/4072) powoduje, że klient nadal dodaje packages folder do kontroli wersji. Obejściem jest wyłączenie integracji kontroli źródła. W tym celu potrzebny Nuget.Config jest plik w .nuget folderze równoległym do rozwiązania. Jeśli ten folder jeszcze nie istnieje, musisz go utworzyć. W Nuget.Configpliku dodaj następującą zawartość:

<configuration>
    <solution>
        <add key="disableSourceControlIntegration" value="true" />
    </solution>
</configuration>

Aby komunikować się z kontrolą wersji, która nie ma zamiaru zaewidencjonować folderów pakietów , dodaliśmy również ignorowanie plików zarówno dla narzędzia git (.gitignore), jak i kontroli wersji serwera TF (.tfignore). Te pliki opisują wzorce plików, których nie chcesz zaewidencjonować.

Plik .gitignore wygląda następująco:

syntax: glob
*.user
*.suo
bin
obj
packages
*.nupkg
project.lock.json
project.assets.json

Plik .gitignore jest dość zaawansowany. Jeśli na przykład chcesz zwykle nie zaewidencjonować zawartości packages folderu, ale chcesz przejść z poprzednimi wskazówkami dotyczącymi ewidencjonowania .targets plików, zamiast tego możesz mieć następującą regułę:

packages
!packages/**/*.targets

Spowoduje to wykluczenie wszystkich packages folderów, ale spowoduje ponowne dołączenie wszystkich zawartych .targets plików. Dzięki temu możesz znaleźć szablon plików .gitignore dostosowanych specjalnie do potrzeb deweloperów programu Visual Studio.

Kontrola wersji serwera TF obsługuje bardzo podobny mechanizm za pośrednictwem pliku .tfignore . Składnia jest praktycznie taka sama:

*.user
*.suo
bin
obj
packages
*.nupkg
project.lock.json
project.assets.json

build.proj

W naszym pokazie utrzymujemy dość prosty proces kompilacji. Utworzymy projekt MSBuild, który kompiluje wszystkie rozwiązania, upewniając się, że pakiety zostaną przywrócone przed utworzeniem rozwiązań.

Ten projekt będzie miał trzy konwencjonalne cele Clean, Build a Rebuild także nowy cel RestorePackages.

  • Oba Build obiekty docelowe i Rebuild zależą od RestorePackages. Dzięki temu można uruchamiać Build pakiety i Rebuild polegać na przywracaniu pakietów.
  • CleanBuild i Rebuild wywołaj odpowiedni element docelowy MSBuild we wszystkich plikach rozwiązań.
  • Obiekt RestorePackages docelowy nuget.exe wywołuje dla każdego pliku rozwiązania. Jest to realizowane przy użyciu funkcji dzielenia na partie programu MSBuild.

Wynik wygląda następująco:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
            DefaultTargets="Build"
            xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
    <OutDir Condition=" '$(OutDir)'=='' ">$(MSBuildThisFileDirectory)bin\</OutDir>
    <Configuration Condition=" '$(Configuration)'=='' ">Release</Configuration>
    <SourceHome Condition=" '$(SourceHome)'=='' ">$(MSBuildThisFileDirectory)src\</SourceHome>
    <ToolsHome Condition=" '$(ToolsHome)'=='' ">$(MSBuildThisFileDirectory)tools\</ToolsHome>
    </PropertyGroup>

    <ItemGroup>
    <Solution Include="$(SourceHome)*.sln">
        <AdditionalProperties>OutDir=$(OutDir);Configuration=$(Configuration)</AdditionalProperties>
    </Solution>
    </ItemGroup>

    <Target Name="RestorePackages">
    <Exec Command="&quot;$(ToolsHome)NuGet\nuget.exe&quot; restore &quot;%(Solution.Identity)&quot;" />
    </Target>

    <Target Name="Clean">
    <MSBuild Targets="Clean"
                Projects="@(Solution)" />
    </Target>

    <Target Name="Build" DependsOnTargets="RestorePackages">
    <MSBuild Targets="Build"
                Projects="@(Solution)" />
    </Target>

    <Target Name="Rebuild" DependsOnTargets="RestorePackages">
    <MSBuild Targets="Rebuild"
                Projects="@(Solution)" />
    </Target>
</Project>

Konfigurowanie kompilacji zespołu

Team Build oferuje różne szablony procesów. Na potrzeby tej demonstracji używamy usługi Team Foundation Service. Instalacje lokalne serwera TFS będą jednak bardzo podobne.

Narzędzia Git i kontrola wersji tf mają różne szablony kompilacji zespołu, więc poniższe kroki będą się różnić w zależności od używanego systemu kontroli wersji. W obu przypadkach wystarczy wybrać plik build.proj jako projekt, który chcesz skompilować.

Najpierw przyjrzyjmy się szablonowi procesu dla narzędzia git. W szablonie opartym na usłudze Git kompilacja jest wybierana za pośrednictwem właściwości Solution to build:

Build Process for git

Należy pamiętać, że ta właściwość jest lokalizacją w repozytorium. Ponieważ nasz build.proj element znajduje się w katalogu głównym, po prostu użyliśmy elementu build.proj. Jeśli umieścisz plik kompilacji w folderze o nazwie tools, wartość to tools\build.proj.

W szablonie kontroli wersji serwera TF projekt jest wybierany za pośrednictwem właściwości Projects:

Build Process for TFVC

W przeciwieństwie do szablonu opartego na usłudze Git kontrolka wersji tf obsługuje selektory (przycisk po prawej stronie z trzema kropkami). Aby uniknąć błędów wpisywania, zalecamy użycie ich do wybrania projektu.