How to get nuget restore in TFS build - c#

I can't make it work TFS build. It is nuget restore issue. Nuget is not restoring reference dll files.
Here is belwo my build configuration. Please advise me how I can make this works.

As per this blog post on Nuget's website you can use the command line you mentioned, but it has to be part of a custom target using a Build.proj file.
You need to add a Build.proj and put this as the contents:
<?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=""$(ToolsHome)NuGet\NuGet.exe" restore "%(Solution.Identity)"" />
</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>
Alternatively, you could call it from a custom Pre-Build Script.
Or, customise the XAML template and add a Foreach loop to invoke:
nuget.exe restore path\to\solution.sln
on each solution in the build definition.

Here are some steps (described here which was mentioned in Dave's post) you need to follow in order to have these NuGet packages restored during the VSO (TFS) build process.
Add following items to the solution. (Content of the nuget.config and .tfignore file can be found here)
Add one build.proj file under the root path of the solution folder. (Content of the build.proj file can be found here)
Create one folder named tools under the root path of the solution folder. Create NuGet sub-folder under tools folder, download and save nuget.exe under tools\NuGet path.
Check in nuget.config, .tfignore, build.proj and tools\NuGet\nuget.exe into TFS version control.
Modify the build definition to choose to build the build.proj file.
Then you will have NuGet packages restored successfully during the TFS build process.

Related

How to Exclude Content directory in Nuget

I am trying to build nuget with my csproj and MSBuild.
Nuget package gets created successfully. But I see content and contentFiles folder where it has my 20 .proto files.
And when someone downloads my nuget, they also get my proto files. But I don't want to give those files. How Can I avoid having .proto files.
I don't have .nuspec file.
My csproj looks like this :
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ProduceReferenceAssemblyInOutDir>true</ProduceReferenceAssemblyInOutDir>
<PackageId>BlahBlah</PackageId>
<Title>BlahBlah</Title>
<Version>1.0.0</Version>
<Authors>Test</Authors>
<Company>Test</Company>
<PackageTags>Test nuget</PackageTags>
<DebugType>portable</DebugType>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<PackageOutputPath>Blah</PackageOutputPath>
</PropertyGroup>
<Target Name="Test1" AfterTargets="Pack" Condition="$(PackOnBuild) == 'true'">
<ItemGroup>
<PackageFile Include="$(TestVersion).nupkg" />
</ItemGroup>
<Copy SourceFiles="#(src)" DestinationFolder="$(dst)" />
</Target>
According to the Microsoft docs, you can set <Pack>false</Pack> to exclude files from the NuGet package.
Since I don't know whether proto files are treated as Content or None, it should be either
<PropertyGroup>
<Content Include="*.proto">
<Pack>false</Pack>
</Content>
</PropertyGroup>
or
<PropertyGroup>
<None Include="*.proto">
<Pack>false</Pack>
</Content>
</PropertyGroup>
within the csproj.

How do i have a .csproj build a .proj file before building itself?

I have a .csproj file and a .proj file. As part of my .proj file I am generating a file to include in the .csproj, so the .proj needs to run first.
How can this be done. I originally tried to add a project reference as follows:
<ProjectReference Include="..\FileGenerator\FileGenerator.proj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
This however gives me the error:
error MSB4057: The target "GetNativeManifest" does not exist in the project
I then noticed there is a BeforeBuild target in my csproj file.
Can I use this to have the other file be built?
Use MSBuild task to invoke other projects. Example:
<Target Name="BeforeBuild">
<MSBuild Projects="..\FileGenerator\FileGenerator.proj" Targets="Build" />
</Target>
If you need any cleanup done as part of the common Clean target, you can plug in custom cleanup target like this:
<Target Name="FileGeneratorClean" BeforeTargets="Clean">
<MSBuild Projects="..\FileGenerator\FileGenerator.proj" Targets="Clean" />
</Target>

Replacing TFSBuild.proj files with TFS 2013

I'm trying to upgrade our TFS server to 2013. We're currently using 2012, but we've also been clinging on to the upgrade template for dear life. With 2013, we'd like to go to the default template and modify it as little as possible.
The problem comes in when you consider that the default template asks you to add each individual .csproj or .sln file that you would like to build. The nice thing about the tfsbuild.proj files is that not only can you build on the server, but you can check out the entire branch and build everything locally, on the command line, by just passing the tfsbuild.proj file to msbuild.exe. Also, developers can own the tfsbuild.proj file without having write access to change the build definition.
What is the replacement for the TFSBuild.proj file in TFS 2013?
My requirements are:
Clean build configuration.
Can easily build everything locally.
What is the solution to this problem in TFS 2013?
Create a wrapper MSBuild .proj that your TFS build definition uses. We use this technique for NuGet package restore, but it can equally be used to chain together multiple solution files.
For local builds you can use msbuild with that .proj wrapper as the target (I just build the .sln file directly as there is only 1).
.proj file (not suggesting that you should use this exact .proj file, just an example)
<PropertyGroup>
<OutDir Condition=" '$(OutDir)'=='' ">$(MSBuildThisFileDirectory)bin\</OutDir>
<Configuration Condition=" '$(Configuration)'=='' ">Release</Configuration>
<SourceHome Condition=" '$(SourceHome)'=='' ">$(MSBuildThisFileDirectory)</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=""$(ToolsHome)NuGet\NuGet.exe" restore "%(Solution.Identity)"" />
</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>

Msbuild for copying assemblies to a few folders of applications?

I have a VS solution that contains a few applications and public APIs to be published along with shared libraries. I have some shallow experience in crafting msbuild file like this one.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TPath>C:\Program Files (x86)\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>
<ETPath>C:\Program Files (x86)\MSBuild\ExtensionPack\4.0\</ETPath>
</PropertyGroup>
<ItemDefinitionGroup />
<ItemGroup>
<SolutionFile Include="MyApplications.sln" />
</ItemGroup>
<Target Name="Build" Outputs="#(CollectedBuildOutput)">
<MSBuild Projects="#(SolutionFile)" Targets="Rebuild" BuildInParallel="True"
Properties="BuildingSolutionFile=true; Configuration=$(Configuration); Platform=$(Platform); TargetFrameworkVersion=$(TargetFrameworkVersion); WarningLevel=3"
SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)">
<Output TaskParameter="TargetOutputs" ItemName="CollectedBuildOutput"/>
</MSBuild>
</Target>
</Project>
Then I run
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MyProjects.msbuild /p:outdir=C:\VSProjectsRelease\MyApplications\Release\
So all assemblies will go to the same directory. So far so good. However, if I want to zip files for each application, or harvest files for Wix setup projects, troubles will emerge.
For example, in MyApplications.sln, I have 10 projects, 3 of which are applications say AppA, AppB and AppC.
I would like to run a single msbuild file which will create 3 folders of applications, and have assemblies copied to there without explicitly defining dependencies since Sln and csproj files already have the knowledge. And I would want msbuild will build each project only once. How to do this?

