NuGet restoring PostSharp package before the build begins - visual-studio

I am using PostSharp and I have the following target description in my project file:
<Target Name="EnsurePostSharpImported" BeforeTargets="BeforeBuild" Condition="'$(PostSharp30Imported)' == ''">
<Error Condition="!Exists('..\..\packages\PostSharp.3.1.33\tools\PostSharp.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://www.postsharp.net/links/nuget-restore." />
<Error Condition="Exists('..\..\packages\PostSharp.3.1.33\tools\PostSharp.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://www.postsharp.net/links/nuget-restore." />
</Target>
As far as I understand, this is added to the project when PostSharp is referenced through NuGet, and the error conditions check the following:
The first error condition breaks the build when PostSharp is not available (i.e. NuGet did not restore it successfully).
The second error condition breaks the build when PostSharp was successfully restored by NuGet on the last build but was therefore not included in the project, so therefore a rebuild is necessary.
BUT, if I have the following configuration in NuGet.Config and .csproj file, is the second error condition even necessary?
NuGet.Config file:
<configuration>
<packageRestore>
<!-- Allow NuGet to download missing packages -->
<add key="enabled" value="True" />
<!-- Automatically check for missing packages during build in Visual Studio -->
<add key="automatic" value="True" />
</packageRestore>
...
</configuration>
.csproj file:
<RestorePackages>true</RestorePackages>
As far as I understand, NuGet will then restore the missing packages BEFORE the build even starts. The second error condition will essentially break the build for no reason at all.
Note: I am using Visual Studio 2013 and NuGet 2.8.

It depends on how the restore is done and which version of NuGet you have installed. It looks like the error messages are trying to cover three scenarios:
Building without the MSBuild based package restore enabled (which is configured inside Visual Studio by right clicking the solution and selecting Enable Package restore).
Building outside of Visual Studio when the MSBuild based package restore is not enabled.
Building with Visual Studio using an old version of NuGet which does not support the automatic restore before a build.
If you are using the MSBuild based package restore then the restore will occur during the build and the PostSharp files will not be imported at this point so the $(PostSharp30Imported) will be empty and the second error message will be displayed. At least I suspect that is the case.
If you building from the command line and not using the MSBuild based package restore then you would see the first error message if the NuGet packages were missing.
If you are not using the MSBuild based package restore, and are building from within Visual Studio with a recent version of NuGet, then you are correct that the packages will be restored before anything is built at all. So the PostSharp imports should be available to MSBuild before it is even executed.

As PostSharp dlls are required during msbuild loading (so targets referencing this dlls are available during build) they must be available during final call to msbuild.
While in VS it is acceptable to click build twice, I was using PostSharp in CI environment, and requirement to call build on solution two times was frustrating (first build restore nugets but also failed build due to error).
I ended up with separate build steps:
Restore nuget Packages (this downloads PostSharp packages and return success code to environment):
NuGet.exe restore SolutionWithProjectsUsingPostSharp.sln
Build solution.

You need to edit the second error condition in the target in the csproj
<Target Name="EnsurePostSharpImported" BeforeTargets="BeforeBuild" Condition="'$(PostSharp30Imported)' == ''">
<Error Condition="!Exists('....\packages\PostSharp.3.1.33\tools\PostSharp.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://www.postsharp.net/links/nuget-restore." />
<Error Condition="Exists('....\packages\PostSharp.3.1.33\tools\PostSharp.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://www.postsharp.net/links/nuget-restore." />
</Target>>
I have answered in detail in a different post at SO

We are using 'old' MSBuild-Integrated package restore ( .nuget\NuGet.targets file is present) and normally do not store in source control packages, but rely on build to restore them for each build.
But for PostSharp on TeamCity build server I am getting error :
The build restored NuGet packages. Build the project again to include
these packages in the build.
The simplest way is to explicitly include in source control packages\PostSharp.VerXXX.
Alternatively solution could be migrating to automatic package restore,
as it was advised in Issue Using PostSharp 3.x with NuGet Auto Restore

