From f3a18486f1872027709a11b2bab0a696fce074b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Gonz=C3=A1lez?= Date: Mon, 31 Jul 2023 15:02:45 +0200 Subject: [PATCH] Add deploy script to complete Add release wf (#19) * Remove load message * bug: as we are callling Write-AssertionDot * fea: add testing workflow * fea: add release workflow * fea: add release script * fea: add deploy script --- deploy.ps1 | 81 ++++++++++++++++++++++ tools/deploy.Helper.ps1 | 147 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 deploy.ps1 create mode 100644 tools/deploy.Helper.ps1 diff --git a/deploy.ps1 b/deploy.ps1 new file mode 100644 index 0000000..bf66cfb --- /dev/null +++ b/deploy.ps1 @@ -0,0 +1,81 @@ +<# +.SYNOPSIS + Deploy module to PSGallery + +.DESCRIPTION + Deploy module to PSGallery + +.PARAMETER VersionTag + Update the module manifest with the version tag (Sample: v10.0.01-alpha) + +.PARAMETER NuGetApiKey + PAT for the PSGallery + +.PARAMETER DependencyInjection + DependencyInjection SCRIPTBLOCK to dot source mainly for testing + +.EXAMPLE + .\deploy.ps1 -VersionTag v10.0.01-alpha -NuGetApiKey $NUGETAPIKEY + +.EXAMPLE + $env:$NUGETAPIKEY = '****' + .\deploy.ps1 -VersionTag v10.0.01-alpha + +.EXAMPLE + .\deploy.ps1 -VersionTag v10.0.01-alpha -NuGetApiKey $NUGETAPIKEY -DependencyInjection $SCRIPTBLOCK_FOR_TESTING + +.LINK + https://raw.githubusercontent.com/rulasg/DemoPsModule/main/deploy.ps1 + +#> + + +[cmdletbinding(SupportsShouldProcess, ConfirmImpact='High')] +param( + # Update the module manifest with the version tag (Sample: v10.0.01-alpha) + [Parameter(Mandatory=$false)] [string]$VersionTag, + # PAT for the PSGallery + [Parameter(Mandatory=$false)] [string]$NuGetApiKey, + # DependencyInjection Ps1 file + [Parameter(Mandatory=$false)] [scriptblock]$DependencyInjection +) + +$MODULE_PATH = $PSScriptRoot +$MODULE_NAME = $MODULE_PATH | Split-Path -LeafBase +$MODULE_PSD1 = Join-Path -Path $MODULE_PATH -ChildPath "$MODULE_NAME.psd1" +$MODULE_TOOLS = Join-Path -Path $MODULE_PATH -ChildPath "tools" + +# Load helper +# We dot souce the ps1 to allow all code to be in the same scope as the script +# Easier to inject for testing with DependecyInjection parameter +. ($MODULE_TOOLS | Join-Path -ChildPath "deploy.Helper.ps1") +if ($DependencyInjection) { + . $DependencyInjection +} + +# Process Tag +if($VersionTag){ + + try { + # Force manifest update even with -whatif + Update-DeployModuleManifest $VersionTag -whatif:$false + } + catch { + Write-Error -Message "Failed to update module manifest with version tag [$VersionTag]. Error: $_" + exit 1 + } +} + +# check that $NuggetApiKey is null or whitespace +# If it is use environment variable $env:NugetApiKey +if ( [string]::IsNullOrWhiteSpace($NuGetApiKey) ) { + if ( [string]::IsNullOrWhiteSpace($env:NUGETAPIKEY) ) { + # Write-Error -Message '$Env:NUGETAPIKEY is not set. Try running `$Env:NUGETAPIKEY = (Find-DocsFile nugetapikey | rsk | Get-SecretData).Get()`' + Write-Error -Message '$Env:NUGETAPIKEY is not set. Please set the variable with a PSGallery PAT or use -NuGetApiKey parameter.' + exit 1 + } + $NuGetApiKey = $env:NUGETAPIKEY +} + +# Deploy module to PSGallery +Invoke-DeployModuleToPSGallery -NuGetApiKey $NuGetApiKey -Force -ModuleManifestPath $MODULE_PSD1 diff --git a/tools/deploy.Helper.ps1 b/tools/deploy.Helper.ps1 new file mode 100644 index 0000000..16eeea5 --- /dev/null +++ b/tools/deploy.Helper.ps1 @@ -0,0 +1,147 @@ +# add help to script + +<# +.SYNOPSIS + Deploy a PowerShell module to the PowerShell Gallery. + +.DESCRIPTION + Functions library for deploying a PowerShell module to the PowerShell Gallery. + + This script is intended to be used as a helper for the Deploy.ps1 script. + It is not intended to be used directly. + +.LINK + https://raw.githubusercontent.com/rulasg/DemoPsModule/main/deploy.Helper.ps1 + https://github.com/rulasg/TestingHelper/blob/main/private/templates/template.v3.deploy.Helper.ps1 + https://raw.githubusercontent.com/rulasg/TestingHelper/main/private/templates/template.v3.deploy.Helper.ps1 + +#> + +Write-Information -MessageData ("Loading {0} ..." -f ($PSCommandPath | Split-Path -LeafBase)) + +# This functionalty should be moved to TestingHelper module to allow a simple Deploy.ps1 code. + +function Invoke-DeployModuleToPSGallery{ + [CmdletBinding( + SupportsShouldProcess, + ConfirmImpact='High' + )] + param( + # The NuGet API Key for the PSGallery + [Parameter(Mandatory=$true)] [string]$NuGetApiKey, + # Force the deploy without prompting for confirmation + [Parameter(Mandatory=$false)] [switch]$Force, + # Force deploying package to the gallery. Equivalente to Import-Module -Force + [Parameter(Mandatory=$false)] [switch]$ForceDeploy, + # Module Manifest Path + [Parameter(Mandatory=$false)] [string]$ModuleManifestPath + ) + + $psdPath = $ModuleManifestPath + + # check if $psd is set + if ( -not (Test-Path -Path $psdPath)) { + Write-Error -Message 'No psd1 file found' + return + } + + # Display Module Information + $psd1 = Import-PowerShellDataFile -Path $psdPath + $psd1 + $psd1.PrivateData.PSData + + # Confirm if not forced + if ($Force -and -not $Confirm){ + $ConfirmPreference = 'None' + } + + # Deploy the module with ShouldProcess (-whatif, -confirm) + if ($PSCmdlet.ShouldProcess($psdPath, "Invoke-DeployModule")) { + "Deploying {0} {1} {2} to PSGallery ..." -f $($psd1.RootModule), $($psd1.ModuleVersion), $($psd1.PrivateData.pSData.Prerelease) | Write-Information + # During testing we should use -WhatIf paarmetre when calling for deploy. + # Just reach this point when testing call failure + Invoke-DeployModule -Name $psdPath -NuGetApiKey $NuGetApiKey -Force:$ForceDeploy + } +} + +function Update-DeployModuleManifest { + [CmdletBinding(SupportsShouldProcess)] + param( + [Parameter(Mandatory=$true)][string]$VersionTag + ) + + $parameters = @{ + ModuleVersion = Get-DeployModuleVersion -VersionTag $VersionTag + Path = $MODULE_PSD1 + Prerelease = Get-DeployModulePreRelease -VersionTag $VersionTag + } + + # if ($PSCmdlet.ShouldProcess($parameters.Path, "Update-ModuleManifest with ModuleVersion:{0} Prerelease:{1}" -f $parameters.ModuleVersion, $parameters.Prerelease)) { + if ($PSCmdlet.ShouldProcess($parameters.Path, "Update-ModuleManifest with $versionTag")) { + "Updating module manifest with version tag [$VersionTag] ..." | Write-Information + Update-ModuleManifest @parameters + + } else { + Write-Warning -Message "Update-ModuleManifest skipped. Any PSD1 deploy will not have the proper version." + } + + if($?){ + Write-Information -MessageData "Updated module manifest with version tag [$VersionTag]" + } + else{ + Write-Error -Message "Failed to update module manifest with version tag [$VersionTag]" + exit 1 + } +} + +function script:Invoke-DeployModule { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)][string]$Name, + [Parameter(Mandatory=$true)][string]$NuGetApiKey, + [Parameter(Mandatory=$false)][switch]$Force + ) + + $parameters = @{ + Name = $Name + NuGetApiKey = $NuGetApiKey + Force = $Force + } + + Publish-Module @parameters + + if($?){ + Write-Information -MessageData "Deployed module [$Name] to PSGallery" + } + else{ + Write-Error -Message "Failed to deploy module [$Name] to PSGallery" + exit 1 + } +} + +function Get-DeployModuleVersion { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)][string]$VersionTag + ) + + $version = $VersionTag.split('-')[0] + #remove all leters from $version + $version = $version -replace '[a-zA-Z_]' + $version +} + +function Get-DeployModulePreRelease { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)][string]$VersionTag + ) + + $preRelease = $VersionTag.split('-')[1] + # to clear the preRelease by Update-ModuleManifest + # preRelease must be a string with a space. + # $null or [string]::Empty leaves the value that has. + $preRelease = $preRelease ?? " " + $preRelease +} +