XSLTC.EXE MSBuild Task

I have several XSLTs used in my ASP.NET web application.
I want these files to be compiled to dll whenever I build the project.
Currently, I'm compiling the xslts manually by invoking xsltc.exe from vs2010 tools command prompt.
How can I add msbuild task for xsltc.exe so that it will generate assembly whenevr i build my project?
I'm using .NET 4.0.
That works but doesn't really wrap the tool in a MSBuild friendly way.
I came up with this (which was good enough to get by).
<!-- The Transform File Names... -->
<ItemGroup>
<XsltcTransform Include="Transform1.xslt">
<!-- And the generated .Net Class name. -->
<Class>Transform1Class</Class>
</XsltcTransform>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- Sadly using $(OutDir) MUST come after the Import of CSharp.targets -->
<PropertyGroup>
<XSLTCOutputDll>$(OutDir)xslts.dll</XSLTCOutputDll>
</PropertyGroup>
<Target Name="FindXSLTC">
<PropertyGroup>
<XSLTC>"$(TargetFrameworkSDKToolsDirectory)xsltc.exe"</XSLTC>
</PropertyGroup>
</Target>
<Target Name="XSLTC" Inputs="#(XsltcTransform)" Outputs="$(XSLTCOutputDll)" DependsOnTargets="FindXSLTC">
<Exec Command="$(XSLTC) /out:"$(XSLTCOutputDll)" #(XsltcTransform -> ' /class:%(Class) %(FullPath) ')" />
</Target>
<Target Name="BeforeResolveReferences" DependsOnTargets="XSLTC">
</Target>
These targets will let you compile multiple transforms into one DLL.
Running XSLTC before "BeforeResolveRefereneces" is necessary so that you can have an assembly reference to the generated DLL.
<PropertyGroup>
<WinSDK>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin</WinSDK>
</PropertyGroup>
<Target Name="Build">
<Exec Command="%22$(WinSDK)\xsltc.exe%22 /out:$(OutputPath)\_PublishedWebsites\xyzapp\bin\Xslts.dll /class:ABC %22$(MSBuildProjectDirectory)\xyzapp\a.xslt%22 /class:DEF %22$(MSBuildProjectDirectory)\xyzapp\b.xslt%22 /class:GHI %22$(MSBuildProjectDirectory)\xyzapp\c.xslt%22"/>
</Target>

Categories