Right click on the solution, Manage Nuget packages; and remove the packages you dont want .
This error also shows up , when trying to restore the packages from the web. Just connect your self to the internet and then try opening the project.
The errors went away for me on following the above steps.

Related

Self-hosted Azure Devops build cant resolve packages

I have a Azure DevOps build pipeline that runs as expected on a hosted vs2017 agent, but fails on a self-hosted agent.
The error I get in the Visual Studio build step is:
C:\WINDOWS\TEMP\.NETStandard,Version=v2.0.AssemblyAttributes.cs(4,20): Error CS0400: The type or namespace name 'System' could not be found in the global namespace (are you missing an assembly reference?)
The two agents seems to run the same version of msbuild.
From the diagnostic output from msbuild I can see that the output from the ResolvePackageDependencies task contains a lot of packages where the ResolvedPath is empty, for instance:
runtime.native.System/4.3.0
Name=runtime.native.System
Path=runtime.native.system/4.3.0
ResolvedPath=
Type=package
Version=4.3.0
But the NuGet restore step seems to complete without problems.
Any suggestions for what I am missing?
I believe I had a similar issue. I ended up having to install the latest Nuget and then run Nuget on the solution including a NuGet.config file.
Add a nuget.config to your solution so it is part of your repo/pull. Mine is in the same directory as the solution file. Example below
Add a task "NuGet Tool Installer" - I install NuGet 4.4.1, just put 4.4.1 in the Version to install input.
Add a task "NuGet Installer" - Different from above. Version 0.* - I have not tried the other versions.
Set the Path to the solution. IE. $(Build.Repository.LocalPath)/Source/Sample.sln
Add the path to the Nuget config file. Example $(Build.Repository.LocalPath)/Source/nuget.config
Nuget.config contains how to get the packages. Add other locations if you get packages from other sources like a local folder or something.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Used to specify the default Sources for list, install and update.
See: nuget.exe help list
See: nuget.exe help install
See: nuget.exe help update
-->
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
<packageRestore>
<!-- Allow NuGet to download missing packages -->
<add key="enabled" value="True" />
<!-- Automatically check for missing packages during build in Visual Studio -->
<add key="automatic" value="True" />
</packageRestore>
Your build task should run fine now and find all the packages.
Self-hosted Azure Devops build cant resolve packages
According to the error message, it seem nuget not restore the reference from SDK.
To resolve this issue, we need update our nuget.exe version to 4.0 and above.
In the NuGet tool installer we could specify the nuget.exe version:
As you comment above, it seems you have already use nuget installer, in this case, you can try to update Visual Studio to 15.3 and above on the build server. Because VS only adds proper support for .NET Core 2.0 SDK in version 15.3.
Finally, if your project/solution is .net core/standard you can use dotnet restore and then run dotnet build to compile your app.
Hope this helps.

how to fix ChakraCore NuGet package error?

