Skip to content

Add support for nuget v2 OData package entry endpoints

What does this MR do and why?

To be able to install Nuget packages using NuGet v2 feed, the following endpoints should be supported:

  • GET /api/v4/projects/<project_id>/packages/nuget/v2/$metadata ( !128786 (merged))

    • This endpoint isn't documented anymore but it's publicly available at https://www.nuget.org/api/v2/$metadata, so I followed the NuGet implementation and twisted its response to suit our needs.
  • GET /api/v4/projects/<project_id>/packages/nuget/v2/FindPackagesById()?id='<package_name'

    • Implemented as documented here. I simplified the XML response so it's limited to just the <entry> representation of the package with the minimum needed attributes:
      <?xml version="1.0" encoding="UTF-8"?>
      <entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xml:base="http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2">
        <id>http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/Packages(Id='<package_name>',Version='0.0.0-latest-version')</id>
        <category term="V2FeedPackage" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
        <title type="text">package</title>
        <content type="application/zip" src="http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/download/<package_name>/latest"/>
       <m:properties>
          <d:Version>0.0.0-latest-version</d:Version>
       </m:properties>
     </entry>
    • Note the 0.0.0-latest-version inside the <d:Version> node. This endpoint is public because the clients such as choco & nuget don't send the authentication credentials with this request but sent in the subsequent download request. Thus, we cannot reveal the actual latest version of a package before authenticating the request. In order to work around this issue, I had to respond with this dummy version 0.0.0-latest-version. It should adhere to SemVer rules; that's why I put the 0.0.0 prefix.
  • GET /api/v4/projects/<project_id>/packages/nuget/v2/Packages()?$filter=(tolower(Id) eq '<package_name>')

    • Same implementation and response as FindPackagesById() endpoint.
  • GET /api/v4/projects/<project_id>/packages/nuget/v2/Packages(Id='<package_name>',Version='<package_version>')

    • Same implementation and response as FindPackagesById() & Packages() endpoints with the difference that it gets called when the client sends a specific package version to be installed.
  • GET /api/v4/projects/<project_id>/packages/nuget/v2/download/<package_name>/<package_version> (!129126 (merged))

    • This is similar to the v3 feed download endpoint. The client receives it in the response of one of the previous endpoints:
     <content type="application/zip" src="http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/download/<package_name>/<package_version or latest>"/>

Here's the sequence of requests in case of installing a package using choco or nuget which support NuGet v2 feed:

  • When executing this command (install specific version):

      choco install PackageName -Source gitlab --version=1.0.8
      --or
      nuget install PackageName -Source gitlab -Version 1.0.8
    1. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/
    2. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/$metadata
    3. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/Packages(Id='PackageName',Version='1.0.8')
    4. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/download/PackageName/1.0.8
  • When executing this command (install the latest version):

      choco install PackageName -Source gitlab
    1. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/
    2. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/$metadata
    3. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/Packages()?$filter=(tolower(Id) eq 'PackageName') and IsLatestVersion
    4. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/download/PackageName/latest
  • When executing this command (install the latest version):

      nuget install PackageName -Source gitlab
    1. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/
    2. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/$metadata
    3. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/FindPackagesById()?$filter=IsLatestVersion&$orderby=Version%20desc&$top=1&id='PackageName
    4. GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/download/PackageName/latest

How to set up and validate locally

We cannot test the full install cycle until the other 2 needed MRs (!128786 (merged) & !129126 (merged)) are merged. Instead, the endpoints introduced in this MR can be tested using curl or directly in the browser:

GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/Packages()?$filter=(tolower(Id) eq '<package_name>')
GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/FindPackagesById()?id='<package_name>'
GET http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/Packages(Id='<package_name>',Version='<package_version>')

An XML response for the OData package entry should be returned:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xml:base="http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2">
  <id>http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/Packages(Id='<package_name>',Version='<package_version>')</id>
  <category term="V2FeedPackage" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
  <title type="text">moaz</title>
  <content type="application/zip" src="http://gdk.test:3000/api/v4/projects/<project_id>/packages/nuget/v2/download/<package_name>/<package_version>"/>
  <m:properties>
    <d:Version>1.4</d:Version>
  </m:properties>
</entry>

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #416405 (closed)

Edited by Moaz Khalifa

Merge request reports