This is essentially a duplicate of closed issue 3663 which was marked as closed because while it failed in PowerShell 5.1 as the original poster commented, @SteveL-MSFT, indicated this works in PowerShell 6. I can not get it to work in 6.0.4.
I'm unclear as to why the required modules have to be installed locally before publishing. As part of the publishing process, a check is performed to ensure that the required modules are available on the repo. If the required modules are not available on the repo, the publishing of the module fails. If the required modules are found on the repo, the publishing of the module will succeed. With that workflow, why require them to be installed locally?
New-ModuleManifest m.psd1 -RequiredModules sub
Test-ModuleManifest m.psd1 -verbose
I'd expect it to return details on the module being tested. For example:
Test-ModuleManifest m.psd1 -Verbose
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 0.0.1 m
I get an error
Test-ModuleManifest m.psd1 -Verbose
Test-ModuleManifest : The specified RequiredModules entry 'sub' in the module manifest 'C:\Inbox\m.psd1' is invalid. Try again after updating this entry with valid values.
At line:1 char:1
+ Test-ModuleManifest m.psd1 -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (m.psd1:String) [Test-ModuleManifest], DirectoryNotFoundException
+ FullyQualifiedErrorId : Modules_InvalidRequiredModulesinModuleManifest,Microsoft.PowerShell.Commands.TestModuleManifestCommand
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 0.0.1 m
This happens in version 6.0.4 on both Windows and Ubunutu
Windows
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.4
PSEdition Core
GitCommitId v6.0.4
OS Microsoft Windows 10.0.14393
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Ubuntu
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.4
PSEdition Core
GitCommitId v6.0.4
OS Linux 4.4.0-28-generic #47-Ubuntu SMP Fri Jun...
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
To get around this limitation, we read in the data file information, create an array of the required modules and install each of them.
# Get .psd1 data
$data = Import-PowerShellDataFile .\*.psd1
# Get the RequiredModules
$requiredModules = $data.RequiredModules.ModuleName
if ($requiredModules) {
# Create credentials used to connect to private NuGet feed
Write-Output 'Creating credentials'
$pwd = ConvertTo-SecureString $NuGetApiKey -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ("username", $pwd)
# Install the required modules
foreach ($module in $requiredModules) {
Install-Module $module -Repository $repo -Credential $cred -Verbose
}
}
While this works, it adds additional, unneeded overhead.
Another quick follow up, when installing the required modules, you'll notice that I don't specify a version I always just grab the latest. The locally installed version of the required modules does NOT have to match the version specified in the required modules section of the .psd1.
If the workflow is going to force you to have the required modules installed locally, it should additionally ensure it's the correct version.
@cholmes1111:
Good point about not enforcing the version; that bug has already been reported: #7495
That same report, created by @rjmholt, also suggests the following enhancement, which addresses your main issue:
Provide an option to only check the validity of the manifest itself, and not whether it will work in the current session (this last point I think is part of the need to separate "Module manifests that are not well-formed" from "Module manifests that cannot be loaded in the current session"
Note that this means that the default behavior would remain as-is (except for the need to fix the version bug), and that performing a test for mere well-formation would be _opt-in_.
In the meantime, you can use the stopgap demonstrated in this SO answer.
@mklement0 - Thanks for the feedback! I didn't see the previously reported bug 7495 . I agree with @rjmholt on all of his points:
If Test-ModuleManifest is updated to have an opt-in, would Publish-Module be updated to check the manifests with that opt-in? I only encountered this issue when attempting to Publish-Module.
Thanks for the link to the stopgap as well. I'll give it a try and update my process accordingly if I can validate it works.
If you're like me and you've come across this page while searching for a solution to publishing modules from a container (Bitbucket/Azure DevOps) I have a very simple work around to this issue.
The problem is that Publish-Module runs Test-ModuleManifest which expects any requiredModules (which will include Externally Required modules) to be installed on the local file system. This is especially challenging when your module depends on modules from multiple external repos.
The thing is that Test-ModuleManifest just looks for the existence of the .psd1 file and doesn't care about the contents. I was able to work around this by simply identifying the location where modules are installed by default and then creating the module directory and an empty .psd1 file like this:
Function Build-RequiredModuleFiles {
# Get .psd1 data
$Data = Import-PowerShellDataFile .\*.psd1
# Get the RequiredModules
[array]$RequiredModules = $data.RequiredModules
If ($RequiredModules) {
Set-Location '/root/.local/share/powershell/Modules'
# Create the required module manifests
ForEach ($module in $requiredModules) {
$moduleName = $module.ModuleName
New-Item $moduleName -type Directory
Write-Output "Creating empty .psd1 file for module $modulename at $((Get-Location).Path)\$moduleName\$moduleName.psd1"
# Create manifest
New-Item ".\$moduleName\$moduleName.psd1"
}
}
}
I think it makes no sense to create a module manifest if it can not be used or tested locally. Don't add RequiredModules if you have to ignore it on next step.
Most helpful comment
@mklement0 - Thanks for the feedback! I didn't see the previously reported bug 7495 . I agree with @rjmholt on all of his points:
If Test-ModuleManifest is updated to have an opt-in, would Publish-Module be updated to check the manifests with that opt-in? I only encountered this issue when attempting to Publish-Module.
Thanks for the link to the stopgap as well. I'll give it a try and update my process accordingly if I can validate it works.