NuGet 6 not available on Azure Pipeline - nuget

I try to update my pipeline from NET 5 to NET 6. It immediately bombed out at nuget restore saying that the used version does not support NET 6. When going to advanced settings for the NuGet tool installer therer is an i icon showing all available versions (links to https://dist.nuget.org/tools.json). That link shows 6.0.0-preview.3. If I set this and run the pipeline I get an error that latest version is 5.11.
I did add a task BEFORE to install net SDK 6 which succeeds (Successfully installed .NET Core sdk version 6.0.100-preview.3.21202.5.
Creating global tool path and pre-pending to PATH.)
So why can't it find the nuget 6 ?

Azure DevOps Pipeline's NuGetCommand task is a wrapper of nuget.exe. However, I don't recommend using nuget.exe restore to restore your projects. I bet you don't use it locally, so why not use the same tools on CI as you use for local builds.
If you build with dotnet build, then I suggest you use dotnet restore. If you build with msbuild, then I suggest you restore with msbuild -t:restore. Therefore, your pipeline should use the DotnetCoreCLI task, or MSBuild pipeline task.

Try updating the vm image defined in the yml file.
I was getting error with windows latest but allowed for nuget restore and project/solution builds.
pool:
vmImage: 'windows-2022'

This seems to be an expected behavior.
Following line filters out releases with "EarlyAccessPreview" tag.
let releasedVersions: INuGetVersionInfo[] = nugetVersions.filter(x => x.stage.toString() !== NuGetReleaseStage[NuGetReleaseStage.EarlyAccessPreview]);
Not sure if there is any possible side effect when letting user to install preview release of nuget.exe. So the task decides to download the stable released version.
For a workaround:
You could use the powershell to download the Nuget 6.0.0- preview3.
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Source file location
$source = 'https://dist.nuget.org/win-x86-commandline/v6.0.0-preview3/nuget.exe'
# Destination to save the file
$destination = '$(Agent.TempDirectory)\nuget.exe'
#Download the file
Invoke-WebRequest -Uri $source -OutFile $destination
For more info, you could refer to this ticket: NuGetToolInstallerV1 cannot download preview releases

Related

How to publish .snupkg Source Link package to MyGet using DevOps build pipeline

My build creates Source Link packages, in the form of .snupkg files, and I'd like to push those packages to MyGet. From what I understand, tools such as Rider and Visual Studio can then download the symbols automatically. I can get this nuget push command working from my local machine, but I cannot figure out how to push those symbols using a DevOps build task. Here's my YAML:
- task: NuGetCommand#2
displayName: 'Publish Symbols ($(Build_Major).$(Build_Minor).$(Build_Patch))'
condition: succeeded()
inputs:
command: 'push'
packagesToPush: 'projects/${{ parameters.projectName }}/src/**/bin/**/*.$(Build_Major).$(Build_Minor)*.snupkg'
nuGetFeedType: 'external'
publishFeedCredentials: 'MyGet - Test'
I'm absolutely sure that MyGet - Test is correct, since I'm using the exact URL and API key that the MyGet web UI tells me to use for publishing symbols, as well as the same ones I have working locally. However, in the build logs I get:
C:\hostedtoolcache\windows\NuGet\6.4.0\x64\nuget.exe sources Add -NonInteractive -Name redacted_source -Source https://company.myget.org/F/myfeed/api/v3/index.json -ConfigFile D:\a\1\Nuget\tempNuGet_311668.config
Package source with Name: redacted_source added successfully.
Using authentication information for the following URI: https://company.myget.org/F/myfeed/api/v3/index.json
C:\hostedtoolcache\windows\NuGet\6.4.0\x64\nuget.exe setapikey *** -NonInteractive -Source redacted_source -ConfigFile D:\a\1\Nuget\tempNuGet_311668.config
The API Key '***' was saved for 'https://company.myget.org/F/myfeed/api/v3/index.json'.
C:\hostedtoolcache\windows\NuGet\6.4.0\x64\nuget.exe push D:\a\1\s\src\myproject\bin\Release\MyProject.1.10.24-beta.snupkg -NonInteractive -Source https://company.myget.org/F/myfeed/api/v3/index.json -ApiKey *** -ConfigFile D:\a\1\Nuget\tempNuGet_311668.config -Verbosity Detailed
Unable to load the service index for source https://company.myget.org/F/myfeed/api/v3/index.json.
NuGet Version: 6.4.0.123
Response status code does not indicate success: 401 (Unauthorized).
This does work a bit different than how I can successfully do this from the command line, which is:
nuget push .\MyProject.1.10.100-mike-beta.nupkg b848309c-0000-0000-0000-a893d8fc5d56 -Source https://company.myget.org/F/myfeed/api/v3/index.json
However, I'm not quite sure how to get the NuGetCommand task to behave like that. It seems like both should work anyway. Any ideas?
I figured this out! Though, the solution is kinda stupid. You must use a pre-authenticated URL to push packages or symbols using the v3 API:
Authentication seems to work fine using the v2 API, but the v2 API doesn't let you push symbols. I'm not sure if this is a limitation of MyGet or the DevOps NuGet task or what. However, since the pre-authenticated URL can still live as a secret in the service connection, it's a fairly easy and secure workaround.
I'll leave this question open in case anyone has more insight or a better solution.
You can first create a service connection credential for the feed.
Then add NuGet authenticate task before NuGetCommand#2 task in the pipeline.
steps:
- task: NuGetAuthenticate#1
displayName: 'NuGet Authenticate'
inputs:
nuGetServiceConnections: feed
Please refer to the document Publish NuGet packages with Azure Pipelines.

Installing the Visual Studio 2015 toolkit (v140) on a Microsoft hosted Azure Devops Build Pipeline Agent

I have a legacy solution that we've moved into an Azure Devops git repo and I am trying to setup a build pipeline for it. The solution is a mixture of v141 (2017) and v140 (2015) projects, which on my local machine I can just build in Visual Studio 2017 as long as I've installed the v140 toolset.
Ideally, I'd like to use a Microsoft provided agent but it seems like the vs2017-win2016 image does not include the v140 toolset by default. As this is not something we are planning to build very often, I attempted to install the v140 toolset using the 2017 installer:
pool:
vmImage: 'vs2017-win2016'
steps:
- task: PowerShell#2
displayName: 'Install Visual Studio v140 Toolset'
inputs:
targetType: 'inline'
script: |
Write-Output "Starting the installation process. This will take some time"
$installProcess = Start-Process -FilePath $(Build.SourcesDirectory)/External/VisualStudioBuildTools/installer.exe -ArgumentList "--add Microsoft.VisualStudio.Component.VC.140", "--quiet", "--wait", "--norestart" -Wait -PassThru
Write-Output "Install Completed with code $($process.ExitCode)"
- task: VSBuild#1
displayName: 'Build Debug [.sln]'
inputs:
solution: '$(Build.SourcesDirectory)/LegacySolution.sln'
vsVersion: '15.0'
configuration: 'Debug'
platform: 'x64'
When I run this in Azure Devops, the install process exits with code 0 (success) after about a minute. However, when it then tries to build the solution it fails with:
##[error]C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\Microsoft.Cpp.Platform.targets(67,5): Error MSB8020: The build tools for v140 (Platform Toolset = 'v140') cannot be found. To build using the v140 build tools, please install v140 build tools. Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Retarget solution".
Has anyone tried this before with any luck? The only other thing I can think of is to try to check in a copy of the v140 toolset and play with adding it correctly to the path, but I can see this being a major pain to get right!
Installing the Visual Studio 2015 toolkit (v140) on a Microsoft hosted Azure Devops Build Pipeline Agent
In generally you can't. If something requires admin access and you're using the hosted agent, you can't do that thing. I have test this command line in my local, I need to run the powershell with Administrator, otherwise, I will get a confirmation prompt.
Besides, MS replied:
VS has grown to a point, where installing multiple versions on the
same agent is not feasible any longer for us. Also, we notice problems
in side-by-side VS installations for certain project types. For these
reasons, we have decided to keep a single tool set going forward. If
you need multiple versions, then you would have to setup custom
agents. We are sorry that we cannot meet all of our customers'
requirements using a common hosted agent image.
So, to resolve this issue, we have to setup our private agent.
Hope this helps.

How to use ClickOnce bootstrapper prerequisites on Azure DevOps build server?

We have a ClickOnce application which we're trying to get running with CI/CD on Azure DevOps.
Currently the ClickOnce Prerequisites are set to 'Download prerequisites from the same location as my application' which is the behaviour we want ideally (this app is installed on a Customer's server and the client PCs download the .NET framework and various custom bootstrappers from that server):
When VS builds on my local development PC it picks up those bootstrapper files (which includes some custom bootstrappers we've written) from the local machine and outputs them to the ClickOnce Publishing folder:
However, this doesn't work on Azure DevOps I get this error about not being able to find the .NET bootstrapper instead:
[error]C:\Program Files (x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(5390,5):
Error MSB3152: To enable 'Download prerequisites from the same
location as my application' in the Prerequisites dialog box, you must
download file 'DotNetFX462\NDP462-KB3151800-x86-x64-AllOS-ENU.exe' for
item 'Microsoft .NET Framework 4.6.2 (x86 and x64)' to your local
machine. For more information, see
http://go.microsoft.com/fwlink/?LinkId=616018.
As you'd expect, if I untick .NET 4.6.2 as I prerequisite I no longer get an error about .NET, but weirdly I don't then get an error for our custom bootstrappers, even though those don't exist on Azure either. The difference there seems to be that those custom bootstrappers don't currently exist on my local PC either, so they are shown with yellow exclamation triangles on my local machine.
So, is the .NET bootstrapper definitely not in the Azure build server image that gets spun up, or is it perhaps just a different path?
Or failing that, is there any way to tell DevOps to ignore this issue and just carry on building the actual ClickOnce application files and complete the build? The bootstrappers are already installed on our customer's server, so I don't actually need Azure to bundle them in the output.
Although not the best solution, the following worked for me:
I created an artifacts feed
I used Azure Artifacts with Universal packages to post my bootstrap packages
In the pipeline I used the "Universal packages" task to download the packages in "$ (System.DefaultWorkingDirectory)\bootstrapper"
I added the argument "/p:GenerateBootstrapperSdkPath=$(System.DefaultWorkingDirectory)\bootstrapper" to msbuild
The biggest drawback with this is the space used.
To publish the packages you will need:
Azure CLI
Azure DevOps extension for the Azure CLI: Run "az extension add --name azure-devops" when you have Azure CLI installed
Prepare the packages
In addition to your packages you need to upload the "Engine" directory which is where the setup.bin file is located. In my case I took it from "C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper"
I copied the "Engine" and "Schemas" directories to a temporary directory and then executed:
az login
az artifacts universal publish ^
--organization https://dev.azure.com/<MY-ORGANIZATION>/ ^
--project = "<MY PROJECT>" ^
--scope project ^
--feed <MY-FEED> ^
--name clickonce ^
--version 16.0.28315 ^
--description "ClickOnce Bootstrapper" ^
--path "D:\temp\ClickOnce Bootstrapper"
In the parameters "name", "version" and "description" you can put what you want, the important thing is to identify the package.
If the feed you created is associated with the organization, the command should not include the parameters "project" or "scope", you can see an example on how to publish by clicking on the "Connect to feed" button in your artifacts feed.
Then I ran the same command for each package I require, for example:
az artifacts universal publish ^
--organization https://dev.azure.com/my-organization/ ^
--project = "my project" ^
--scope project ^
--feed my-feed ^
--name dotnet ^
--version 4.6.2 ^
--description "Microsoft .Net Framework 4.6.2" ^
--path "C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\Packages\DotNetFX462"
The pipeline
Before the compilation task add the download of the packages:
First download the engine, in the case of this example it would be the clickonce package 16.0.28315
- task: UniversalPackages#0
inputs:
command: 'download'
downloadDirectory: '$(System.DefaultWorkingDirectory)\bootstrapper'
feedsToUse: 'internal'
vstsFeed: '<MY FEED ID>'
vstsFeedPackage: '<MY PACKAGE ID>'
vstsPackageVersion: '16.0.28315'
Of course, with the wizard it is much easier, find the "Universal packages" task, select the "Download" command and fill in the rest of the parameters.
For your packages it is similar, just change the download path to "$(System.DefaultWorkingDirectory)\bootstrapper\Packages<PACKAGE NAME>"
The important thing at this point is that if you already have the packages published on a website, the "Package name" is the same name of the directory where the package is currently published, since the setup will try to download it from that path.
Lastly, my compilation task looks something like this:
- task: VSBuild#1
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
msbuildArgs: '/target:publish /p:GenerateBootstrapperSdkPath=$(System.DefaultWorkingDirectory)\bootstrapper'
Of course, this makes a lot more sense with your own packages. It works with the .Net Framework, but it will use some valuable MB. An alternative could be to create a script, in PowerShell for example, that downloads and installs the .Net Framework. Another option, if you have one available, is to copy the files from an FTP or fileserver, the latter applies to both the .Net Framework and its own packages, the only thing relevant is to redirect the Bootstrappers path with the parameter "GenerateBootstrapperSdkPath", about how packets get into that directory, you have several options.

Why are there no files in my release artifacts directory?

I created a .netcore 2.1 api project and set up Azure DevOps to deploy it to an On-Prem computer using the Windows Agent.
The folder agent_work\r1\a was created on the machine running the agent, however there are no files in it.
I can see that a build did occur and that there is an artifact in my release
What did I miss doing?
[Update]
I can see in the agent job, there is a section which is about downloading an artifact.
It has the error message
There is no build available or the source is not accessible. You can select all artifacts or specify the list of artifacts to be downloaded below.
[Update]
Looks like I need to add a task to the job that is in a stage of my release.
And that task needs to copy the files I want to deploy.
Now the problem is knowing how to specify the source folder.
The strange thing is that it allows me to select a location and then rejects the selected location
There is help that says that if I leave the source folder empty, that will indicate the root of the repo. If I do this the deploy does not error but no files are deployed.
[Update]
I can see in the Get Sources of the Build the message "YOu are in 'detached Head' state. Maybe this has something to do with the problem.
[Update]
In the build pipeline I have
[Update]
When I try to create a new build pipeline I get the following
I select the location to be Azure Repos and the Repository to be vste
then I the azure-pipelines.yml auto-generates as
# ASP.NET Core
# Build and test ASP.NET Core web applications targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://learn.microsoft.com/vsts/pipelines/languages/dotnet-core
pool:
vmImage: 'Ubuntu 16.04'
variables:
buildConfiguration: 'Release'
steps:
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
[Update]
Looks like I might need to select Use The Visual Designer
[Update]
From ollifant's comment I have found the Publish Artifact task.
Now to figure out how to populate it
[Update]
Uh Uh not looking great
I had not used the ASP NET Core (.NET framework) template when creating the agent job in the build template, so the project was not building correctly.
New build pipeline -> Use the visual designer -> Continue -> ASP.NET Core (.Net Framework)

Azure Pipelines Hosted Agent Can't Access DevOps project Feed

I have an Azure DevOps project (just one).
I have a Build Pipeline set to run in the "Hosted VS2017" Agent Pool. This Agent Pool appears to be in the [MyProject]\Build Administrators, Contributors, Project Administrators, and Release Administrators roles.
I also have an Artifacts nuget feed in the DevOps project. It has [MyProject]\Project Valid Users set as "Reader" role. It appears that Project Valid Users has all of the Agent Pool's roles mentioned above as members.
I have an azure-pipelines.yml script that adds that adds the artifacts feed as a nuget source right at the beginning:
# Add nuget source
- powershell: Invoke-RestMethod "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile "$env:UserProfile/nuget.exe"
- script: '%UserProfile%\nuget.exe sources Add -Name "devops" -Source "https://pkgs.dev.azure.com/MyProject/_packaging/feed/nuget/v3/index.json"'
The build yml then dot a dotnet build but fails inside NuGet.targets with:
Unable to load the service index for source https://pkgs.dev.azure.com/MyProject/_packaging/feed/nuget/v3/index.json.
Response status code does not indicate success: 401 (Unauthorized).
how can I make this work? My build needs packages from other builds that are on that artifacts feed...
There is a better alternative imo. You can continue using your script to dotnet restore.
Simply add a task just before that with NuGetAuthenticate#0
steps:
- task: NuGetAuthenticate#0
- script: dotnet restore --no-cache --force
this task will authenticate the pipeline with the nuget feeds that require so and are found at the NuGet.config file.
More info here
Notice that when the nuGet feed is within Azure DevOps there is nothing else required. If the feed is external you can configure at your Azure DevOps a nuGet Service Connections (at the link there is further info).
Use the built-in tasks for installing and running NuGet and you won't have authentication problems.
Use the dotnet task's restore command. If you're using a single Azure Artifacts feed, just select it from the dropdown in the task (instead of the PowerShell you mentioned). If multiple feeds (doesn't look like it from your question, but just in case), you'll need to check in a NuGet.config that references all of those feeds, then point the task to that config.
You may also need to pass the '--no-restore' flag to your 'dotnet build' command.
If you still encounter issues, ensure the correct build identity has access to your feed.