When initializing a new React Native Windows WPF project, this error happens:
NuGet Package restore failed for project Native: Unable to find version '1.4.1-preview-00010-42060' of package 'Microsoft.ChakraCore'.
https://www.myget.org/F/chakracore-preview/api/v3/index.json: Package 'Microsoft.ChakraCore.1.4.1-preview-00010-42060' is not found on source 'https://www.myget.org/F/chakracore-preview/api/v3/index.json'.
https://api.nuget.org/v3/index.json: Package 'Microsoft.ChakraCore.1.4.1-preview-00010-42060' is not found on source 'https://api.nuget.org/v3/index.json'.
If I create a standalone project and add the same NuGet package reference, I get the same error -- even on Xamarin Studio Mac.
The problem is that the project was referencing the "preview" feed on myget.org, instead of the official release feed on nuget.org. In the NuGet.Config file(s) in your project, remove line that references the preview feed that looks like this:
<add key="ChakraCore" value="https://www.myget.org/F/chakracore-preview/api/v3/index.json" />
In the Visual Studio 2015 (or Xamarin/Visual Studio Mac) project, right-click on the project and select Manage NuGet References. From there, you can click on the Updates tab, select ChakraCore from the list, and click "Update". This should update the packages.config and other files for you. Note that if you had the project open while editing the config files you'll need to close and re-open the project to get the new settings to take hold. In some cases, the upgrade may leave behind the reference to the previous 1.4.1-preview package and you'll need to hand-edit the csproj file to get rid of it.
If you need to make this change without Visual/Xamarin Studio, you just have to edit a few text files. In the packages.config (in Visual Studio 2015), change the line referencing the 1.4.1-preview version to the latest release (1.5.2 as of this writing):
<package id="Microsoft.ChakraCore" version="1.4.1-preview-00010-42060" targetFramework="net46" developmentDependency="true" />
becomes
<package id="Microsoft.ChakraCore" version="1.5.2" targetFramework="net46" developmentDependency="true" />
In your project's csproj file:
<Import Project="$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props')" />
becomes
<Import Project="$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props')" />
and
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.ChakraCore.1.4.1\build\netstandard1.0\Microsoft.ChakraCore.props'))" />
becomes
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.ChakraCore.1.5.2\build\netstandard1.0\Microsoft.ChakraCore.props'))" />
Generally speaking, don't reference preview packages from myget.org in production projects or project templates others will use. They can be removed at any time, and security updates may not be published there with the same regularity as official channels.
Looks like the preview Microsoft.ChakraCore NuGet package was removed from the MyGet feed.
The main NuGet.org site only has stable releases for the Microsoft.ChakraCore NuGet package.
So you are left with editing any references to the package and using a published version. Microsoft.ChakraCore version 1.4.4 should work.
There is also an open issue about this on the React native GitHub site.

How to correctly edit vbproj file in VS2015 for incorrect nuget package information

We have a project that is housed in Visual Studio Online and we're trying to deploy it to Azure. When the build executed, we got an error about a missing nuget package. In VS, nuget did report that a package was missing and I restored it but we continue to get an error in VSO (the app compiles without error and if I deploy directly from VS to Azure, it works).
So I opened the vbproj file and in the last section, I see this:
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\theprojectfolder\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\SMDTalentLink\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\theprojectfolder\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\SMDTalentLink\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
While the package has been restored, it seems that VS hasn't deleted the error. VSO sees the error and won't compile the package. Can I delete this or do I need to edit it somehow? I'm not familiar with the proj files and am afraid I'll make things worse.
Removing the items does fix the issue. Unclear why VS didn't fix it.

Is it possible to get NuGet.exe running disconnected from Visual Studio?

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).

How do I integrate StyleCop 4.5.25 into msbuild in VS2010?

How do I setup StyleCop 4.5.25 (via NuGet package manager in VS2010) to integrate with MSBuild?
I currently have StyleCop 4.4 and the following setup:
http://stylecop.codeplex.com/wikipage?title=Running%20StyleCop%20in%20VS2005%20or%20VS%20Express&referringTitle=Documentation
My goal is to switch from the current setup to using Nuget as my package manager for Stylecop while retaining the biuld integration. There are only 2 files in the package installed by Nuget(src\packages\StyleCop.4.5.25.0\lib\net35): StyleCop.dll and StyleCop.CSharp.dll. Since there is no targets file, I am not sure how to integrate this new version.
In your msbuild file add:
<!--this will import stylecop as a task -->
<UsingTask AssemblyFile="$(StyleCopInstallDirectory)Microsoft.StyleCop.dll" TaskName="StyleCopTask"/>
<Target Name="RunStyleCop" >
<StyleCopTask
ProjectFullPath="$(MSBuildProjectFile)"
SourceFiles="#(StyleCopFiles)"
ForceFullAnalysis="$(StyleCopForceFullAnalysis)"
DefineConstants="$(DefineConstants)"
TreatErrorsAsWarnings="$(StyleCopTreatErrorsAsWarnings)"
CacheResults="$(StyleCopCacheResults)"
OverrideSettingsFile="$(StyleCopOverrideSettingsFile)" />
</Target>
A colleague recently tried to do something similar. It looks like the NuGet package contains only the libraries for creating StyleCop rules. It does not contain everything you need to run StyleCop as part of the build process.
For now, we just committed the StyleCop stuff, but we're hoping a NuGet package to set it all up appears soon!

Resources