diff --git a/.github/actions/Build-PSModule/src/helpers/Build/Build-PSModuleManifest.ps1 b/.github/actions/Build-PSModule/src/helpers/Build/Build-PSModuleManifest.ps1 index fd564a61..8e37790f 100644 --- a/.github/actions/Build-PSModule/src/helpers/Build/Build-PSModuleManifest.ps1 +++ b/.github/actions/Build-PSModule/src/helpers/Build/Build-PSModuleManifest.ps1 @@ -260,7 +260,8 @@ Write-Host "Processing required module [$requiredModuleName]" $requiredVersion = $group.Group.RequiredVersion | ForEach-Object { [Version]$_ } | Sort-Object -Unique $minimumVersion = $group.Group.Version | ForEach-Object { [Version]$_ } | Sort-Object -Unique | Select-Object -Last 1 - $maximumVersion = $group.Group.MaximumVersion | ForEach-Object { [Version]$_ } | Sort-Object -Unique | Select-Object -First 1 + $maximumVersion = $group.Group.MaximumVersion | Sort-Object -Unique | Select-Object -First 1 + $maximumVersionBound = if ($maximumVersion -and ($maximumVersion -notmatch '[*]')) { [Version]$maximumVersion } else { $null } Write-Host "RequiredVersion: [$($requiredVersion -join ', ')]" Write-Host "ModuleVersion: [$minimumVersion]" Write-Host "MaximumVersion: [$maximumVersion]" @@ -274,17 +275,17 @@ } if (-not $maximumVersion) { - $maximumVersion = [Version]'9999.9999.9999' + $maximumVersionBound = [Version]'9999.9999.9999' } if ($requiredVersion -and ($minimumVersion -gt $requiredVersion)) { throw 'ModuleVersion is higher than RequiredVersion.' } - if ($minimumVersion -gt $maximumVersion) { + if ($maximumVersionBound -and ($minimumVersion -gt $maximumVersionBound)) { throw 'ModuleVersion is higher than MaximumVersion.' } - if ($requiredVersion -and ($requiredVersion -gt $maximumVersion)) { + if ($requiredVersion -and $maximumVersionBound -and ($requiredVersion -gt $maximumVersionBound)) { throw 'RequiredVersion is higher than MaximumVersion.' } @@ -294,7 +295,7 @@ ModuleName = $requiredModuleName RequiredVersion = $requiredVersion } - } elseif (($minimumVersion -ne [Version]'0.0.0') -or ($maximumVersion -ne [Version]'9999.9999.9999')) { + } elseif (($minimumVersion -ne [Version]'0.0.0') -or ($maximumVersionBound -ne [Version]'9999.9999.9999')) { Write-Host '[RequiredModules] - ModuleVersion/MaximumVersion' $uniqueModule = @{ ModuleName = $requiredModuleName @@ -302,7 +303,7 @@ if ($minimumVersion -ne [Version]'0.0.0') { $uniqueModule['ModuleVersion'] = $minimumVersion } - if ($maximumVersion -ne [Version]'9999.9999.9999') { + if ($maximumVersionBound -ne [Version]'9999.9999.9999') { $uniqueModule['MaximumVersion'] = $maximumVersion } } else { diff --git a/.github/actions/Install-PSModule/src/PSModule/PSModule.psm1 b/.github/actions/Install-PSModule/src/PSModule/PSModule.psm1 index 48b8fb85..555be40c 100644 --- a/.github/actions/Install-PSModule/src/PSModule/PSModule.psm1 +++ b/.github/actions/Install-PSModule/src/PSModule/PSModule.psm1 @@ -87,18 +87,40 @@ function Convert-VersionSpec { [string] $RequiredVersion ) + $maximumVersionIsWildcard = $MaximumVersion -and ($MaximumVersion -match '[*]') + if ($maximumVersionIsWildcard) { + $versionParts = @($MaximumVersion -split '\.') + $wildcardIndex = [Array]::IndexOf($versionParts, '*') + if ($wildcardIndex -lt 0) { + throw "MaximumVersion '$MaximumVersion' contains an unsupported wildcard pattern." + } + + if ($wildcardIndex -eq 0) { + throw "MaximumVersion '$MaximumVersion' contains an unsupported wildcard pattern." + } + + $upperBoundParts = @(0, 0, 0) + for ($i = 0; $i -lt $wildcardIndex; $i++) { + $upperBoundParts[$i] = [int]$versionParts[$i] + } + $upperBoundParts[$wildcardIndex - 1]++ + $MaximumVersion = $upperBoundParts -join '.' + } + if ($RequiredVersion) { # Use exact match in bracket notation. return "[$RequiredVersion]" } elseif ($MinimumVersion -and $MaximumVersion) { - # Both bounds provided; both are inclusive. - return "[$MinimumVersion,$MaximumVersion]" + # Wildcard maximum versions are translated to an exclusive upper bound. + $upperBound = $maximumVersionIsWildcard ? ')' : ']' + return "[$MinimumVersion,$MaximumVersion$upperBound" } elseif ($MinimumVersion) { # Only a minimum is provided. Use a minimum-inclusive range. return "[$MinimumVersion, ]" } elseif ($MaximumVersion) { - # Only a maximum is provided; lower bound open. - return "(, $MaximumVersion]" + # Only a maximum is provided; lower bound open. Wildcards are exclusive upper bounds. + $upperBound = $maximumVersionIsWildcard ? ')' : ']' + return "(, $MaximumVersion$upperBound" } else { return $null } diff --git a/tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 b/tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 index a48c08c2..d3c7ca04 100644 --- a/tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 +++ b/tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 @@ -1,6 +1,6 @@ #Requires -Modules Utilities #Requires -Modules @{ ModuleName = 'PSSemVer'; RequiredVersion = '1.1.4' } -#Requires -Modules @{ ModuleName = 'DynamicParams'; ModuleVersion = '1.1.8' } +#Requires -Modules @{ ModuleName = 'ThreadJob'; ModuleVersion = '1.0.0'; MaximumVersion = '1.*' } #Requires -Modules @{ ModuleName = 'Store'; ModuleVersion = '0.3.1' } function Get-PSModuleTest { diff --git a/tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 index 96eb02c1..4353eed8 100644 --- a/tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 +++ b/tests/srcWithManifestTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 @@ -1,6 +1,6 @@ #Requires -Modules Utilities #Requires -Modules @{ ModuleName = 'PSSemVer'; RequiredVersion = '1.1.4' } -#Requires -Modules @{ ModuleName = 'DynamicParams'; ModuleVersion = '1.1.8' } +#Requires -Modules @{ ModuleName = 'ThreadJob'; ModuleVersion = '1.0.0'; MaximumVersion = '1.*' } #Requires -Modules @{ ModuleName = 'Store'; ModuleVersion = '0.3.1' } function Get-PSModuleTest {