2
votes

My solution uses packages from both the official NuGet server as well as a private NuGet server. I am trying to configure my build pipeline to restore packages from both locations, but keep getting NuGet restore build errors where it looks like it is trying to restore my private package from the public NuGet server and understandably failing because of that.

I am at a bit of a loss as to what else I should do. It appears that there are no settings within Azure DevOps that can be made for the NuGet restore step as it looks like that is all configured within the YAML file now. Any suggestions on what I could be doing wrong or what else I could try would be appreciated.

My NuGet.config in my solution:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageRestore>
    <!-- Allow NuGet to download missing packages -->
    <add key="enabled" value="True" />
    <!-- Automatically check for missing packages during build in Visual Studio -->
    <add key="automatic" value="True" />
  </packageRestore>
  <packageSources>
    <add key="NuGet official package source" value="https://api.nuget.org/v3/index.json" />
    <add key="Private" value="http://privatenuget.net:8080/nuget" />
  </packageSources>
  <activePackageSource>
    <add key="All" value="(Aggregate source)" />
  </activePackageSource>
</configuration>

My YAML file that Pipelines is using:

# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4

pool:
  vmImage: 'VS2017-Win2016'

variables:
  solution: 'MyProject.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: NuGetToolInstaller@0

- task: NuGetCommand@2
  inputs:
    nugetConfigPath: 'MyProject\NuGet.config'
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

My error I get on the NuGetCommand step of the build:

The nuget command failed with exit code(1) and error(Errors in packages.config projects
    NU1000: Unable to find version '1.1.5' of package 'MyPackage'.
      https://api.nuget.org/v3/index.json: Package 'MyPackage' is not found on source 'https://api.nuget.org/v3/index.json'.)
Packages failed to restore
3

3 Answers

4
votes

You can start with an empty job and not use the existing YAML. Then u can set your agents/tasks(nuget restore etc) to build your application.

New build

Empty job

3
votes

Your YML file is not correct,you must add feedsToUse: config

- task: NuGetCommand@2
  displayName: 'Nuget Restore'
  inputs:
    restoreSolution: '$(solution)'
    feedsToUse: config
    nugetConfigPath: nuget.config
2
votes

I just ran into this issue, but didn't have a NuGet.config file in my project to use, and didn't want to add one. Using NuGet.config requires you to store the personal access token (PAT) in clear text, which is less than ideal, to say the least, especially if it's being committed to your repo along with your project.

After a lot of research, I came upon a near perfect solution. Using variable groups in Azure DevOps, you can add variables (and secrets) that can be made available to all your pipelines. It occurred to me, that I could put the entire NuGet.config into a secret there (along with the PAT), and then pipe that into an actual NuGet.config file as part of the pipeline.

You've already got a NuGet.config file, but in case anyone else lands on this and is starting from scratch, you need the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="MyPrivateFeed" value="*** PRIVATE FEED URL HERE ***" />
  </packageSources>
  <packageSourceCredentials>
    <MyPrivateFeed>
      <add key="Username" value="anything" />      
      <add key="ClearTextPassword" value="*** PAT HERE ***" />
    </MyPrivateFeed>
  </packageSourceCredentials>
</configuration>

Fill in your feed URL and PAT and then copy all of it and paste it into a variable named "NuGet.config" in a variable group. Click the lock icon on the variable to make it a secret. The variable can be named whatever you want, but you'll need to update it in the code below, if you use something different.

Then, you simply need to include your variable group:

variables:
  - group: my-variable-group

And add the following to your pipeline yaml, before any other steps that will be using the private feed (such as dotnet build).

- bash: echo -e '$(NuGet.config)' > NuGet.config
  displayName: Create NuGet.config