Home: add `dotnet nuget <add|remove|update|disable|enable|list> source` command

Created on 18 Dec 2016  路  23Comments  路  Source: NuGet/Home

Update on 2/6/2020 from @rrelyea:
Fixed with: https://github.com/NuGet/NuGet.Client/pull/3206
Spec link: https://github.com/NuGet/Home/wiki/Add-nuget-sources-command-to-the-dotnet-CLI


Original text:

Moving from https://github.com/dotnet/cli/issues/5053#issuecomment-267794961 on behalf of @meichtf, @emgarten.


Steps to reproduce

try to add a username/ClearTextPassword in the dotnet restore --source command

Expected behavior

My nuget repository requires authentication and it is not possible to add a username/ClearTextPassword in the dotnet restore command for a source

Actual behavior

It's not possible to add a username/ClearTextPassword for a ..source

Environment data

dotnet --info output:
.NET Command Line Tools (1.0.0-preview2-1-003177)

Product Information:
Version: 1.0.0-preview2-1-003177
Commit SHA-1 hash: a2df9c2576

Runtime Environment:
OS Name: Windows
OS Version: 10.0.14393
OS Platform: Windows
RID: win10-x64

Settings Xplat NeedsTriageDiscussion Feature

Most helpful comment

As a temporary workaround, here's a basic powershell script that can be used with Powershell Core anywhere that the dotnet cli runs:

[CmdletBinding()]
param (
    [Parameter(Mandatory = $true)][string]$ConfigFile,
    [Parameter(Mandatory = $true)][string]$Source,
    [Parameter(Mandatory = $true)][string]$Username,
    [Parameter(Mandatory = $true)][string]$Password
)
$doc = New-Object System.Xml.XmlDocument
$filename = (Get-Item $ConfigFile).FullName
$doc.Load($filename)

$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
if ($creds -eq $null)
{
    $creds = $doc.CreateElement("packageSourceCredentials")
    $doc.DocumentElement.AppendChild($creds) | Out-Null
}

$sourceElement = $creds.SelectSingleNode($Source)
if ($sourceElement -eq $null)
{
    $sourceElement = $doc.CreateElement($Source)
    $creds.AppendChild($sourceElement) | Out-Null
}

$usernameElement = $sourceElement.SelectSingleNode("add[@key='Username']")
if ($usernameElement -eq $null)
{
    $usernameElement = $doc.CreateElement("add")
    $usernameElement.SetAttribute("key", "Username")
    $sourceElement.AppendChild($usernameElement) | Out-Null
}
$usernameElement.SetAttribute("value", $Username)

$passwordElement = $sourceElement.SelectSingleNode("add[@key='ClearTextPassword']")
if ($passwordElement -eq $null)
{
    $passwordElement = $doc.CreateElement("add")
    $passwordElement.SetAttribute("key", "ClearTextPassword")
    $sourceElement.AppendChild($passwordElement) | Out-Null
}
$passwordElement.SetAttribute("value", $Password)

$doc.Save($filename)

I used it in a GitHub Actions workflow with the following YAML:

    - name: Set NuGet creds
      shell: pwsh
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: ./Set-NuGetCredentials -ConfigFile ./nuget.config -Source gpr-test -Username zivkan -Password $env:GITHUB_TOKEN

All 23 comments

Are there any plans for this to be looked at sometime soon? There's currently no way to add the source with authentication through the dotnet cli. The only workaround is to add the source then manually patch the config, which is far from ideal.

Any idea of when this will be added? :(

yes any update?

Wondering the status of this as well - hitting this on the non-Windows platforms right now where NuGet.exe doesn't exist.

For those stuck and needing a workaround for docker, like I did, this is what I did for now:
1) Created docker-compose.ci.build.yml

version: '2'

services:
  ci-build:
    image: microsoft/aspnetcore-build:2.0.5-2.1.4-stretch
    volumes:
      - .:/src
    working_dir: /src
    environment:
      - PACKAGESUSERNAME=${PACKAGESUSERNAME}
      - PACKAGESPAT=${PACKAGESPAT}
    command: /bin/bash "./build.sh"

