Visual Studio 2019 is not detecting or discovering NUNit nor MSTest unit tests at all. I installed it fresh just a week ago. The MS guide here https://learn.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019&tabs=mstest does not work.
A few threads hold possible solutions, but none that I've tried helped have helped. I'm new to C# so much of the steps have taken a long time to figure out, but while my application is progressing nicely I really want to work and learn in a TDD style.
Even if a create a new blank MSTest project, with no application code or libs in the solution at all, the example/template project does not work, so I'm missing something big someplace. (I have .NET Core SDKs installed - my intent is to target macOS and linux at a future point.)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup>
</Project>
Threads I have tried: Tests not running in Test Explorer Why will Visual Studio 2019 will not run my unit tests? Visual Studio 2019 Test Explorer puts all tests under "Not Run Tests"
If I create a project targeting .NET 4.7 all is good, it's when I want to target Core that I'm unstuck, if that helps.
Stuck again
I had to install a component called "NUnit 3", https://marketplace.visualstudio.com/items?itemName=NUnitDevelopers.NUnitTemplatesforVisualStudio worked for a moment... but when I added a testcase, it all broke again.
Did the nuget package updates, still not working.
I cloned. from git this project https://github.com/dotnet/samples/tree/master/core/getting-started/unit-testing-using-nunit
And it does not work either.
I then re-installed 2019, and emailed my project to a friend, who merely removed the nunit nuget modules, added them back and then it worked for him, but the project he sent me back did not work. Module versions unchanged
I opened the same project in the Microsoft developer VM/iso image and the project works just fine. so it's my environment that is incompatible with nunit somehow. Is there a way to see some traces?
Changed the installation drive from D: to C: I get this error now
Testhost process exited with error: A fatal error occurred, the required library hostfxr.dll could not be found.
If this is a self-contained application, that library should exist in [C:\Users\zapho\src\c#\tutorials\working\ConsoleApp1\ConsoleApp1\NUnit.Tests2\bin\Debug\netcoreapp3.1\].
If this is a framework-dependent application, install the runtime in the default location [C:\Program Files\dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location.
. Please check the diagnostic logs for more information.
Testhost process exited with error: A fatal error occurred, the required library hostfxr.dll could not be found.
If this is a self-contained application, that library should exist in [C:\Users\zapho\src\c#\tutorials\working\ConsoleApp1\ConsoleApp1\NUnit.Tests2\bin\Debug\netcoreapp3.1\].
If this is a framework-dependent application, install the runtime in the default location [C:\Program Files\dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location.
. Please check the diagnostic logs for more information.
You need to add the Microsoft.NET.Test.Sdk NuGet package to your solution to run tests in Visual Studio.
Modify your project file,
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
</ItemGroup>
</Project>
Fixed it by eventually setting environment variable
DOTNET_ROOT=D:\Program Files\dotnet\
as per an answer
https://stackoverflow.com/a/61453119/337598
Related
The scenario
You add a nuget package, which in turn injects <Import .../> statement into your csproj file which references a targets or props file from the package itself.
This works fine when building the code in Visual Studio, but fails miserably when building the same solution with msbuild.
The root cause
There are several. First, the logic to restore the packages is executed by the VS itself outside of the build proper. We can solve it by importing Nuget.targets which would run the RestorePackage target before the build. Check.
But the second problem is more serious. The Import statements importing targets/props from the packages can only be resolved after the packages are restored. Meaning restoring the packages cannot be part of the build. It must happen before the msbuild is given the solution to build. Yes, Visual Studio does it already, but I do not use Visual Studio on my Gated Check-In or CI server. I need it to work with msbuild.
What one can do?
As far as I understand, I need to be able to run the same logic VS does only on the command line. I.e. identify the packages and restore them before running msbuild. But devil is in details. Cannot be I am the first one to face this problem.
How do you do it?
Found the answer in this blog post - http://sedodream.com/2013/06/06/HowToSimplifyShippingBuildUpdatesInANuGetPackage.aspx
Following this blog I have created before.MySolutionName.sln.targets file with the following content:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Restore">
<Target Name="Restore" BeforeTargets="Build">
<Exec Command=".nuget\nuget.exe restore $(MSBuildProjectName)" LogStandardErrorAsError="true" />
</Target>
</Project>
Now all the packages in the solution are restored before the build.
Thank you, Sayed Ibrahim Hashimi.
I'm updating an old Visual Studio extension for VS 2017. It compiles fine from Visual Studio and msbuild in debug and release on my local computer.
This is the msbuild command line I am using:
msbuild VxCop.sln /p:ToolsHome=C:\ProgramData\chocolatey\bin /p:Configuration=Release /p:Platform="Any CPU"
However, on the build machine (TFS Build 2010) calling msbuild.exe with the same command line it fails with this error
In order to fix this I am trying to specify VSToolsPath. I've tried various things such as altering the VSToolsPath entry in the .csproj (which seems to not be taken into account since doing this had no effect) and also passing it on the command line:
msbuild VxCop.sln /p:ToolsHome=C:\ProgramData\chocolatey\bin /p:Configuration=Release /p:Platform="Any CPU" /p:VSToolsPath=Packages\Microsoft.VSSDK.BuildTools.15.1.192\tools\
This causes a very strange error:
CopyFilesToOutputDirectory:
Copying file from "obj\Release\SymCop.dll" to "bin\Release\SymCop.dll".
SymCop -> H:\src\tools\VisualStudioExtensions\Main\VxCop\source\SymCop\bin\Release\SymCop.dll
Copying file from "obj\Release\SymCop.pdb" to "bin\Release\SymCop.pdb".
Done Building Project "H:\src\tools\VisualStudioExtensions\Main\VxCop\source\SymCop\SymCop.csproj" (default targets).
Done Building Project "H:\src\tools\VisualStudioExtensions\Main\VxCop\VxCop.sln" (Build target(s)) -- FAILED.
Done Building Project "H:\src\tools\VisualStudioExtensions\Main\VxCop\build.proj" (default targets) -- FAILED.
Build FAILED.
0 Warning(s)
0 Error(s)
The actual extension project isn't appearing in the log at all, and there's no, y'know, errors. But the build returns as failed, the return code is non-zero, and the vsix project seems to not be built (its output is missing)
Hopefully someone has some suggestions
Thanks
Edit:
For those reading this in the future, the problem seemed to be that there was an <Import> further down in the same file which didn't care about my update to $(VSToolsPath).
Changing that import fixed it:
<Import Project="$(SolutionDir)\packages\Microsoft.VSSDK.BuildTools.15.1.192\tools\VSSDK\Microsoft.VsSDK.targets"
/>
Visual Studio 2017 extension - VSToolsPath not working
I got the same result as you based on your scripts. After installed the NuGet package Microsoft.VSSDK.BuildTools to the project, the Microsoft.VSSDK.BuildTools.props will be imported in to project file, open the project file, you can find below Import:
<Import Project="..\packages\Microsoft.VSSDK.BuildTools.15.1.192\build\Microsoft.VSSDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.VSSDK.BuildTools.15.1.192\build\Microsoft.VSSDK.BuildTools.props')" />
Then open this props file, you can notice below scripts snippet:
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="VSSDK_NuGet_Configuration">
<ThisPackageDirectory>$(MSBuildThisFileDirectory)..\</ThisPackageDirectory>
<VSToolsPath>$(ThisPackageDirectory)\tools</VSToolsPath>
<VsSDKInstall>$(VSToolsPath)\VSSDK</VsSDKInstall>
<VsSDKIncludes>$(VsSDKInstall)\inc</VsSDKIncludes>
<VsSDKToolsPath>$(VsSDKInstall)\bin</VsSDKToolsPath>
</PropertyGroup>
</Project>
In this case, NuGet package override the value VSToolsPath with $(ThisPackageDirectory)\tools. So MSBuild will skip set the value setting in the next step in the project file:
<PropertyGroup>
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
Because NuGet have already set the value $(VSToolsPath), the value of Condition="'$(VSToolsPath)' == ''" would be False. In addition, you can add a target to check if the value is set, like:
<Target Name="CheckVSToolsPath" BeforeTargets="Build">
<Message Text="$(VSToolsPath)"></Message>
</Target>
You will find this value is set to:
C:\Users\Admin\Documents\Visual Studio 2017\Projects\VSIXProject2\packages\Microsoft.VSSDK.BuildTools.15.1.192\build\..\\tools
Summary above, the value of VSToolsPath was imported correctly, we do not need to passing it on the command line.
After in-depth investigation, I found the reason for the previous error "MSB4226: The imported project "(...)\VSSDK\Microsoft.VsSDK.targets" was not found." is that the MSBuild property of "VisualStudioVersion" not be set on the build server.
See below link for detail info Building a VSIX extension with the Visual Studio 2017 Build Tools:
something that a machine with the full Visual Studio 2017 does and that a machine with the Build Tools 2017 does if you open a developer command prompt. Since I was not using it, I passed it as a parameter to the MSBuild script. It can be defined too inside the .csproj file, something that previous Visual Studio versions did automatically but recent versions don’t.
So to resolve the error "MSBuild4226", you should pass the visual studio version on command line:
msbuild VxCop.sln /p:ToolsHome=C:\ProgramData\chocolatey\bin /p:Configuration=Release /p:Platform="Any CPU" /p:VisualStudioVersion=15.0
After using this command line, the error MSBuild 4226 was resolved.
Hope this helps.
I resolved this problem in VS 2019 by https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#generatepathproperty
<ItemGroup>
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="16.10.1055">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<Import Project="$(PkgMicrosoft_VSSDK_BuildTools)\tools\vssdk\Microsoft.VsSDK.targets" />
Has anyone seen this error and know how to fix it?
The "TransformXml" task could not be loaded from the assembly C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll.
Could not load file or assembly 'file:///C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll' or one of its dependencies. The system cannot find the file specified.
Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
I read elsewhere that the problem is when you don't have SQL Server installed. But I do have SQL Express 2012 x64 installed with SP1. I am also running VS 2013 Professional.
I have ran this exact same solution in VS 2012 express with no problems.
The answers provided by Dai Bok and emalamisura work fine as long as you use Visual Studio 2012.
For VS 2013 this fails as well. In order to make this work with all versions of Visual Studio you should:
Open the project file (.csproj) of the project failing to load
Search for <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />
Change it to <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets" />
Reload the project
That will set the correct version of Visual Studio dynamically and properly.
To get mine to work, I just copied my v10.0 folder and renamed it to v11.0, and things seems to work well from then on. That's the quick fix for now.
As this is probably not the best solution, and although it works, I was going to try installing the Microsoft Windows SDK for Windows 7 and .NET Framework 4 Windows SDK for Windows 7 and .NET Framework 4, but it is taking to long to download.
To fix the issue,
Find the Visual studio Installer in your computer
Click or tap to start the installer, and then select Modify.
From the Individual Components screen, select Asp.net and web development tools and then select Modify/Install.
This solved the issue as it creates the dll's in the mentioned path.
I've been combating this problem on our build server for several days, so I figured I'd document the resolution I came to. First, my build server has the web publishing extensions installed. I can use the TransformXml task to my heart's content inside of a web application project.
To use it outside of a web application project, I tried to add the UsingTask element to my project and point it to the right place using ms build properties (as Benjamin demonstrated). However, they weren't there on my build server (those with easy access to the file system of their build server can probably skip this and just install the relevant package to Visual Studio). I even went so far as to hard code visual studio versions, but it always dropped that error on me.
I finally gave up, pulled the DLLs from my local PC:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.XmlTransform.dll
I uploaded them to source control and added that folder to my build's workspace (Edit Build Definition -> Source Settings -> Source Control Folder). From there, I don't even need to reference the folder -- here's what my UsingTask looks like:
<UsingTask TaskName="TransformXml" AssemblyFile="Microsoft.Web.Publishing.Tasks.dll" />
Now I can use the TransformXml task to my heart's content from any project.
For VS2019
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(MSBuildToolsVersion
I replaced MSBuildToolsVersion with VisualStudioVersion.
Because there are only v12.0, v14.0 and v15.0 in my VisualStudio folder, I edit my project file and change the reference path from v10.0 to v14.0. Then the project builds successfully.
Before:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
After:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
Solutions provided seem to work for using VS as an IDE, but if you use DotnetCore via CLI or on a unix based system this does not work.
I found that the following seem to work
<PropertyGroup>
<XmlTransformDllPath Condition="'$(XmlTransformDllPath)' == '' AND '$(MSBuildRuntimeType)' == 'core'">$(MSBuildSDKsPath)/Microsoft.NET.Sdk.Publish/tools/net5.0/Microsoft.NET.Sdk.Publish.Tasks.dll</XmlTransformDllPath>
<XmlTransformDllPath Condition="'$(XmlTransformDllPath)' == '' AND '$(MSBuildRuntimeType)' != 'core'">$(MSBuildSDKsPath)/Microsoft.NET.Sdk.Publish/tools/net472/Microsoft.NET.Sdk.Publish.Tasks.dll</XmlTransformDllPath>
<XmlTransformDllPath Condition="!Exists($(XmlTransformDllPath))">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll</XmlTransformDllPath>
</PropertyGroup>
<UsingTask TaskName="TransformXml" AssemblyFile="$(XmlTransformDllPath)" />
This solution takes into account netcore, full .net
For some reason MSBuildSDKsPath and MSBuildExtensionsPath32 are different on windows when using CLI vs VS2019
CLI:
MSBuildSDKsPath = C:\Program Files\dotnet\sdk\5.0.103\Sdks
MSBuildExtensionsPath32 = C:\Program Files\dotnet\sdk\5.0.103
Vs2019
MSBuildSDKsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Sdks
MSBuildExtensionsPath32 = C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild
Which on my Mac returns /usr/local/share/dotnet/sdk/5.0.201
Only problem I see is with the tools/net5.0 part of the name which changes ever release
Also created https://github.com/dotnet/sdk/issues/16469 and answers this on The "TransformXml" task was not found (error MSB4036) on TeamCity build
The correct answer to this is to unload the project in question and then edit the csproj file, look for an entry where they are referencing the 10.0 path and change it to point to 11.0 instead.
You need two things to make it work:
1) Install Visual Studio Build Tools (You don't need the whole Visual Studio, only the VS Build Tools) with selected "Web development build tools" option on your build server
https://www.visualstudio.com/pl/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15
2) Ensure that path to Microsoft.Web.Publishing.Tasks.dll is correct
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(MSBuildToolsVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
For me it started working just by adding reference to the NuGet package MSBuild.Microsoft.VisualStudio.Web.targets v14.0.0.3
Even no need to add UsingTask element to the project file as it mentioned by the package author
https://github.com/pdonald/nuget-webtargets
Just install the NuGet package. The package automatically sets the
$(VSToolsPath) property to use the targets file in the tools folder.
And then I was able to use TransformXml and other tasks, defined in the package, for instance to transform app.config
<Target Name="app_config_AfterCompile" AfterTargets="AfterCompile" Condition="Exists('app.$(Configuration).config')">
<!--Generate transformed app config in the intermediate directory-->
<TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
<!--Force build process to use the transformed configuration file from now on.-->
<ItemGroup>
<AppConfigWithTargetPath Remove="App.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target>
Just in case someone is using an SDK-style csproj, you can achieve this without having to install Visual Studio on the build server.
First you should install the SlowCheetah nuget package to your project. Once you install it, you'll see the following in your SDK-style project.
<PackageReference Include="Microsoft.VisualStudio.SlowCheetah" Version="3.2.20">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Then make sure you add the GeneratePathProperty="true" attribute (see below). This is very important for the next part because it'll help you grab the path of where the nuget package is restored on your machine. George Dangl explains it in his article here.
<PackageReference Include="Microsoft.VisualStudio.SlowCheetah" Version="3.2.20" GeneratePathProperty="true">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Import the SlowCheetah targets into your project:
<Import Project="$(PkgMicrosoft_VisualStudio_SlowCheetah)\build\Microsoft.VisualStudio.SlowCheetah.targets" />
You can now use an target command (in this case after publish) to apply some custom transformations. If you need to, you can always hard-code the file names below instead of using the variables in the below example.
<Target Name="AfterPublishs" AfterTargets="Publish">
<TransformTask Source="Web.config" Transform="Web.$(Configuration).MyCustomTransformFile.config" Destination="$(PublishDir)\Web.config" />
</Target>
If you haven't used SlowCheetah before, I recommend checking it out. They have a Visual Studio extension that will make it easier for you to preview transform files.
I've been wrestling with NuGet for a few days now and I'm turning to StackOverflow in frustration - hopefully someone here can be kind enough to point me in the right direction.
I've used NuGet several times for simple one-man pet projects, but this is the first time I've used it for something I really care about and want to have fully continuous builds, etc. I'm trying to create a simple NAnt build script to get the source for Git, ensure the external dependencies have been brought down, compile, and run tests - vanilla CI.
I originally went down the path of trying to get solution restore working, but it just didn't work or I didn't how it worked. Visual Studio is not on the build server and will not be installed there - that is not an option. As an aside, I couldn't get solution restore to work just with two developers (one trying to bring down the source fresh and build cleanly). I'm assuming it's because "allow solution restore" must be turned on everywhere (and is not by default). I punted on that approach before I got to the bottom of it - frankly, having my package manager so tightly coupled to the IDE makes me uncomfortable and was hoping I could do it another way. The package managers I'm used to using are simple command line tools - the CI build script invokes it on build, and developers do it on demand. I've spent the last two hours trying to get this working with the last 30 minutes in the NuGet source code. I feel like I'm fighting the tool and need to reboot.
Does anyone have any examples of the best to use NuGet in a multi-developer + CI scenario? This is what I want:
Any and all developers can get the source and run the tests in 3 or
less clicks (preferably 1). If the binaries are not present locally, that will be JIT fetched. If they are there, they will be updated if necessary, etc. This would ideally not even require NuGet to be installed (i.e. NuGet.exe would need to be in my repo).
Do #1 via a CI server like Jenkins, TeamCity, etc. (preferably using the same script)
If its not overly fighting the tool, I would like to have all this disconnected from Visual Studio with a single packages.config file and all binaries dumped into a single Lib folder in the root of the repo.
Any pointers would be very much appreciated.
Below, how I think you can achieve each your requisites:
You need to "Enable NuGet Package Restore" in your solution: http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages
As #alexander-doroshenko mentioned for TeamCity you can use Nuget Installer: http://confluence.jetbrains.com/display/TCD7/NuGet+Installer, but if you want a script to run in Jenkins, try this (works at TC too, as a command line step) for each project:
nuget.exe install "[Project folder]/packages.config" -source "" -solutionDir "" -OutputDirectory "packages"
This requisite will be done by item 1 and 2.
TeamCity has a build step for that, called "NuGet Installer", it fetch required packages from .sln file and download the locally. It does not require Visual Studio to run.
Read more about it here: http://confluence.jetbrains.com/display/TCD7/NuGet+Installer
There are several different solutions for integrating NuGet into your build process depending on how much integration you require. In our case we wanted to use NuGet as package manager and allow developers to build their solutions even if they haven't got NuGet installed on their machine. For that to work we enabled package restore which adds the NuGet binaries to your solution folder and updates the project files. Note that NuGet doesn't always do the update of the project files correctly. In our case we found that some project files got updated but others didn't. To verify that the project was updated you will need to open the project file as XML file. To achieve this load the solution and right click the project in question and select unload project. Then right click the project again and select edit [PROJECT_NAME]. In the project file you should see
A RestorePackages property in the first propertygroup. This property should have the value true
An import statement at the very end of the project file. This import statement should point to the 'NuGet.targets file that accompanies the NuGet binary.
Below is an example of one of our project files (heavily edited)
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir Condition="'$(SolutionDir)' == '' or '$(SolutionDir)' == '*undefined*'">$(MSBuildProjectDirectory)\..</SolutionDir>
<ProjectGuid>{8B467882-7574-41B2-B3A8-2F34DA84BE82}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>MyCompany.MyNamespace</RootNamespace>
<AssemblyName>MyCompany.MyNamespace</AssemblyName>
<!-- Allow NuGet to restore the packages if they are missing -->
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<Import Project="$(SolutionDir)\BaseConfiguration.targets" />
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="MyClass.cs" />
<!--
.... MANY MORE FILES HERE
-->
</ItemGroup>
<!-- Import the Nuget.targets file which integrates NuGet in the build process -->
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
The next step you'll need to take is to provide a solution level NuGet configuration file in which you'll indicate where the packages need to be 'installed' and what the URL of the package repository is. In our case the solution directory structure looks like:
(D) root
(D) build
(D) packages
(D) source
(D) .nuget
NuGet.config
NuGet.exe
NuGet.targets
(D) MyCoolProject
MyCoolProject.csproj
MyCoolProject.sln
(D) templates
NuGet.Config
Where (D) indicates a directory.
The NuGet.config file contains the following configuration settings.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
<config>
<add key="repositorypath" value="packages" />
</config>
<packageSources>
<add key="OurPackageServer" value="PACKAGE_SERVER_ADDRESS" />
</packageSources>
<activePackageSource>
<add key="All" value="(Aggregate source)" />
</activePackageSource>
</configuration>
This configuration file indicates that package restore is enabled, that the repository path (where the packages are placed) is the packages directory and which package sources are active.
By placing a NuGet.config file in the root directory we can use the hierarchical configuration option with NuGet. This allows the individual solutions to override computer specific configurations. The other benefit is that this way we don't need to have NuGet installed on the build server (because the executable and the configurations are in the repository).
With this setup developers can build the solution from Visual Studio. The build should work fine on developers machines even if they don't have NuGet installed. Note however that they won't be able to add packages to a project without having NuGet installed in visual studio.
On the build server you can simply use MsBuild to build the solution which will automatically download the packages from your package repository. Visual Studio is not required to be installed on the build machine for that (just the .NET framework of your choice).
I am trying to configure TeamCity 5.0 to run "Publish" target on one of my projects.
When I load the solution in VS 2008 and click publish on the project the website is being build nicely - files on server appearing by themselves etc. Yet when I run the sln file via TeamCity Sln2008 runner the TeamCity returns:
[Project "Portal.csproj" (Publish target(s)):] Skipping unpublishable project.
Has anyone had the same problem?
Filip
You could create your own simple build file. For example:
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<PackageFolder>C:\Builds\AppServer\Actual</PackageFolder>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="BeforeBuild">
<MSBuild Projects="TeamWork-AppServer.sln"
Targets="Rebuild"
Properties="Configuration=Debug;OutDir=$(PackageFolder)\;"></MSBuild>
</Target>
</Project>
Or you can use VS 2008 Web Deployment Project. Here is a great turtorial.
If it is a WebProject you can use the Microsoft.WebApplication.targets. Unless you have installed the windows SDK on your build agent you will need to copy the targets file into your source control and reference it from your web project by adding:
<Import Project="{path to your tools}\Microsoft.WebApplication.targets" />
You can find the targets file here (depending on your os):
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications
Now you just need to update your msbuild task to reference the right targets:
<MSBuild Projects="{path to your web project file}"
Targets="Build;ResolveReferences;_CopyWebApplication"
Properties="Configuration=Release;Architecture=Any;WebProjectOutputDir={your web root};OutDir={your web root}\bin\" />
Here is how I modified the .csproj file for an ASP.NET MVC project to deploy via TeamCity 5.1.2. In the .csproj file, replace the AfterBuild target with this XML (If there are already commands in your existing AfterBuild, you will have to merge them into these targets):
<PropertyGroup>
<DeployTarget>0</DeployTarget>
<PublishTarget>0</PublishTarget>
<PublishFolder>..\Deployment\YourWebsiteName</PublishFolder>
</PropertyGroup>
<Target Name="PublishProperties">
<CreateProperty Value="$(PublishFolder)">
<Output TaskParameter="Value" PropertyName="WebProjectOutputDir"/>
</CreateProperty>
<CreateProperty Value="$(PublishFolder)\bin\">
<Output TaskParameter="Value" PropertyName="OutDir"/>
</CreateProperty>
</Target>
<Target Name="WebPublish" DependsOnTargets="BeforeBuild;PublishProperties">
<RemoveDir Directories="$(PublishFolder)"
ContinueOnError="true" />
<CallTarget Targets="ResolveReferences;_CopyWebApplication" />
</Target>
<Target Name="Deploy" DependsOnTargets="WebPublish">
<CreateProperty Value="Path\To\Your\Server" Condition="$(DeployFolder) == ''">
<Output TaskParameter="Value" PropertyName="DeployFolder"/>
</CreateProperty>
<RemoveDir Directories="$(DeployFolder)" Condition="$(CleanDeploy) == 1" />
<ItemGroup>
<DeploymentFiles Include="$(PublishFolder)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(DeploymentFiles)"
DestinationFolder="$(DeployFolder)\%(RecursiveDir)" />
</Target>
<Target Name="AfterBuild">
<CallTarget Targets="WebPublish" Condition="$(PublishTarget) == 1" />
<CallTarget Targets="Deploy" Condition="$(DeployTarget) == 1" />
</Target>
This script uses the $(PublishTarget) and $(DeployTarget) properties to trigger additional steps after your project is built. The PropertyGroup at the beginning sets the default values to 0, so the extra targets are not run. You can override the default in TeamCity by going to the Properties and Environment Variables page of your build configuration and adding System Properties names "PublishTarget" and "DeployTarget" and setting their value to 1.
The Publish target contains most of the magic. This makes a call to the Visual Studio _CopyWebApplication target to output the website to the PublishFolder. By default the publish folder is "..\Deployment\YourWebsiteName" relative to the project file, but this can also be overridden with a System Property. The Deploy target takes the files output by the Publish target and copies them to the DeployFolder. DeployFolder can be set with a System Property in TeamCity or you can replace the "Path\To\Your\Server" path in the Deploy target.
You could also skip the extra Deploy step by simply setting the PublishFolder to whatever your deployment destination is. This script depends on the "Microsoft.WebApplication.Build.Tasks.Dll" and "Microsoft.WebApplication.targets" files installed by Visual Studio, but you can simply copy the files from your developer workstation to the build server. The default location is "C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications".
I have this same problem, here's what I've tried:
I have a solution file in Visual Studio 2010, committed to a Mercurial repository.
I have setup an FTP server for the root directory of the site to publish to, and publishing from within Visual Studio 2010 locally works nicely, it connects and uploads everything as expected, and the website works.
Now, I wanted to automate this on every push to the central Mercurial repository, and since I'm using TeamCity, I discovered that the field to specify the Target of the build, usually "Rebuild" can also take "Publish", so I specified "Rebuild;Publish", as per the documentation and help.
I have verified that after publishing in Visual Studio, and committing new files, a file named ProjectName.Publish.xml is accompanying my ProjectName.csproj file, and this file is pulled down into the server directory when TeamCity builds.
Yet, no publishing is done, and when I check the build log, it says:
[19:01:02]: [Project "Test.sln" (Rebuild;Publish target(s)):] Project "Test.UI.Web.csproj" (Publish target(s)):
[19:01:02]: [Project "Test.UI.Web.csproj" (Publish target(s)):] Skipping unpublishable project.
Exactly as the question here says.
Note that this is a development site, publishing just so that we can let more people test changes, so don't get into a discussion of whether this is actually a good idea or not.
Note: I do not care in which way the files are published, I just need the single TeamCity build-step to actually do it, so if anyone got a MSBuild-like solution that just sidesteps TeamCity, then I would be satisfied
Have you tried to execute Visual Studio directly, rather than relying on MSBuild to publish the project directly. MSBuild can't execute certain kinds of projects. I had a similar problem with getting MSI's built from within Team City.
I'm taking a guess at the exact commandline settings to this, since I don't know your exact setup.
<PropertyGroup>
<buildconfiguration>Release</buildconfiguration>
<DevEnv>C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com</DevEnv>
</PropertyGroup>
<Exec Command="%22$(DevEnv)%22 /build $(buildconfiguration) $(teamcity_build_checkoutDir)\Test.sln /project Test.UI.Web.csproj"/>
If you're using the Team City solution runner as your build runner, you'll have to switch to MSBuild.
If you want to stay with the Team City runner, you could always try adding a project to your solution that will be the last one built, (or do it on the project that currently gets built last), and do the spawning trick as a post-build command line on the project.
Can TeamCity publish a Web project using the sln2008 build runner
Can TeamCity publish a Web project using the sln2008 build runner?
What type of project are you trying to publish?
http://social.msdn.microsoft.com/forums/en-US/msbuild/thread/7ec0d942-6354-41c3-9c97-7e7d1f461c29
Taken from above link:
What I discovered is that "Shared-addins" are not publishable
and are distinct and different from document and application level
VSTO addins, which are deployable.
When I rebuilt my application as an application level
VSTO addin, the publish option was available.
http://www.automise.com/Default.aspx?tabid=53&aft=9813
Taken from above link:
Assuming you're using Visual Studio 2008, we're unable to execute the web site
publish feature from FinalBuilder as it's partially implemented by the VS IDE.
You'll need to use to the MSBuild action to compile the application and then
use one of the other actions (FTP, File Copy, etc) in FinalBuilder to perform
the deployment. Visual Studio 2010 has fixed this problem by performing the
entire publish using MSBuild, see this post for more info:
http://www.finalbuilder.com/forums....&afv=topic
Two threads that might help
http://devnet.jetbrains.net/thread/280420;jsessionid=5E8948AE810FFFF251996D85E7EB3FE3
Visual Studio. Publish project from command line
For anyone using Web Application Projects in VS2010, I managed to get TeamCity to package the deliverables and then Web Deploy the package after successfully building the solution.
With a little tweaking, this had the same effect as hitting the 'Publish' button in VS.
My solution has a handful of projects, 1 of which is an ASP.NET MVC Web Application project. I build the solution, package the web app project, and msdeploy the package in 3 steps. I haven't figured out a (better|shorter|simpler|more elegant) way to do this.
I don't have VS installed on my TeamCity server, so I needed to grab both C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web and C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web Applications and put them both in the same spot on the TeamCity server (the second depends on the first). If you're working w/x64 machines, I'd grab them from both Program Files (x86) and Program Files. You also need to have Web Deploy installed on your machine and (I believe) IIS Management Service (i.e., something listening on https://yourservername:8172/MsDeploy.axd)
There are 3 build steps:
Visusal Studio (sln), Target=Rebuild, Configuration=Debug
MSBuild WebProject.csproj, Targets=Package Commandline=/p:PackageLocation=%teamcity.build.checkoutDir%\Debug.zip /p:Configuration=Debug
Commandline, Executable=%teamcity.build.checkoutDir%\Debug.deploy.cmd, Parameters=
/Y "-setParam:'IIS Web Application Name'='Default Web Site/PreCreatedAppInIis'"
In that last step, 'IIS Web Application Name' is an actual parameter name, don't change it. It's value can either be something like 'Default Web Site' or whatever you named your website in IIS and/or it can be an IIS application path below it. If the application doesn't exist, you may run into errors about the app pool not being configured correctly to host the application. Rather than investigate it, I just created an application in the appropriate app pool. In my case, I'm targeting ASP.NET 4.0 x64 where the default app pool is ASP.NET 2.0 x64.