GlitchEnzo / NuGetForUnity

A NuGet Package Manager for Unity
MIT License
3.25k stars 319 forks source link

Cannot find updates for packages located in JFrog Artifactory #666

Open RoBit666 opened 2 months ago

RoBit666 commented 2 months ago

Description

Does not find updates for packages located in JFrog Artifactory. The "Online" tab shows packages from JFrog, the "Updates" tab is empty. If you manually change the version in the "packages.config" file, the updated package will be downloaded. There are no errors in the console. The NuGet tool in Rider correctly shows updates from JFrog, so I think the problem is not in the packages themselves or JFrog

Attempting to use protocol version 3 results in an error.

Initialization of api client for 'https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/' failed so we can't use it. error (cached): System.InvalidOperationException: missing '@id' property inside resource of type ''
  at NugetForUnity.PackageSource.NugetApiClientV3.InitializeApiAddressesAsync (NugetForUnity.PackageSource.NugetPackageSourceV3 packageSource) [0x001b7] in .\Library\PackageCache\com.github-glitchenzo.nugetforunity@4.1.1\Editor\PackageSource\NugetApiClientV3.cs:649 
  at NugetForUnity.PackageSource.NugetApiClientV3.EnsureInitializedAsync (NugetForUnity.PackageSource.NugetPackageSourceV3 packageSource) [0x00049] in .\Library\PackageCache\com.github-glitchenzo.nugetforunity@4.1.1\Editor\PackageSource\NugetApiClientV3.cs:596 .
UnityEngine.Debug:LogError (object)
NugetForUnity.PackageSource.NugetApiClientV3/<EnsureInitializedAsync>d__28:MoveNext () (at ./Library/PackageCache/com.github-glitchenzo.nugetforunity@4.1.1/Editor/PackageSource/NugetApiClientV3.cs:601)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<bool>:Start<NugetForUnity.PackageSource.NugetApiClientV3/<EnsureInitializedAsync>d__28> (NugetForUnity.PackageSource.NugetApiClientV3/<EnsureInitializedAsync>d__28&)
NugetForUnity.PackageSource.NugetApiClientV3:EnsureInitializedAsync (NugetForUnity.PackageSource.NugetPackageSourceV3)
NugetForUnity.PackageSource.NugetApiClientV3/<SearchPackageAsync>d__13:MoveNext () (at ./Library/PackageCache/com.github-glitchenzo.nugetforunity@4.1.1/Editor/PackageSource/NugetApiClientV3.cs:143)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<System.Collections.Generic.List`1<NugetForUnity.Models.INugetPackage>>:Start<NugetForUnity.PackageSource.NugetApiClientV3/<SearchPackageAsync>d__13> (NugetForUnity.PackageSource.NugetApiClientV3/<SearchPackageAsync>d__13&)
NugetForUnity.PackageSource.NugetApiClientV3:SearchPackageAsync (NugetForUnity.PackageSource.NugetPackageSourceV3,string,int,int,bool,System.Threading.CancellationToken)
NugetForUnity.PackageSource.NugetPackageSourceV3/<>c__DisplayClass53_0/<<GetUpdates>b__0>d:MoveNext () (at ./Library/PackageCache/com.github-glitchenzo.nugetforunity@4.1.1/Editor/PackageSource/NugetPackageSourceV3.cs:220)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<System.Collections.Generic.List`1<NugetForUnity.Models.INugetPackage>>:Start<NugetForUnity.PackageSource.NugetPackageSourceV3/<>c__DisplayClass53_0/<<GetUpdates>b__0>d> (NugetForUnity.PackageSource.NugetPackageSourceV3/<>c__DisplayClass53_0/<<GetUpdates>b__0>d&)
NugetForUnity.PackageSource.NugetPackageSourceV3/<>c__DisplayClass53_0:<GetUpdates>b__0 ()
System.Threading._ThreadPoolWaitCallback:PerformWaitCallback ()

Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="NuGet" value="http://www.nuget.org/api/v2/" />
    <add 
      key="Artifactory" 
      value="https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/" 
      protocolVersion="3"
      packageDownloadUrlTemplateOverwrite="https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration-semver2/Download/{0}/{1}"
      updateSearchBatchSize="1"
      />
  </packageSources>
  <disabledPackageSources />
  <packageSourceCredentials>
    <Artifactory>
      <add key="userName" value="***" />
      <add key="clearTextPassword" value="***" />
    </Artifactory>
  </packageSourceCredentials>
  <activePackageSource>
    <add key="All" value="(Aggregate source)" />
  </activePackageSource>
  <config>
    <add key="packageInstallLocation" value="InPackagesFolder" />
    <add key="repositoryPath" value="./Packages" />
    <add key="PackagesConfigDirectoryPath" value="." />
    <add key="DefaultPushSource" value="http://www.nuget.org/api/v2/" />
    <add key="slimRestore" value="true" />
  </config>
