Paket fails to download private GitHub packages
Nobody has claimed this yet.
- 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
-
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).
-
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.dependenciestrimmed for clarity) -
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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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