Your browser may have trouble rendering this page. See supported browsers for more information.

|<<>>|54 of 273 Show listMobile Mode

Installing a dotnet tool on Azure

Published by marco on

I have a .NET solution (Quino) that contains a project that I publish as a `dotnet` tool. The tool calculates a version number based on the branch and version number found in the solution. I use it from Quino itself and also from other project pipelines.

In order to use it from any pipeline (including Quino itself), I need to install it from the Quino artifact feed. The original solution is a couple of years old: I’d had a secure file for NuGet.Config that included the PAT. This works fine, until the PAT expires.

So, I went searching for a better solution and thought I’d try something a bit more resilient and better-supported. By now, I’m using YAML files for my pipeline, so I tried the DotNet task, but it doesn’t support installing tools.

There are open issues and even a very old open pull-request for supporting a Microsoft tool on Microsoft’s premiere hosting service that Microsoft has steadfastly ignored. There seem to be no plans for supporting dotnet tool install natively, with seamless authentication, as they’ve done for dotnet restore. The example below shows how this works for restore.

  − task: DotNetCoreCLI@2
    displayName: 'Restore Server Packages'
    inputs:
      command: 'restore'
      feedsToUse: 'select'
      feedRestore: 'Quino'
      projects: 'server/src/**/*.csproj'
      verbosityRestore: Normal
      includeNuGetOrg: true

I was hoping to follow this pattern to use the dotnet task to install a tool with something like the following:

  − task: DotNetCoreCLI@2
    displayName: 'Restore Server Packages'
    inputs:
      command: 'tool install'
      feedsToUse: 'select'
      feedRestore: 'Quino'
      includeNuGetOrg: true
      isGlobal: true
      toolName: quino

There is no support for this. The PR mentioned above would support it, but it’s never been accepted and Microsoft has not seen fit to add automatically authenticated feeds for anything other than restore.

Instead, I use two tasks: the first is a workaround for the lack of proper support in Azure for `dotnet tool install` from authenticated feeds; the second installs the tool. See dotnet tool install/update” not working with Azure Artifacts #10057 and Add dotnet tool install command to support tools location in Azure Artifact feeds #13401 (the PR) for more information.

I can copy/paste the two tasks below into all of the pipelines that need it. It’s a bit bulky and non-intuitive, but it is both project-agnostic and doesn’t include any passwords or PATs directly. Instead, it uses the $(System.AccessToken). If the project has been granted access to the feed identified by <INTERNALFEEDURL> using the standard feed permissions control panel, then it works.

  − task: NuGetCommand@2
    displayName: 'NuGet Add Credentials For Internal Feed'
    inputs:
      command: custom
      arguments: > 'sources add
        -Name "<INTERNALFEEDNAME>"
        -Source "<INTERNALFEEDURL>/nuget/v3/index.json"
        -Username "this_value_could_anything"
        -Password "$(System.AccessToken)"'
  − task: CmdLine@3
    displayName: Install tools
    inputs:
      targetType: inline
      script: dotnet tool install <TOOLNAME> –global

Where:

  • <INTERNALFEEDURL> is obtained from your Azure project
  • <INTERNALFEEDNAME> doesn’t matter, as long as it doesn’t conflict with any defaults
  • <TOOLNAME> is the name of the tool to execute

This is utterly unintuitive, but it works and it’s not too much hacking. I think it’s indisputable that it would be much nicer if “install tool” was an option for the “dotnet” command. It’s not like it’s an external tool. This is literally how Microsoft has asked us to work.

It would be nice if I hadn’t had to spend half an afternoon trying to figure out how to get a dotnet tool installed from a feed in the same project on Azure. I’m glad I got it working, but everyone who comes after will also waste time trying to figure this out—or will give up and use a gross hack instead.