How to publish a .net core console application to a (private) nuget repository and install it with chocolatey?
Asked Answered
J

1

6

There is a lot of comprehensive and verbose documentation about dotnet.exe nuget.exe and chocolatey but I failed to find a simple and concise tutorial about one common need: to push a .NET Core console application to a private Nuget repository and install it with Chocolatey. Here comes one.

Jealous answered 16/2, 2019 at 20:56 Comment(0)
J
4
  1. Define environment variables to make it easier to pass the values around (replace with the actual ones):
$version = "1.2.3"
$apiKey = "1234123412341234"
$repository = "https://your.repository.manager:8081/repository/repo-name/"
  1. Build and publish your application. This will create the DLLs (and other project items) to something like <path to your project>\bin\Release\netcoreapp2.2\publish.
dotnet publish -c Release /p:version=$version
  1. Create the nuspec file (replace the values in square brackets):
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata>
    <id>[your package id]</id>
    <version>$version$</version>
    <title>[your package title]</title>
    <authors>[author(s)]</authors>
    <owners>[owner(s)]</owners>
    <projectUrl>[project url e.g. containing documentation]</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>[description]</description>
    <copyright>[copyright]</copyright>
  </metadata>
  <files>
    <file src="chocolateyinstall.ps1" target="tools" />
    <file src="chocolateyuninstall.ps1" target="tools" />
    <file src="[path to the publish directory from step 2]\**" target="tools" />
  </files>
</package>
  1. Create the installation files. These will be used by Chocolatey to install and uninstall your application. First, chocolateyinstall.ps1:
$ErrorActionPreference = 'Stop'

$toolsDir   = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$defaultDotnetRuntimePath = "C:\Program Files\dotnet\dotnet.exe"

if (!(Test-Path $defaultDotnetRuntimePath))
{
    Write-Host -ForegroundColor Red "File not found: $defaultDotnetRuntimePath"
    Write-Host "The package depends on the .NET Core Runtime (dotnet.exe) which was not found."
    Write-Host "Please install the latest version of the .NET Core Runtime to use this package."
    exit 1
}

Install-Binfile -Name [executable name, e.g. my-tool] -Path "$defaultDotnetRuntimePath" -Command "$toolsDir\[name of your main dll, e.g. My.Awesome.Cli.Program.dll]"

and then chocolateyuninstall.ps1:

$ErrorActionPreference = 'Stop'

Uninstall-BinFile [executable name, e.g. my-tool]
  1. Create the nuget package:
choco pack "[path to your nuspec file created in step 3]" --version $version
  1. Push your package to the repository:
choco push "[path to the nuget package created in step 5]" -k $apiKey -s $repository

*add --force if your private nuget repo is not behind https

  1. Install (or upgrade) your program with Chocolatey:
choco upgrade [your package id] -y -s $repository

It's ready now! You can run it with the executable name defined in the chocolateyinstall.ps1 file, e.g. my-tool --version.

Jealous answered 16/2, 2019 at 20:56 Comment(6)
Is there is a reason you are doing NuGet pack and push? Rather than using the choco commands?Rudder
No other reason but that's what I usually use for nuget stuff. But that's a good point - installing nuget is not necessary because choco can handle those too. I'll update the example.Jealous
Further than that... if you use choco new to scaffold our the Chocolatey package, NuGet won’t actually be able to do the pack as out of the box, the nuspec file contains additional attributes that NuGet doesn’t know about.Rudder
Also, thinking about it... your nuspec file should have a dependency on the dotnet core runtime. That way, if it isn’t there, it will be installed and your package will work. Hard coding to the location to it probably isn’t ideal either.Rudder
I'm not sure if that's a good idea. The .NET Core Runtime installation and upgrades might be handled by other tools (e.g. Visual Studio) and in such case the package will probably fail to install because of the dependency. Also because of using a private source, the dotnetcore-runtime package would need to be present in that source too. It's just getting too complicated. I'll add a check for the dotnet.exe though so the user will know what's wrong if installation fails because of missing runtime.Jealous
This is great, but I wonder if it was written before self-contained and single file publish options were available? Being able to deploy a self contained application without relying on dotnet being installed, or a particular framework version, is surely even better. We'll have a go and modifying these steps for that scenario. Example command line: dotnet publish --self-contained true --runtime win-x64 -p:PublishSingleFile=trueTuna

© 2022 - 2024 — McMap. All rights reserved.