diff --git a/CHANGELOG.md b/CHANGELOG.md index 8054d5a..111d623 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- For any bug fix. +- Fixed offline repository descriptors serializing `PrivateData.PSData` as the + string `System.Collections.Hashtable` when packaging a prerelease module. ### Security diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index 863732b..e191995 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -16,6 +16,7 @@ PSScriptAnalyzer = 'latest' Pester = 'latest' ModuleBuilder = 'latest' + Metadata = 'latest' ChangelogManagement = 'latest' Sampler = 'latest' 'Sampler.GitHubTasks' = 'latest' diff --git a/source/Private/New-UniversalAutomationRepositoryManifest.ps1 b/source/Private/New-UniversalAutomationRepositoryManifest.ps1 index e7c7d1b..ecf7229 100644 --- a/source/Private/New-UniversalAutomationRepositoryManifest.ps1 +++ b/source/Private/New-UniversalAutomationRepositoryManifest.ps1 @@ -48,11 +48,10 @@ function New-UniversalAutomationRepositoryManifest '' } - $manifestParameters = @{ - Path = $Path + $manifestData = [ordered] @{ RootModule = $Module.Name ModuleVersion = $versionPart - Guid = (New-Guid) + GUID = (New-Guid).ToString() Author = $Module.Author CompanyName = $Module.CompanyName Copyright = $Module.Copyright @@ -65,11 +64,7 @@ function New-UniversalAutomationRepositoryManifest if (-not [System.String]::IsNullOrWhiteSpace($prereleasePart)) { - # Use PrivateData.PSData.Prerelease instead of the -Prerelease parameter because - # New-ModuleManifest only gained -Prerelease in PowerShell 6.0. PrivateData works - # identically on Windows PowerShell 5.1 and PowerShell 7, and is the same location - # PowerShellGet/PSResourceGet store the prerelease tag in the resulting manifest. - $manifestParameters['PrivateData'] = @{ + $manifestData['PrivateData'] = @{ PSData = @{ Prerelease = $prereleasePart } @@ -78,6 +73,12 @@ function New-UniversalAutomationRepositoryManifest if ($PSCmdlet.ShouldProcess($Path, 'Create PowerShell Universal repository manifest')) { - New-ModuleManifest @manifestParameters + $exportMetadataParameters = @{ + Path = $Path + InputObject = $manifestData + AsHashtable = $true + } + + Export-Metadata @exportMetadataParameters } } diff --git a/source/Sampler.PowerShellUniversalTasks.psd1 b/source/Sampler.PowerShellUniversalTasks.psd1 index 03b97a4..1fab90f 100644 --- a/source/Sampler.PowerShellUniversalTasks.psd1 +++ b/source/Sampler.PowerShellUniversalTasks.psd1 @@ -51,7 +51,9 @@ PowerShellVersion = '5.0' # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module -RequiredModules = @() +RequiredModules = @( + 'Metadata' +) # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() @@ -137,4 +139,3 @@ PrivateData = @{ - diff --git a/tests/Unit/Private/New-UniversalAutomationRepositoryManifest.Tests.ps1 b/tests/Unit/Private/New-UniversalAutomationRepositoryManifest.Tests.ps1 index 6f5918b..d7a7d79 100644 --- a/tests/Unit/Private/New-UniversalAutomationRepositoryManifest.Tests.ps1 +++ b/tests/Unit/Private/New-UniversalAutomationRepositoryManifest.Tests.ps1 @@ -25,31 +25,36 @@ AfterAll { } Describe 'New-UniversalAutomationRepositoryManifest' { - BeforeAll { - Mock -CommandName New-ModuleManifest - } - It 'Should create the repository descriptor for the module' { + $manifestPath = Join-Path -Path $TestDrive -ChildPath 'MyModule.psd1' + InModuleScope -ScriptBlock { $module = New-Module -Name 'MyModule' -ScriptBlock { } New-UniversalAutomationRepositoryManifest -Path $ManifestPath -Module $module -ModuleVersion '1.2.3-preview1' -Confirm:$false - } -Parameters @{ ManifestPath = (Join-Path -Path $TestDrive -ChildPath 'MyModule.psd1') } - - Should -Invoke -CommandName New-ModuleManifest -Exactly -Times 1 -Scope It -ParameterFilter { - $RootModule -eq 'MyModule' -and $ModuleVersion -eq '1.2.3' -and $PrivateData.PSData.Prerelease -eq 'preview1' - } + } -Parameters @{ ManifestPath = $manifestPath } + + $manifest = Import-PowerShellDataFile -Path $manifestPath + $manifest.RootModule | Should -Be 'MyModule' + $manifest.ModuleVersion.ToString() | Should -Be '1.2.3' + $manifest.PrivateData | Should -BeOfType [System.Collections.Hashtable] + $manifest.PrivateData.PSData | Should -BeOfType [System.Collections.Hashtable] + $manifest.PrivateData.PSData.Prerelease | Should -Be 'preview1' + Get-Content -Path $manifestPath -Raw | Should -Not -Match "PSData\s*=\s*'System.Collections.Hashtable'" } It 'Should create the repository descriptor without a prerelease tag when the version has none' { + $manifestPath = Join-Path -Path $TestDrive -ChildPath 'MyModule.psd1' + InModuleScope -ScriptBlock { $module = New-Module -Name 'MyModule' -ScriptBlock { } New-UniversalAutomationRepositoryManifest -Path $ManifestPath -Module $module -ModuleVersion '1.2.3' -Confirm:$false - } -Parameters @{ ManifestPath = (Join-Path -Path $TestDrive -ChildPath 'MyModule.psd1') } + } -Parameters @{ ManifestPath = $manifestPath } - Should -Invoke -CommandName New-ModuleManifest -Exactly -Times 1 -Scope It -ParameterFilter { - $RootModule -eq 'MyModule' -and $ModuleVersion -eq '1.2.3' -and -not $PrivateData - } + $manifest = Import-PowerShellDataFile -Path $manifestPath + $manifest.RootModule | Should -Be 'MyModule' + $manifest.ModuleVersion.ToString() | Should -Be '1.2.3' + $manifest.ContainsKey('PrivateData') | Should -BeFalse } }