</configuration>
igor84 commented 2 months ago

Hi. I am using Artifactory and I don't have any issues with the Updates. You configuration seems ok. For each installed package updates should be fetched using a link that looks like https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/query?semVerLevel=2.0.0&q=%20packageid%3Ayour.packageid so you can check if that Url works ok from the browser.

The error you are getting suggests that when you open this url https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local in the browser you get a json with an array under "resources" key and that some object in that array does not have a field "@id". Can you verify that? It should look something like this:

{
  "version": "3.0.0",
  "resources": [
    {
      "@id": "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/query",
      "@type": "SearchQueryService",
      "comment": "Query endpoint of NuGet Search service (primary)"
    },
    {
      "@id": "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/",
      "@type": "RegistrationsBaseUrl",
      "comment": "Base URL of Azure storage where NuGet package registration info is stored"
    },
    [MORE ELEMENTS LIKE THE TWO ABOVE EACH HAVING @id FIELD]
  ]
}
RoBit666 commented 2 months ago

Hi! This is what I got for https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/query?semVerLevel=2.0.0&q=%20packageid%3A***.Contracts in the browser. The package version in the project I selected for query is 1.0.17.

{
  "totalHits" : 1,
  "data" : [ {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration-semver2/***.contracts/index.json",
    "registration" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration-semver2/***.contracts/index.json",
    "id" : "***.Contracts",
    "version" : "1.0.18",
    "description" : "Package Description",
    "authors" : [ "***.Contracts" ],
    "totalDownloads" : 34,
    "verified" : false,
    "versions" : [ ... ]
  } ]
}

Result https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/:

{
  "version" : "3.0.0",
  "resources" : [ 
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/query",
    "@type" : "SearchQueryService",
    "comment" : "Query endpoint of NuGet Search service (primary)"
  }, 
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/",
    "@type" : "RegistrationsBaseUrl",
    "comment" : "Base URL of Azure storage where NuGet package registration info is stored"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/***-nuget-local",
    "@type" : "LegacyGallery"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/***-nuget-local",
    "@type" : "LegacyGallery/2.0.0"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/***-nuget-local",
    "@type" : "PackagePublish/2.0.0"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/symbols",
    "@type" : "SymbolPackagePublish/4.9.0"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/query",
    "@type" : "SearchQueryService/3.0.0-rc",
    "comment" : "Query endpoint of NuGet Search service (primary) used by RC clients"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/",
    "@type" : "RegistrationsBaseUrl/3.0.0-rc",
    "comment" : "Base URL of Azure storage where NuGet package registration info is stored used by RC clients. This base URL does not include SemVer 2.0.0 packages."
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/{id-lower}/index.json",
    "@type" : "PackageDisplayMetadataUriTemplate/3.0.0-rc",
    "comment" : "URI template used by NuGet Client to construct display metadata for Packages using ID"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/{id-lower}/{version-lower}.json",
    "@type" : "PackageVersionDisplayMetadataUriTemplate/3.0.0-rc",
    "comment" : "URI template used by NuGet Client to construct display metadata for Packages using ID, Version"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/query",
    "@type" : "SearchQueryService/3.0.0-beta",
    "comment" : "Query endpoint of NuGet Search service (primary) used by beta clients"
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/",
    "@type" : "RegistrationsBaseUrl/3.0.0-beta",
    "comment" : "Base URL of Azure storage where NuGet package registration info is stored used by Beta clients. This base URL does not include SemVer 2.0.0 packages."
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration/",
    "@type" : "RegistrationsBaseUrl/3.4.0",
    "comment" : "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL does not include SemVer 2.0.0 packages."
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration-semver2/",
    "@type" : "RegistrationsBaseUrl/3.6.0",
    "comment" : "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
  },
  {
    "@id" : "https://***.jfrog.io/artifactory/api/nuget/v3/***-nuget-local/registration-semver2/",
    "@type" : "RegistrationsBaseUrl/Versioned",
    "comment" : "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages.",
    "clientVersion" : "4.3.0-alpha"
  } ]
}
igor84 commented 2 months ago

I think I see what is the problem. We are parsing this json into a C# class and since we can't call class fields @id and @type we call them in code atId and atType and in order for json deserialization to populate those fields we are first doing responseString.Replace(@"""@id"":", @"""atId"":").Replace(@"""@type"":", @"""atType"":"). The issue is that in your json the fields have an additional space after the name and before the : character so our Replace code fails to properly prepare the string for parsing. I wonder why is your Artifactory adding that additional space since it works for us and we know there are other users using Artifactory without issue as well. Can you tell us what version of Artifactory are you using?

I guess we could modify our replace code to work in either case...

RoBit666 commented 2 months ago

We didn't deploy our own Artifactory, but used the jfrog platform

RoBit666 commented 2 months ago

Yes, I fixed responseString.Replace and everything worked