2) Create a nuget.ci.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <config>
    </config>
    <packageRestore>
        <!-- Allow NuGet to download missing packages -->
        <add key="enabled" value="True" />
    </packageRestore>
    <packageSources>
        <add key="packages" value="YOURPRIVATREPOLOCATIONHERE" />
        <add key="Nuget official package source" value="https://api.nuget.org/v3/index.json" />
    </packageSources>
  <packageSourceCredentials>
    <packages>
      <add key="Username" value="PackagesUsername" />
      <add key="ClearTextPassword" value="PackagesPAT" />
    </packages>
  </packageSourceCredentials>
</configuration>

3) Create build.sh

#!/bin/bash
: "${PACKAGESUSERNAME:?Need to set environment variable PACKAGESUSERNAME}"
: "${PACKAGESPAT:?Need to set environment variable PACKAGESPAT}"

sed -r "s/PACKAGESUSERNAME/$PACKAGESUSERNAME/i" ./nuget.ci.config \
    | sed -r "s/PACKAGESPAT/$PACKAGESPAT/i" > ./nuget.ci.build.config \
    && dotnet restore ./MyProject.sln --configfile nuget.ci.build.config \
    && dotnet publish ./MyProject.sln -c Release -o ./obj/Docker/publish
eval "rm -f ./nuget.ci.build.config; exit $?"

The idea is that you would set the environment variables, then invoke the docker compose to make the build happen inside the docker container, mapping the source folder into the container. As a quick note, the build will happen as the root user, so your file ownership may be root at the end.

I find this type of work around unsuitable and really hope that Microsoft adds a wrap that allows us to just pass in the username/password for each nuget source as part of the command line.

Hello @TheRealPiotrP ,

Would you happen to know if this is on the team's radar? I see that there is a spec for a cross-platform credentials plugin but I don't see it being developed for generic uses, only for Azure pipelines: https://github.com/NuGet/Home/wiki/NuGet-Cross-Plat-Credential-Plugin

In any case, Is this something that I can attempt to develop and open a PR for or does the NuGet team have other plans (e.g. the credential plugin)?

Thanks!

We'd love to see this feature added so we can streamline the process of setting up and using an Azure Artifacts private NuGet feed.

Hello @TheRealPiotrP ,

Would you happen to know if this is on the team's radar? I see that there is a spec for a cross-platform credentials plugin but I don't see it being developed for generic uses, only for Azure pipelines: https://github.com/NuGet/Home/wiki/NuGet-Cross-Plat-Credential-Plugin

In any case, Is this something that I can attempt to develop and open a PR for or does the NuGet team have other plans (e.g. the credential plugin)?

Thanks!

Agreed - if it's not on the radar, I could help out on this as well. As my team moves more and more to cross-platform .NET Core it would be great to have it.

We need to support this, else GitHub Package Registry cannot use it.

@clarkbw FYI that this will make it easier to configure dotnet to use GPR.

note, since these earlier discussions, the ADO (azure dev ops) team has shipped an artifacts credential provider: https://github.com/Microsoft/artifacts-credprovider

That said, we do want to move an implementation of nuget sources to dotnet.exe.

here is the help output from "nuget sources -help"
I'm assuming the need is for somthing like this:

usage: dotnet.exe NuGet sources -Name [name] -Source [source]

Provides the ability to manage list of sources located in %AppData%\NuGet\NuGet.config

options:

-Name Name of the source.
-Source (src) Path to the package(s) source.
-Username UserName to be used when connecting to an authenticated source.
-Password Password to be used when connecting to an authenticated source.
-StorePasswordInClearText Enables storing portable package source credentials by disabling password encryption.
-ValidAuthenticationTypes Comma-separated list of valid authentication types for this source. By default, all authentication types are valid. Example: basic,negotiate
-Format Applies to the list action. Accepts two values: Detailed (the default) and Short
.
-Help (?) help
-Verbosity Display this amount of details in the output: normal, quiet, detailed.
-NonInteractive Do not prompt for user input or confirmations.
-ConfigFile The NuGet configuration file. If specified, only the settings from this file will be used. If not specified, the hierarchy of configuration files from the current directory will be used.

To learn more about NuGet configuration go to https://docs.microsoft.com/en-us/nuget/consume-packages/configuring-nuget-behavior.

-ForceEnglishOutput Forces the application to run using an invariant, English-based culture.

For more information, visit https://docs.nuget.org/docs/reference/command-line-reference

@rrelyea I guess the idea is to also not leak the token and still be able to use it i.e. support encrypting the password without the need for -StorePasswordInClearText

