Packages not downloading on MSBuild Server - asp.net-mvc

ASP.NET 4.5 MVC application
Builds/runs just fine locally
Packages folder NOT checked into source control
Source control looks like this:
MyProject
-.nuget
-.tfignore
-MyProject.Web
-MyProject.Utilities
-MyProject
-MyProject.sln
Inside of the .nuget folder, there is only one file: NuGet.config, which has this inside:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
</configuration>
I can delete the packages folder locally, run it, and it correctly downloads everything again.
When I kick off a build from Visual Studio which should build the solution and deploy it to Azure Cloud Service, the build fails saying:
The type or namespace name 'WindowsAzure' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

The "new" way to do this is to run
nuget.exe restore "MySolution.sln"
I put my (versioned) nuget.exe files on my build server like this:
c:\MyProgFiles\NuGet\2.8.6\nuget.exe
c:\MyProgFiles\NuGet\3.3.0\nuget.exe
Then before I build, I call
"c:\MyProgFiles\NuGet\2.8.6\nuget.exe" restore "c:\MyFullPath\MySolution.sln"
You can also read this about "how to clean up old nuget stuff"
http://docs.nuget.org/consume/package-restore/migrating-to-automatic-package-restore
(using CI macros when possible to create the file names)
I also put these lines before the "nuget restore" to help with debugging.
"c:\MyProgFiles\NuGet\2.8.6\nuget.exe" sources list
"c:\MyProgFiles\NuGet\2.8.6\nuget.exe" locals all -list
BTW: If you have a package source where the packages might get deleted, then add this to your build scripts (before the "restore" mentioned above)
"c:\MyProgFiles\NuGet\2.8.6\nuget.exe" locals all -clear
This will clear your local cache and force a fresh download.
Again, the value here is ONLY if you use a source where packages get deleted.

Related

How to properly configure NuGet Packages for collaboration with DevOps (TFS)

I have read and gone trough the following:
https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#enabling-and-disabling-package-restore
https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore-troubleshooting
Why is there no packages folder in .my NET Core solution's containing folder?
'nuget' is not recognized but other nuget commands working
https://www.skylinetechnologies.com/Blog/Skyline-Blog/July_2016/Relocate_NuGet_Package_Restore_Folder
But i still have issues with the Folder Packages which contains the Packages for my solution, when i check in my code, for my on my side everything works fine, when someone else gets the checked in solution, he has to change the path that is set in the ProjectNameFile.csproj because the path there contains
../../../../NuGetPackages/....
but should be (and only works if changed to)
../Packages
But than when this persons checks in and i get this version, my packages folder is gone ... We have been using TFS on other projects here but this is a first for me ...
I tried all what the links i posted are suggestion but with no luck.
Tools > options > NuGet Package Manager looks like this:
I have a NuGet.Config file on the same level as my projectname.sln file which has following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<!-- I tried each line below seperately and together -->
<add key="globalPackagesFolder" value=".\packages" />
<add key="repositoryPath" value="C:\Development\projectname\Packages" />
</config>
</configuration>
So what i did now is i created a Packages folder on the projectname.sln level and when i build my solution, this works but hey, i can't do that each (X) time and i am sure there is a way of achieving this but don't know how.
Thank you in advance for any feedback.
How to properly configure NuGet Packages for collaboration with DevOps (TFS)
I suppose you are using the packages.config as nuget package management, because you said " he has to change the path that is set in the ProjectNameFile.csproj because the path there contains ../../../../NuGetPackages/....".
So, if you are using packages.config, you should use relative paths for the repositoryPath in your nuget.config file when you build the project with Azure DevOps.
As we know, when we build the project in the Azure DevOps, Azure DevOps always copy the project to the path like D:\a\1\s\xx, which is different with the path in your local. And NuGet always use the relative paths (..\packages or ../../../../NuGetPackages/...)in the ProjectNameFile.csproj like:
<Reference Include="packagename, Version=3.0.0.0, xxx">
<Private>True</Private>
<HintPath>..\packages\xxx\lib\net45\xxx.dll</HintPath>
</Reference>
In this case, when we build the project, nuget will still restore the nuget packages to absolute path C:\Development\projectname\Packages, but since the location of the project has changed to the D:\a\1\s\xx, so the relative paths for the HintPath in the .csproj file should also be changed accordingly, otherwise nuget can't find the corresponding dll file.
So, we should set the repositoryPath as relative paths in the nuget.config file, like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value=".\packages" />
</config>
</configuration>
With this setting, the path of the packages folder are based on the file nuget.config. As long as you have not modified the location of the nuget.config file, the HintPath does not need to be modified.
Note:
globalPackagesFolder is uesed for another nuget management type packagereference.
If you are working with someone else to develop a project, you need to unify the location of the nuget package, rather than continually modifying the HintPath manually. Otherwise it will cause confusion in your development.
Hope this helps.

