Automate Artifactory NuGet download during build in Visual Studio - visual-studio

I have been working with Artifactory NuGet packages in Visual Studio 2019 recently, and have a workflow which looks sort of like this:
Add private Artifactory repo as NuGet Package Source
Download specific older version of my NuGet package [either using Package Manager UI or Package Manager Console]
Once NuGet package is installed, build VS2019 project
I need to eliminate the need for a user to know how to go through these steps, and make it as simple as possible for a Visual Studio 2019 project to automatically install a specific version of my private NuGet package hosted in artifactory.
I've been trying to accomplish this but with no luck, I'm not sure if this would best be done by editing the Visual Studio project file, or by editing the windows global nuget.config file, or create a custom nuget.config file for my visual studio project.
Any advice/help would be appreciated, thanks.

Since your question does not contain relevant information like if you're using a Visual Studio Solution (*.sln file), Git, etc., I can only have a guess 😉
Assuming you're using Git and having a folder structure like this:
- MyProject
- .git
- MyProject.sln
- ProjectA
- ProjectA.csproj
- ProjectB
- ProjectB.csproj
Now you can create a file MyProject/NuGet.config with the following content and put it under version control:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="Your Artifactory source" value="https://your.artifactory.source/v3/index.json" />
</packageSources>
</configuration>
According to the docs, NuGet should pick up NuGet.config automatically.

Related

Including Nuget Content Files to Target Projects Publish on .net Core Project

before i start i must state that i pretty new to this nuget package things, so come basic at me.
My app has a core project to carry some .dll and .sql files and an api project. I have made the core project a nuget package with dotnet pack and automated it on github action so it creates a new version at all prs and pushes it to my private nuget server and it is all fine till here.
When i install this core package to my api project, there is no problem either. It installs successfully and my sql files shows up on the target project as i expected(but as linked sources).
But when i try to publish this project with dotnet pack, the .sql files are not copied to output folder. I looked to the properties of the files and saw that their copy to output directory prop has been reset to do not copy and the file path was absolute.
My goal is to build and deploy this api with github actions so absolute paths are not acceptable and besides i don't want to arrange something in the target project manually.
I'm packing the core project with dotnet pack
I don't have any
.nuspec file
package config xml
nuget config
package metadata
or other things like than and i don't know how to use them.
I have tried adding to csproj file <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> and <RestoreProjectStyle>PackageReference</RestoreProjectStyle> things and they did not work.
I have tried adding to csproj file
and it did not work too.
Can anyone help me?
The only thing you need to do is that you should write this node <PackageCopyToOutput>true</PackageCopyToOutput> to every content file of the nuget net core project:
<ItemGroup>
<Content Include="Queries\Account\CheckAccountRef.sql">
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
.....
</ItemGroup>
Then, re-pack your nuget project with dotnet pack and then reinstall this new version into your main project. Before you install, you should delete the old caches under C:\Users\xxx\.nuget\packages.
There is a similar issue about this.
You can use .nuspec file to configure all your dependencies. Please refer https://learn.microsoft.com/en-us/nuget/reference/nuspec

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.

Internally distribute a Visual Studio Template using Nuget and SVN

