Search code examples
powershellautorestpowershellget

How to publish .nupkg to Powershell Gallery?


Solution

Credit to mklement0

Here's what I ended up doing to publish my bin\MyModule.0.1.0.nupkg module to PSGallery:

  1. Rename bin\MyModule.0.1.0.nupkg to bin\MyModule.0.1.0.zip
  2. Extract bin\MyModule.0.1.0.zip to bin\MyModule\ (the name of the extracted folder had to match the name of the .psd1 file inside, so in my case there was now a bin\MyModule\MyModule.psd1 file).
  3. Delete the [Content_Types].xml file from inside the extracted folder (not deleting this causes an error when you try to download and install the module from PSGallery, seemingly caused by 2 copies of that file being present in the resulting .nupkg).

Then I was able to run this command:

PS> Publish-Module -NuGetApiKey xxx -Path .\bin\MyModule

And it worked! My module is now published to PSGallery.

Original Post

I have a Powershell module generated and packaged as a .nupkg file by Autorest.Powershell. I now want to publish my module to the Powershell Gallery, but can't figure out how to get it to work. I have tried:

PS> Publish-Module -NuGetApiKey xxx -Path .\bin\MyModule.0.1.0.nupkg
Publish-Module: The specified path '.\bin\MyModule.0.1.0.nupkg' is not a valid directory.

PS> Publish-Module -NuGetApiKey xxx -Path .\bin\
Publish-Module: The specified module with path '.\bin' was not published because no valid module was found with that path.

PS> Publish-Module -NuGetApiKey xxx -Name .\bin\MyModule.0.1.0.nupkg
Get-Module: C:\Users\bport\Documents\PowerShell\Modules\PowerShellGet\2.2.5\PSModule.psm1:10630
 Line |
10630 |  …   $module = Microsoft.PowerShell.Core\Get-Module -ListAvailable -Name …
      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      | The specified module 'D:\workarea\bin\MyModule.0.1.0.nupkg'
      | was not found. Update the Name parameter to point to a valid path, and then try again.

Publish-Module: The specified module '.\bin\MyModule.0.1.0.nupkg' was not published because no module with that name was found in any module directory.

PS> dotnet nuget push .\bin\MyModule.0.1.0.nupkg --api-key xxx --source https://www.powershellgallery.com/api/v2
Pushing MyModule.0.1.0.nupkg to 'https://www.powershellgallery.com/api/v2'...
  PUT https://www.powershellgallery.com/api/v2/
  MethodNotAllowed https://www.powershellgallery.com/api/v2/ 580ms
error: Response status code does not indicate success: 405 (Method Not Allowed).

Publishing .nupkg files to Powershell Gallery should be possible because you're able to download packages from Powershell Gallery as .nupkg files. Additionally, the Autorest documentation says this about its generated nupkg files:

The structure of the .nupkg is created so it can be loaded part of a PSRepository. Additionally, this package is in a format for distribution to the PSGallery.

I'm guessing this is possible, but I just can't figure out how to do it. Any help would be appreciated


Solution

  • As of version 2.2.5 of the PowerShellGet module - the one that comes with preview versions of PowerShell 7.2 - the Publish-Module cmdlet for publishing PowerShell modules to the PowerShell Gallery does not support uploading .nupkg files.

    Instead, it requires a (non-compressed) directory containing the PowerShell module to publish[1], which is then compressed into a (temporary) NuGet package (.nupkg archive) behind the scenes and uploaded to the gallery.

    I'm not familiar with AutoRest.PowerShell, but if it claims that the .nupkg archives it creates are compatible with the PowerShell Gallery you can try to extract (uncompress) such an archive (NuGet files are ZIP archives, so you can pass them to Expand-Archive) into a directory and try to pass that directory's path to Publish-Module's -Path parameter (choose the directory that contains the module manifest file (.psd1), which may be a subfolder).


    [1] If the module to publish is located in one of the directories listed in $env:PSModulePath, its directory location can be inferred from the module's name, passed to the -Name parameter.