TFS NuGet Installer build step not working

I'm trying to configure an automated build of a project that has a NuGet package reference, but I'm not having any luck. (FYI I'm still pretty wet behind the ears with all of this, so please provide simple steps and/or configurations.)
Note: this isn't a duplicate of other similar questions, as I'm using a central package repository. Other similar questions make no mention of this important detail, so they should be assumed to not be relevant.
The build runs fine without the reference. I added Newtonsoft.Json and bound to it by including this simple construct:
Dim eHandling As Newtonsoft.Json.ConstructorHandling
eHandling = Newtonsoft.Json.ConstructorHandling.Default
I checked it in and the build started, but NuGet hadn't first copied the assembly to my application's bin folder. It did, however, copy it to here:
Restoring NuGet package Newtonsoft.Json.9.0.1.
Adding package 'Newtonsoft.Json.9.0.1' to folder 'C:\Agent\_work\1\s\packages'
Naturally the build failed, as it couldn't find the dependency.
It's worth noting that I'm using a central package repository on my dev machine:
<config>
<add key="repositoryPath" value="D:\Dev\Packages" />
</config>
I'd like to emulate this behavior on the server as well, e.g. C:\Packages\*\*.nupkg.
I tried using the standard %AppData%\NuGet\NuGet.config file, but the build ignores it. I tried the advice in this answer (using repositoryPath instead of packageSources as shown there), but that causes the server to hang until I restart the VSO Agent service. Thinking it might be a permissions issue, I reconfigured the agent to run under the user account associated with the %AppData% location of NuGet.config. Still no luck. No build.
How can I get NuGet to download and populate the central package repository on the server and then copy the appropriate dependencies to the application bin folder prior to running the build step?
EDIT 1
Update: Apparently something's working, as I now have a C:\Packages\Newtonsoft.Json.9.0.1 folder on the server. However, the assembly still isn't being copied to the application bin folder prior to build. Same result. Failed build.
EDIT 2
OK, I'm getting closer. I created a D: drive on the server and set the local repositoryPath value to D:\Dev\Packages, the same as it is on my dev machine. The build is still failing, but a quick look at the project XML reveals this:
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\Packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
How to deal with that relative path? That should fix it, yes?
EDIT 3
OK, that worked. I edited the project and changed HintPath to
D:\Dev\Packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
I now have a successful build.
But this is going to get real tedious real fast. Surely I'm not going to have to do this for every single NuGet reference in every single project, past present and future... am I?
OK, got it.
As long as the repositoryPath folder on the server is the same number of levels deep as on our dev machine—in relation to the folder in which the Build Agent puts the project file—we can put it anywhere we want and retain the relative HintPath value in the project file.
For example, in my case I ended up setting the server location to C:\Agent\Build\Packages, to match the hierarchical location of the local Git repos on my dev machine:
D:\Dev\Packages
D:\Dev\Git\app.repo\App\App.vbproj
Works great.
EDIT
Just to clarify, the action of copying the assembly from the package folder to the application bin folder isn't a NuGet action. It's an MsBuild action (i.e. the CopyLocal setting in the project's assembly reference properties).
The reason it was failing was that MsBuild couldn't find the assembly to copy, according to its relative reference as specified in the project file.
So technically my question title is incorrect. The NuGet Installer step has been working fine all along.

MSBUILD script should zip all assemblies in solution after build, but only gets some DLLs (under local and TFS build)

I want to set up my VS solution so at the end of the build, the installable files are zipped up for easy distribution. This should work under either a local build, or a TFS build. This is set up as follows:
There is one project (called MyApp.Packaging) which contains no code, just an MSBUILD .targets script
The project has references to all other projects, so builds last (confirmed by looking at the Project Build Order)
The build script contains the following to identify and zip (using MSBUILD Community Tasks' ZIP task) the EXE and DLLs into two different packages (there is other code to pull the version number from a version.txt file using MSBUILD Community Tasks - omitted for clarity)
<!-- Set package name and input/output folders -->
<PropertyGroup>
<PackageName>MyAppService</PackageName>
<BuildTargetFolder>$(TargetDir)</BuildTargetFolder>
<PackageOutputFolder>$(OutDir)</PackageOutputFolder>
</PropertyGroup>
<!-- Set location of files -->
<ItemGroup>
<MyAppBinaries Include="$(BuildTargetFolder)*.exe$(BuildTargetFolder)*.dll;" Exclude="$(BuildTargetFolder)MyApp.Packaging.dll" />
<MyAppOtherFiles Include="$(SolutionDir)MyApp.Packaging\InstallService.bat;$(SolutionDir)MyApp.Packaging\UnInstallService.bat;$(BuildTargetFolder)MyApp.HostService.exe.config" />
<MyAppContracts Include="$(BuildTargetFolder)MyApp.Common.DataContext.dll;$(BuildTargetFolder)MyApp.Common.Shared.dll" />
</ItemGroup>
<!-- After building (in Release mode only), build the installation package -->
<Target Name="AfterBuild">
<CallTarget Targets="BuildPackage" Condition="'$(Configuration)'=='Release'" />
</Target>
<!-- Build the package -->
<Target Name="BuildPackage">
<!-- Package for installing the MyApp Service -->
<Zip Files="#(MyAppBinaries);#(MyAppOtherFiles)" Flatten="True" WorkingDirectory="$(MSBuildProjectDirectory)" ZipFileName="$(PackageOutputFolder)\$(PackageName)_$(Major).$(Minor).$(Revision)_Install.zip" />
<!-- Package for MyApp Contracts -->
<Zip Files="#(MyAppContracts)" Flatten="True" WorkingDirectory="$(MSBuildProjectDirectory)" ZipFileName="$(PackageOutputFolder)\$(PackageName)_MyAppContracts_$(Major).$(Minor).$(Revision)_Install.zip" />
</Target>
The ZIP files are created in the TFS drop location when TFS does the build, or the Packaging project's bin folder for a local build.
The second ZIP (containing 2 DLLs) always gets created OK, under local and TFS build.
The problem is that when TFS does the build, the first ZIP contains no EXE and only 2 of the 23 DLLs (and all 3 of the files identified by MyAppOtherFiles). When the build is done locally (and the the Packaging project's bin folder is emptied first), the first ZIP contains no EXE or DLLs, and only the 2 .bat files identified by MyAppOtherFiles.
If I change BuildTargetFolder from $(TargetDir) to $(OutDir), I get the same result.
The TFS build definition uses an unmodified Default Template.
It is as if when TFS does the build, the Packaging project is the 3rd project to be built, rather than the last, therefore only zipping 2 DLLs. However, the solution checked into TFS is exactly the same as what I build locally, and in that case it seems the script cannot see ANY of the binaries. If the local build is done again (without emptying the Packaging project's bin folder), the ZIPs then contain all the required files, but this is obviously because after the 1st build the bin folder now contains the EXE & all the DLLs.
Its also confusing that under a TFS build the MyApp.HostService.exe.config (which is produced by the build) is zipped, but not the MyApp.HostService.exe. And why is the 2nd ZIP always created OK, when it contains DLLs that are skipped in the 1st ZIP ????? I have tried swapping the order the ZIPs are created, but it makes no difference!
What can I do to ensure that the zipping is always done after all the projects are built, under both local and a TFS build?
Thanks
Make sure you set the packaging project dependency on the solution depend on the other projects this way it will always build the others first, thus leaving you with the packaging last.
We do something similar but we have our tfs build definition setup to build the targets/proj file instead of the sln. In the targets/proj file we have a target that compiles our application and then uses wix to create a msi. In your case, you should create a target that uses the msbuild target to compile your exe project and then call the zip target to compress the output. You can leave the outdir parameter as is our you can set the property so the output goes to a directory of your choosing. Building this easy will work on both the tfs server and locally.

Make Jenkins aware of custom NuGet Package Source

I've got a little issue regarding Jenkins and NuGet package restore.
What I'm trying to do is build solutions on jenkins (which works perfectly fine). I have enabled package restore for the solution, which generates the .nuget-folder containing NuGet.exe, NuGet.Config and NuGet.targets.
On Jenkins, I am pulblishing some projects as NuGet-packages in a private package source on our server. I am using those packages in other projects, which should be build on jenkins themselves.
VS knows about the private package source, it's configured in the global NuGet.Config-file (the one under AppData) and it is not disabled (by default).
Now, when I try to build a solution which needs a package from the private package source, the build fails, because jenkins doesn't know about it, and is therefore commiting an empty -source-parameter when restoring packages which is not beeing replaced as jenkins doesn't know about the custom source.
What I've tried so far
I already know that adding the private source to the solutions NuGet.Config- or NuGet.Targets-file's Package-Source would solve the problem, but that would mean, i would have to do so for every solution I want to build using Jenkins.
I have also played around a bit with the config-files in AppData and ProgramData by adding the source in to the package-source tags in the files and even making it the active-source, but that didn't help either
of cource, commiting the packages would be a workaround, but thats not the desired outcome, as we'd like to ignore the packages in scm.
Basically, i'd like to know if there is a way to make Jenkins constantly aware of the private package source, or to manipulate the NuGet-installations on the developers maschines, so that they generate a NuGet.targets-file which contains the private package-source. An other possible fix would be a parameter for msbuild, which I'm not aware of.
Any help is greatly appreciated!
To sum up (and extend) my comments:
Nuget package restore via msbuild is deprecated in current versions of Nuget (2.7 and higher)
We use a batch step in Jenkins
nuget.exe restore SOLUTIONTOBUILD.sln -source http://nugetserver...
and avoid thereby the problem that the Jenkins service runs in a different account and searches for the .config in a different place.
On the developer machines, the packages are restored by the Nuget-VS-Addin (and not by msbuild), so don't forget to undo the changes that the old Nuget-VS-Addin may have applied to your project-files.
More Information can be found in the Nuget-Docs
Another solution to this problem is to add your custom NuGet.config and executable to a directory on the Jenkins server, and add a build step to run nuget using the custom config.
C:\nuget\nuget.exe update "%WORKSPACE%\Project.sln" -ConfigFile C:\nuget\NuGet.config
A NuGet.config adding a custom package source would look something like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageRestore>
<add key="enabled" value="True" />
<add key="automatic" value="True" />
</packageRestore>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
<add key="My Custom Package Source" value="http://localhost/guestAuth/app/nuget/v1/FeedService.svc/" />
</packageSources>
<activePackageSource>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</activePackageSource>
</configuration>
The standalone nuget.exe can be downloaded here
This approach makes it easier to add custom feeds to all your jenkins jobs by changing the same config file.
NuGet Config files used by jenkins were as follows, fixing here worked in my case , hope it helps
[Windows] Be sure that the Jenkins service account has permission to see nuget package location. In my case, I was using a local admin account that didn't have the domain perms necessary to navigate the network location of our NuGet folder. Also, be sure the packages aren't nested too deeply.

Specify NuGet sources for build server to use with NuGet Package Restore?

I'm using NuGet Package Restore. I want to specify custom sources during a TFS build server process.
The NuGet.targets file in the hidden '.nuget' folder says that you can either specify sources repositories, or that it will fall back to the NuGet.config in %APPDATA%\NuGet\NuGet.config.
There is however a NuGet.config in the hidden '.nuget' folder as well. I assumed that if you did not specify sources repositories in NuGet.targets that it would fall back to the NuGet.config in the hidden '.nuget' folder. This doesn't seem to be the case.
Any ideas?
With the current version of NuGet it's possible to specify custom repositories in the solution's NuGet.config file and enable package restore during a build.
Having this NuGet.config file allowed us to automatically restore packages from internal repository under a TFS build without any other actions in the build definition:
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
<packageSources>
<add key="Internal" value="http://MyInternalRepository/nuget" />
</packageSources>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
</configuration>
Note: TFS2013's default Build Process Templates already implements NuGet Package Restore workflow without any special configuration as stated here: http://docs.nuget.org/docs/reference/package-restore-with-team-build
If you enable package restore, you'll find a NuGet.targets MSBuild file in the $(SolutionDir)\.nuget folder.
You can set the package sources by modifying the <PackageSources>""</PackageSources> element.
Example:
<!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config -->
<PackageSources>"http://packages.nuget.org/api/v2/;http://myget.org/F/myfeed/"</PackageSources>
According to pranavkm, one of the NuGet devs, at the time of this writing NuGet Package Restore will not use the NuGet.config in the hidden '.nuget' folder for sources. It's only used at the moment for a solution specific setting (to ignore source control bindings). He says it is on the radar for the NuGet team to leverage all aspects of NuGet.config but that it keeps getting bumped in priority.
Another option is to add sources to a machine-wide (not user-specific) nuget config on the build server.
https://stackoverflow.com/a/27569020/374837
in tfs build 2017 when you use the NuGet Restore task version 1.* you can select the NuGet.Config file to use during the build.
See image below NuGet Restore Task

Resources