diff --git a/resources/MyModule.psd1 b/resources/MyModule.psd1 new file mode 100644 index 0000000..295a414 --- /dev/null +++ b/resources/MyModule.psd1 @@ -0,0 +1,141 @@ +# +# Module manifest for module 'MyModule' +# +# Generated by: OCram85 +# +# Generated on: 27.07.2022 +# + +@{ + + # Script module or binary module file associated with this manifest. + # RootModule = '' + + # Version number of this module. + ModuleVersion = '0.0.1' + + # Supported PSEditions + # CompatiblePSEditions = @() + + # ID used to uniquely identify this module + GUID = '71364bab-5f39-4c93-a0f6-319d2b6cfc53' + + # Author of this module + Author = 'OCram85' + + # Company or vendor of this module + CompanyName = 'Unknown' + + # Copyright statement for this module + Copyright = '(c) OCram85. All rights reserved.' + + # Description of the functionality provided by this module + # Description = '' + + # Minimum version of the PowerShell engine required by this module + # PowerShellVersion = '' + + # Name of the PowerShell host required by this module + # PowerShellHostName = '' + + # Minimum version of the PowerShell host required by this module + # PowerShellHostVersion = '' + + # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. + # DotNetFrameworkVersion = '' + + # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. + # ClrVersion = '' + + # Processor architecture (None, X86, Amd64) required by this module + # ProcessorArchitecture = '' + + # Modules that must be imported into the global environment prior to importing this module + # RequiredModules = @() + + # Assemblies that must be loaded prior to importing this module + # RequiredAssemblies = @() + + # Script files (.ps1) that are run in the caller's environment prior to importing this module. + # ScriptsToProcess = @() + + # Type files (.ps1xml) to be loaded when importing this module + # TypesToProcess = @() + + # Format files (.ps1xml) to be loaded when importing this module + # FormatsToProcess = @() + + # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess + # NestedModules = @() + + # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. + FunctionsToExport = @() + + # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. + CmdletsToExport = @() + + # Variables to export from this module + VariablesToExport = '*' + + # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. + AliasesToExport = @() + + # DSC resources to export from this module + # DscResourcesToExport = @() + + # List of all modules packaged with this module + # ModuleList = @() + + # List of all files packaged with this module + # FileList = @() + + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + # Prerelease string of this module + # Prerelease = '' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false + + # External dependent modules of this module + ExternalModuleDependencies = @( + @{ + ModuleName = 'WinSCP' + ModuleVersion = '5.17.8.1' + }, + @{ + ModuleName = 'DataONTAP' + ModuleVersion = '9.7.1.1' + } + ) + + } # End of PSData hashtable + + } # End of PrivateData hashtable + + # HelpInfo URI of this module + # HelpInfoURI = '' + + # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. + # DefaultCommandPrefix = '' + +} + diff --git a/src/Build/Update-ModuleMeta.Tests.ps1 b/src/Build/Update-ModuleMeta.Tests.ps1 index 9140089..ad19e28 100644 --- a/src/Build/Update-ModuleMeta.Tests.ps1 +++ b/src/Build/Update-ModuleMeta.Tests.ps1 @@ -18,4 +18,29 @@ Describe 'Update-ModuleMeta' { $foo.Description[0].Text.Length | Should -BeGreaterThan 5 } } + + Context 'Unit Tests' -Tag 'Unit' { + It 'Update test module manifest' { + { + $Env:DRONE = $true + $Env:DRONE_BUILD_EVENT = 'tag' + $Env:DRONE_SEMVER = '9.9.9-dev9' + $Env:DRONE_SEMVER_SHORT = '9.9.9' + $Env:DRONE_SEMVER_PRERELEASE = 'dev9' + Update-ModuleMeta -Path './resources/MyModule.psd1' -Verbose + } | Should -Not -Throw + $data = Import-PowerShellDataFile -Path './resources/MyModule.psd1' + $data.ModuleVersion | Should -Be '9.9.9' + $data.PrivateData.PSData.Prerelease | Should -Be 'dev9' + } + + It 'Updated manifest is valid' { + { Test-ModuleManifest -Path './resources/MyModule.psd1' } | Should -Not -Throw + } + + It 'External dependencies prop is untouched' { + $d = Test-ModuleManifest -Path './resources/MyModule.psd1' + $d.PrivateData.PSData.ExternalModuleDependencies.Count | Should -Be '2' + } + } } diff --git a/src/Build/Update-ModuleMeta.ps1 b/src/Build/Update-ModuleMeta.ps1 index 124f342..b3edab9 100644 --- a/src/Build/Update-ModuleMeta.ps1 +++ b/src/Build/Update-ModuleMeta.ps1 @@ -27,11 +27,31 @@ function Update-ModuleMeta { '', Justification = 'system state does not change permanent in temp build clients.' )] - param () + param ( + [Parameter(Mandatory = $false)] + [ValidateScript( + { + if (Test-Path -Path $_) { + return $true + } + else { + throw 'Could not find file: {0}' -f $_ + } + } + )] + [ValidateNotNullOrEmpty()] + [string]$Path + ) process { - if ($Env:DRONE) { + if (!$Path) { $Repo = Get-RepoPath + $ManifestFilePath = $Repo.Src.Manifest.Item.FullName + } + else { + $ManifestFilePath = $Path + } + if ($Env:DRONE) { if ($Env:DRONE_BUILD_EVENT -eq 'tag') { if ($null -ne $Env:DRONE_SEMVER) { $nVersion = $Env:DRONE_SEMVER_SHORT @@ -39,37 +59,69 @@ function Update-ModuleMeta { if ($null -ne $Env:DRONE_SEMVER_PRERELEASE) { $nPreRelease = $Env:DRONE_SEMVER_PRERELEASE } - $ModManifestParams = @{ - Path = $Repo.Src.Manifest.Item.FullName - ModuleVersion = $nVersion - ErrorAction = 'Stop' + $DataParams = @{ + Path = $ManifestFilePath + ErrorAction = 'Stop' } + # Getting the module manifest as imported object + try { + $ModManifestData = Import-PowerShellDataFile @DataParams + } + catch { + $_.Exception.Message | Write-Debug + $ErrorParams = @{ + Message = "Could not import the module manifest file." + ErrorAction = 'Stop' + } + Write-Error @ErrorParams + } + # Updating the new module version + $ModManifestData.ModuleVersion = $nVersion + + # Updating the prerelease property if there is one if ($nPreRelease) { - $ModManifestParams.PreRelease = $nPreRelease + $ModManifestData.PrivateData.PSData.Prerelease = $nPreRelease } - $ManifestData = Test-ModuleManifest -Path $Repo.Src.Manifest.Item.FullName + $ManifestData = Test-ModuleManifest -Path $ManifestFilePath if ( ($nVersion -ne $ManifestData.Version) -or - ($nVersion -ne $ManifestData.PrivateData.PSData.Prerelease) + ($nPreRelease -ne $ManifestData.PrivateData.PSData.Prerelease) ) { - Update-ModuleManifest @ModManifestParams + $OutputFileParams = @{ + Path = $ManifestFilePath + #PassThru = $true + Encoding = 'utf8NoBom' + Force = $true + Verbose = $VerbosePreference + } + try { + $ModManifestData | ConvertTo-Psd | Set-Content @OutputFileParams + } + catch { + $_.Exception.Message | Write-Debug + $ErrorParams = @{ + Message = "Failed to update the module manifest file" + ErrorAction = 'Stop' + } + Write-Error @ErrorParams + } } else { - Write-Verbose -Message 'Identical version given. Skipping update.' + Write-Warning -Message 'Identical version given. Skipping update.' } } else { - Write-Verbose -Message 'Could not read the new Tag / Semver!' + Write-Warning -Message 'Could not read the new Tag / Semver!' } } else { - Write-Verbose -Message 'This pipeline was not triggered by a tag.' + Write-Warning -Message 'This pipeline was not triggered by a tag.' } } else { - Write-Verbose -Message 'Running outside of drone.io pipeline. Skipping module update!' + Write-Warning -Message 'Running outside of drone.io pipeline. Skipping module update!' } } } diff --git a/src/Deps/Invoke-InstallDependency.ps1 b/src/Deps/Invoke-InstallDependency.ps1 index 6c451e3..4181f48 100644 --- a/src/Deps/Invoke-InstallDependency.ps1 +++ b/src/Deps/Invoke-InstallDependency.ps1 @@ -56,6 +56,19 @@ function Invoke-InstallDependency { ErrorAction = 'Stop' } Install-Module @PoshParams + + $PsdKitParams = @{ + Name = 'PsdKit' + Scope = 'CurrentUser' + RequiredVersion = '0.6.2' + Force = $true + SkipPublisherCheck = $true + AllowClobber = $true + AllowPrerelease = $true + Verbose = $VerbosePreference + ErrorAction = 'Stop' + } + Install-Module @PsdKitParams } catch { $ExecParams = @{ diff --git a/src/DroneHelper.psd1 b/src/DroneHelper.psd1 index b022ccf..b221f33 100644 --- a/src/DroneHelper.psd1 +++ b/src/DroneHelper.psd1 @@ -68,6 +68,10 @@ @{ ModuleName = 'posh-git' ModuleVersion = '1.1.0' + }, + @{ + ModuleName = 'PsdKit' + ModuleVersion = '0.6.2' } ) diff --git a/tools/DevDependency.psm1 b/tools/DevDependency.psm1 index 58542ab..ed4c094 100644 --- a/tools/DevDependency.psm1 +++ b/tools/DevDependency.psm1 @@ -49,6 +49,20 @@ function Invoke-FixDevDependency { ErrorAction = 'Stop' } Install-Module @PoshParams + + + $PsdKitParams = @{ + Name = 'PsdKit' + Scope = 'CurrentUser' + RequiredVersion = '0.6.2' + Force = $true + SkipPublisherCheck = $true + AllowClobber = $true + AllowPrerelease = $true + Verbose = $VerbosePreference + ErrorAction = 'Stop' + } + Install-Module @PsdKitParams } catch { $ExecParams = @{