fsprojects / fsprojects/Paket

Paket fails to download private GitHub packages

Open
#3,848 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
F#
Stars
2.1k
Forks
528
Avg merge
1d 12m
Merged PRs (30d)
54

Description

Description

I have a private GitHub repo with NuGet packages in it. When I supply the private feed's username and password, Paket is able to fetch the package index and find appropriate versions of my package, but it then fails at the download step. My package is called CommandLineParser.RMunn and is a fork of https://github.com/commandlineparser/commandline/ with some extra PRs included compared to the official CommandLineParser package.

Repro steps

Please provide the steps required to reproduce the problem

  1. Create a private GitHub repo and upload a NuGet package to it (in my case, https://github.com/rmunn/test-build-commandline/ but you won't be able to see that repo).

  2. Add the following to paket.dependencies:

    source https://nuget.pkg.github.com/rmunn/index.json username: "rmunn" password: "%PRIVATE_FEED_PASS%" authtype: "basic"
    storage: none
    nuget CommandLineParser.RMunn ~> 2.8
    

    (Rest of paket.dependencies trimmed for clarity)

  3. Run PRIVATE_FEED_PASS=*** paket install -v

Unfortunately, I can't attach this package to a public repro repository as GitHub only allows one repository to be associated with a given NuGet package (by package name). But it should be easy to reproduce by creating a test package with a new name and putting it in GitHub Packages in a new private repo.

Expected behavior

The packages download and are installed.

Actual behavior

Logs of paket install -v, trimmed to the most relevant parts:

Paket version 5.231.2
found: /home/rmunn/code/csharp/CheckDB/paket.dependencies
Parsing /home/rmunn/code/csharp/CheckDB/paket.dependencies
Skipping resolver for group Build since it is already up-to-date
Skipping resolver for group Test since it is already up-to-date
Resolving packages for group Main:
   0 packages in resolution.
   2 requirements left
     - Packaging.Targets, 0.1.155 (from /home/rmunn/code/csharp/CheckDB/paket.dependencies)
     - CommandLineParser.RMunn, >= 2.8 < 3.0 (from /home/rmunn/code/csharp/CheckDB/paket.dependencies)

  Trying to resolve Packaging.Targets 0.1.155 (from /home/rmunn/code/csharp/CheckDB/paket.dependencies)
 - Packaging.Targets 0.1.155
Starting request to 'https://nuget.pkg.github.com/rmunn/index.json'
Starting request to 'https://nuget.pkg.github.com/rmunn/index.json'
Starting request to 'https://api.nuget.org/v3/index.json'
Starting request to 'https://www.nuget.org/api/v2/FindPackagesById()?semVerLevel=2.0.0&id='Packaging.Targets''
   Found Explored Package  Packaging.Targets 0.1.155
Starting request to 'https://www.nuget.org/api/v2/FindPackagesById()?semVerLevel=2.0.0&id='System.Buffers''
   1 packages in resolution.
     - Packaging.Targets, 0.1.155
   2 requirements left
     - CommandLineParser.RMunn, >= 2.8 < 3.0 (from /home/rmunn/code/csharp/CheckDB/paket.dependencies)
     - System.Buffers, >= 4.5 (from Packaging.Targets 0.1.155)

  Trying to resolve CommandLineParser.RMunn >= 2.8 < 3.0 (from /home/rmunn/code/csharp/CheckDB/paket.dependencies)
Starting request to 'https://nuget.pkg.github.com/rmunn/download/commandlineparser.rmunn/index.json?semVerLevel=2.0.0'
Source 'https://nuget.pkg.github.com/rmunn/index.json' yielded no results
Request failed with '401': 'https://nuget.pkg.github.com/rmunn/download/commandlineparser.rmunn/index.json?semVerLevel=2.0.0'
Starting request to 'https://nuget.pkg.github.com/rmunn/download/commandlineparser.rmunn/index.json?semVerLevel=2.0.0'
Request failed with '401': 'https://nuget.pkg.github.com/rmunn/download/commandlineparser.rmunn/index.json?semVerLevel=2.0.0'
Source 'https://nuget.pkg.github.com/rmunn/index.json' yielded no results
 - Request 'https://nuget.pkg.github.com/rmunn/download/commandlineparser.rmunn/index.json?semVerLevel=2.0.0' finished with: System.Exception: Not authorized (401)

Looking for the text "Request failed with" in the Paket source led me to the failIfNoSuccess function in NetUtils.fs, which is then used in HttpClient.DownloadFileTaskAsync. It looks like there are comments in createHttpClient (in the same file) about how sending HTTP Basic Authentication credentials in the initial request fails with 404 and credentials are only expected after the server responds to the initial request with a 401. But that doesn't seem to be taken into account in the failIfNoSuccess function, which is apparently considering a 401 to be a failure, without ever attempting to handle the 401 by sending network credentials.

Known workarounds

The only workaround I've found is to use the dotnet CLI to install the package (which works if the right nuget.config file is created), and then reference my locally-downloaded copy of the package in paket.dependencies.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/Paket.Core/Common/NetUtils.fs, reading createHttpClient and failIfNoSuccess, then trace their use through HttpClient.DownloadFileTaskAsync. Reproduce the authenticated download with the paket.dependencies entry and verbose paket install shown here. Done means Paket downloads and installs a private GitHub Packages NuGet package instead of returning 401.

Written by the indexing model from the issue text.

Assessment

Tech stack
fsharp, github
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.