If you want to upload a NuGet package you downloaded, or maybe one you created yourself, to your company's NuGet feed, but that feed uses NuGet 3 instead of NuGet 2; fear no more. I will show you how to push that package to NuGet 3 feed in your app.
So in NuGet version 2, all you needed was to use the Nuget.Core package in your app, and with a few lines of code you could upload you're package to any version 2 feed. That is no longer the case in NuGet v3.
Below you will find a utility class that can download a NuGet package (given its id) and upload a NuGet package (given the .nupkg file) to NuGet v3 feed, using NuGet API v3:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NuGet.Common;
using NuGet.Configuration;
using NuGet.Packaging.Core;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using NuGet.Versioning;
namespace NuGetPackageSigner.Helpers
{
internal static class NuGetHelper
{
public async static Task<string> DownloadPackage(string nugetRepositoryUrl, string packageId, string downloadDirectory)
{
string downloadedNugetPackageFilePath;
List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
providers.AddRange(Repository.Provider.GetCoreV3());
PackageSource packageSource = new PackageSource(nugetRepositoryUrl);
SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
using (var sourceCacheContext = new SourceCacheContext())
{
var findResource = await sourceRepository.GetResourceAsync<FindPackageByIdResource>(CancellationToken.None);
IEnumerable<NuGetVersion> versions =
await findResource.GetAllVersionsAsync(packageId, sourceCacheContext, NullLogger.Instance, CancellationToken.None);
if (!versions.Any())
throw new Exception($"Cannot locate package id {packageId} in repository {nugetRepositoryUrl}.");
PackageIdentity newestPackageIdentity = new PackageIdentity(packageId, versions.Where(version => version.IsLegacyVersion == false).Max());
string completePackageName = newestPackageIdentity.Id + "." + newestPackageIdentity.Version.ToString();
string packageDownloadFilePath = Path.Combine(downloadDirectory, completePackageName);
var packageDownloadContext = new PackageDownloadContext(sourceCacheContext, packageDownloadFilePath, true);
using (DownloadResourceResult downloadResult = await NuGet.PackageManagement.PackageDownloader.GetDownloadResourceResultAsync(
new List<SourceRepository> { sourceRepository }, newestPackageIdentity, packageDownloadContext, "",
NullLogger.Instance, CancellationToken.None))
{
if (downloadResult.Status == DownloadResourceResultStatus.NotFound)
throw new Exception($".nupkg file not found for package {packageId} in repository {nugetRepositoryUrl}.");
if (downloadResult.Status == DownloadResourceResultStatus.Cancelled)
throw new Exception($"Download of .nupkg file was cancelled for package {packageId}. Please try again.");
if (downloadResult.Status == DownloadResourceResultStatus.AvailableWithoutStream)
throw new Exception($"Error retrieving stream of the downloaded .nupkg file for package {packageId}. Please try again.");
downloadedNugetPackageFilePath = Path.Combine(packageDownloadFilePath, completePackageName + ".nupkg");
using (FileStream fileStream = File.Create(downloadedNugetPackageFilePath, (int)downloadResult.PackageStream.Length))
{
byte[] bytesInStream = new byte[downloadResult.PackageStream.Length];
downloadResult.PackageStream.Read(bytesInStream, 0, (int)downloadResult.PackageStream.Length);
fileStream.Write(bytesInStream, 0, (int)downloadResult.PackageStream.Length);
}
}
}
return downloadedNugetPackageFilePath;
}
public async static Task UploadPackage(string nugetRepositoryUrl, string packagePath, string apiKey)
{
List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
providers.AddRange(Repository.Provider.GetCoreV3());
PackageSource packageSource = new PackageSource(nugetRepositoryUrl);
SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
using (var sourceCacheContext = new SourceCacheContext())
{
PackageUpdateResource uploadResource = await sourceRepository.GetResourceAsync<PackageUpdateResource>();
await uploadResource.Push(packagePath, null, 480, false, (param) => apiKey, null, NullLogger.Instance);
}
}
}
}
Hope this helps someone, as there is not much documentation on the subject.
TYVM - 'not much documentation' is something of an understatement...