@infin8x, how long is the validity of GITHUB_TOKEN? Is there a new token created on every use?

@anangaur yep, it expires shortly after the run ends.

ah ok, so this whole thing is really just an ask for encrypted passwords in nuget.config via dotnet.exe?
(that is tricky...last time we talked to corefx about that one, they didn't have an answer for us that works cross platform.)

this issue is confusing...cause the title asks for the command. and during the thread, somebody says having a cross platform credential provider would solve it too.

1) we have delivered the artifacts credential provider -- works xplat.
2) we have not delivered a dotnet nuget sources command
3) when we do deliver dotnet nuget sources-- adding credentials in non-clear text will be extra hard, i believe.

are all these requests just asking us for 3?

dotnet nuget sources would make it easier for GitHub Package Registry to provide good configuration experiences for using NuGet packages in absence of a credential provider. I don't think it matters particularly to us if the token is encrypted or not - I assume it would be on Windows but not on Mac and Linux unless the dotnet team has solved the cryptography problem.

I agree. Not necessary or urgent but encryption will be great to have for dev machine scenarios. Not so much for Actions as they run temporarily and the GITHUB_TOKEN anyway expires after use.

/cc: @zivkan

Yeah, and encryption is important to enterprise security types but there seems to be a strong culture on Mac and Linux of putting tokens in the home directory and using file system permissions to keep them limited access. Not my area of expertise, just an observation.

As a temporary workaround, here's a basic powershell script that can be used with Powershell Core anywhere that the dotnet cli runs:

[CmdletBinding()]
param (
    [Parameter(Mandatory = $true)][string]$ConfigFile,
    [Parameter(Mandatory = $true)][string]$Source,
    [Parameter(Mandatory = $true)][string]$Username,
    [Parameter(Mandatory = $true)][string]$Password
)
$doc = New-Object System.Xml.XmlDocument
$filename = (Get-Item $ConfigFile).FullName
$doc.Load($filename)

$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
if ($creds -eq $null)
{
    $creds = $doc.CreateElement("packageSourceCredentials")
    $doc.DocumentElement.AppendChild($creds) | Out-Null
}

$sourceElement = $creds.SelectSingleNode($Source)
if ($sourceElement -eq $null)
{
    $sourceElement = $doc.CreateElement($Source)
    $creds.AppendChild($sourceElement) | Out-Null
}

$usernameElement = $sourceElement.SelectSingleNode("add[@key='Username']")
if ($usernameElement -eq $null)
{
    $usernameElement = $doc.CreateElement("add")
    $usernameElement.SetAttribute("key", "Username")
    $sourceElement.AppendChild($usernameElement) | Out-Null
}
$usernameElement.SetAttribute("value", $Username)

$passwordElement = $sourceElement.SelectSingleNode("add[@key='ClearTextPassword']")
if ($passwordElement -eq $null)
{
    $passwordElement = $doc.CreateElement("add")
    $passwordElement.SetAttribute("key", "ClearTextPassword")
    $sourceElement.AppendChild($passwordElement) | Out-Null
}
$passwordElement.SetAttribute("value", $Password)

$doc.Save($filename)

I used it in a GitHub Actions workflow with the following YAML:

    - name: Set NuGet creds
      shell: pwsh
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: ./Set-NuGetCredentials -ConfigFile ./nuget.config -Source gpr-test -Username zivkan -Password $env:GITHUB_TOKEN

Great work @rrelyea! 馃憤 Any ETA for when the fix will be released so we can start using it? Can't wait to throw out my bodges from my pwsh-scripts 馃榿

This is great news

@OskarKlintrot -This should ship during the NuGet 5.5 wave.

We hope to insert a build that contains this into VS 16.5p3 daily builds today.
Next, we create a PR that inserts this into SDK/CLI... dotnet SDK 3.1.200.
If all goes well, 3.1.200-preview that ships with VS 16.5 preview 3 will be the first build that will be available externally.

When there is a nuget.config file in the current folder, I'd like all read/write operations to use that file instead of %APPDATA%\NuGet\NuGet.config without using the explicit -c switch.

@rido-min , I think that is the current behavior except when it comes to persisting creds which is machine/user leve nuget.config. @rrelyea ?

Was this page helpful?
0 / 5 - 0 ratings