Suppose we have a Visual Studio template that we would like to distribute within our organization. This template is hosted on an SVN server. I would like users to be able to point Nuget to the SVN location and get the template installed in the proper location just like any other package. Is this possible?
Is this possible?
We can do it but individuals do NOT recommend it.
How
According to the NuGet document:
Put simply, a NuGet package is a single ZIP file with the .nupkg
extension that contains compiled code (DLLs), other files related to
that code, and a descriptive manifest that includes information like
the package's version number. Developers with code to share create
packages and publish them to a public or private host. Package
consumers obtain those packages from suitable hosts, add them to their
projects, and then call a package's functionality in their project
code. NuGet itself then handles all of the intermediate details.
However, the Visual Studio Template is a file with the .zip extension, which could not be recognized by NuGet. Even if we point NuGet to the SVN location, NuGet still can not recognize it.
To resolve this issue, we have to create a NuGet package to include this Visual Studio Template .zip file, like:
<files>
<file src="TestDemo.zip" target="Tools\TestDemo.zip" />
</files>
Besides, there is another question, when we install this nuget package to the project, this Visual Studio Template .zip file would be downloaded to the \packages folder in the solution folder. We have to move it to the Visual Studio Templates folder.
So, we have to add .targets with copy task in that nuget package to copy zip file to the Visual Studio Templates folder.
The content of .targets file:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyTemplate" BeforeTargets="Build">
<Message Text="Copy Template to template folder."></Message>
<Copy
SourceFiles="$(SolutionDir)packages\MyTemplatePackage.1.0.0\Tools\TestDemo.zip"
DestinationFolder="$(USERPROFILE)\Documents\Visual Studio 2017\Templates\ProjectTemplates"
/>
</Target>
</Project>
Finally, the .nuspec file like following:
<?xml version="1.0"?>
<package >
<metadata>
<id>MyTemplatePackage</id>
<version>1.0.0</version>
<authors>Tester</authors>
<owners>Tester</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package description</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2018</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="TestDemo.zip" target="Tools\TestDemo.zip" />
<file src="MyTemplatePackage.targets" target="Build\MyTemplatePackage.targets" />
</files>
</package>
Then pack this .nuspec file, add this nuget package to the SVN location, add the SVN location to the nuget package source, you can install this nuget package to the project, and build the project, Visual Studio will download that nuget package and copy .zip file to the Visual Studio Templates folder.
I have created a sample test nuget package and it work fine on my side with Visual Studio 2017, you can test it on VS2017: https://1drv.ms/u/s!Ai1sp_yvodHf2Vax7TzuC6HQUD5w
Why not recommend
Just as you can see above, it is not easy and simple to do this, we have to do a lot of things to create that nuget package. What`s more, in order to get the template we have to create a project and install that package and build the project. It pulls in too many extra operations. Besides, when you change anything in the template, you have to re-create this package and install it.
Since this template is hosted on an SVN server, you can just check it to the Visual Studio template folder, this will be more effective.
Hope this complicated answer helps.

MSBuild Macro for NuGet package directory

I'm working on a NuGet package that adds a step to the build process by using a .targets file.
I need to reference other files from my NuGet package in order to complete the build successfully.
In the past, I've used $(SolutionDir)packages\MyPackage and all has worked fine.
However, I was just playing around with the VS 2017 RC, and I noticed that my package was installed in the global NuGet package directory, not in the solution folder.
Is there some macro that I can use from MSBuild, that contains the path for the NuGet packages folder? It is a requirement that I maintain compatibility with VS2012.
The $(NuGetPackageRoot) macro points to the package root.
You can use an alternative method that create a NuGet.Config file in the root of the \Solutions\ folder to set the package repositoryPath of VS 2017 RC, add to NuGet.Config the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
For the repositoryPath setting, you can specify an absolute path or relative path (recommended) using the $ token. The $ token is based on where the NuGet.Config is located. In this case, you package will install in $(SolutionDir)packages\ folder, you can used $(SolutionDir)packages\MyPackage for Visual Studio 2017 RC. It`s also maintain compatibility with VS2012.

Install NuGet packages to Project Dirs instead of Solution Dir?

I have a solution in Visual Studio 2015 with about 40 projects in it. Some of these projects have some NuGet packages referenced.
Due to a combination of our branching strategy (where each project folder is branched individually) and our security requirements (that the NuGet binaries are actually checked into TFS) I would like the NuGet packages for each Project to be installed into each Project's folder, not in the solution's folder. Space usage is not a concern here.
I've looked at:
https://docs.nuget.org/consume/nuget-config-file
https://docs.nuget.org/Release-Notes/NuGet-2.1#Specify-packages-Folder-Location
And they've helped my understanding of how the config files work... but I can't seem to get it to do what I want.
I've tried this in my config file:
<configuration>
<config>
<add key="repositoryPath" value="$(ProjectDir)\Nuget\" />
</config>
</configuration>
But it creates a folder in the solution folder actually called '$(ProjectDir)'.
And I can't hardcode the path to the project folders (i.e. 'C:\myteam\teampackages' in the NuGet docs) as pretty much everyone in the team have different paths to their local workspaces!
How can I do this?
Firstly, you should not check in NuGet packages into TFS Version Control. As one of the advantages of using NuGet is that you can use it to avoid checking in binaries to your version control system.
Instead, you need to restore NuGet packages during TFS build process and the required packages will be downloaded. In VS2015, you need to follow steps in this blog: https://docs.nuget.org/consume/package-restore/team-build).
Some key steps are (assume you're working with XAML build):
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.
The Nuget docs mentions specifying package folder location is to have many different solutions share the same package. This is an opposite scenario as your. Repository path setting only allows you to install the NuGet packages in the specified folder (like C:\teampackages ) or for relative path (like ../Nuget).
To make installing package in different repositoryPath, you can try:
<configuration>
<config>
<add key="repositoryPath" value="../Nuget" />
</config>
</configuration>
Check case: Is it possible to change the location of packages for NuGet?

Resources