Scripts/InvokeBuildHelperTasks.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
<#
.SYNOPSIS Common build tasks for a PowerShell module. .DESCRIPTION Script with the common build tasks definition. The configuration will be stored in the $IBHConfig variable. .LINK https://github.com/nightroman/Invoke-Build https://github.com/claudiospizzi/PSInvokeBuildHelper #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')] param () # Load the build configuration $IBHConfig = Get-IBHConfig -BuildRoot $BuildRoot # Stop this build if we try to release the module itself. This is not supported at all. if ($null -ne (Get-PSCallStack | Where-Object { $_.Command -eq 'Invoke-Build.ps1' -and $_.Arguments -like '*Task=Release*' }) -and $IBHConfig.ModuleName -eq 'InvokeBuildHelper') { throw 'Release task is not supported for the module InvokeBuildHelper itself! Please use the sub-tasks Gallery and Repository.' } # Synopsis: The default task will verify, build and test the module. This task is intended to be used during the development of the target module. task . Verify, Build, Test # Synopsis: Release the module to the repository and the gallery. This task is used to publish a new module version. task Release Verify, Build, Test, Repository, Gallery, ZipFile # Synopsis: Build the C# solutions, if any exists. This includes clean, compile and deploy. task Build Clean, Compile # Synopsis: Test the module with pester and script analyzer. This includes schema tests, module unit tests and script analyzer rules. task Test UnitTest, SchemaTest, AnalyzerTest # Synopsis: Verify the build system itself, like the InvokeBuild and InvokeBuildHelper module version. task Verify { if ($IBHConfig.VerifyTask.Enabled) { # Ensure the module dependency on InvokeBuild is ok $ibActualVersion = Get-Module -Name 'InvokeBuild' | Select-Object -ExpandProperty 'Version' $ibRequiredVersion = [System.Version] $IBHConfig.VerifyTask.InvokeBuildVersion assert ($ibActualVersion -ge $ibRequiredVersion) "The InvokeBuild module version $ibActualVersion is outdated, please update to $ibRequiredVersion or later!" # Ensure the module dependency on InvokeBuildHelper itself is ok $ibhActualVersion = Get-Module -Name 'InvokeBuildHelper' | Select-Object -ExpandProperty 'Version' $ibhRequiredVersion = Invoke-RestMethod -Uri $IBHConfig.VerifyTask.ModulePackageUrl -TimeoutSec 5 | Select-Object -Last 1 | ForEach-Object { [System.Version] $_.properties.version } assert ($ibhActualVersion -ge $ibhRequiredVersion) "The InvokeBuildHelper module version $ibhActualVersion is outdated, please update to $ibhRequiredVersion or later!" } else { Write-Warning 'Verify task is disabled, no meta tests before build!' } } # Synopsis: Planned task for C# solution clean. task Clean { if (-not [System.String]::IsNullOrEmpty($IBHConfig.SolutionName)) { $Host.UI.WriteLine() # Get the MSBuild command $msBuildCommand = Resolve-MSBuild # Define the solution name to compile $solutionFile = '{0}\{1}\{1}.sln' -f $IBHConfig.BuildRoot, $IBHConfig.SolutionName # Invoke the release build exec { & "$msBuildCommand" "$solutionFile" /p:Configuration=Release /t:Clean /v:minimal } $Host.UI.WriteLine() } } # Synopsis: Planned task for C# solution compile. task Compile { if (-not [System.String]::IsNullOrEmpty($IBHConfig.SolutionName)) { $Host.UI.WriteLine() # Get the MSBuild command $msBuildCommand = Resolve-MSBuild # Define the solution name to compile $solutionFile = '{0}\{1}\{1}.sln' -f $IBHConfig.BuildRoot, $IBHConfig.SolutionName # Invoke the release build exec { & "$msBuildCommand" "$solutionFile" /p:Configuration=Release /t:Build /v:minimal } $Host.UI.WriteLine() } } # Synopsis: Run all pester unit tests for the PowerShell module. task UnitTest { $Host.UI.WriteLine() # Create output folder $outputPath = New-Item -Path (Join-Path -Path $BuildRoot -ChildPath 'out') -ItemType 'Directory' -Force | Select-Object -ExpandProperty 'FullName' # Invoke the Pester unit tests $result = Invoke-IBHPesterUnitTest -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName -OutputPath $outputPath $Host.UI.WriteLine() assert ($result.FailedCount -eq 0) ('{0} failure(s) in Pester Unit tests' -f $result.FailedCount) } # Synopsis: Run all pester integration tests for the PowerShell module. task IntegrationTest { $Host.UI.WriteLine() # Create output folder $outputPath = New-Item -Path (Join-Path -Path $BuildRoot -ChildPath 'out') -ItemType 'Directory' -Force | Select-Object -ExpandProperty 'FullName' # Invoke the Pester integration tests $result = Invoke-IBHPesterIntegrationTest -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName -OutputPath $outputPath $Host.UI.WriteLine() assert ($result.FailedCount -eq 0) ('{0} failure(s) in Pester Integration tests' -f $result.FailedCount) } # Synopsis: Test the PowerShell module schema. task SchemaTest { $Host.UI.WriteLine() # Create output folder $outputPath = New-Item -Path (Join-Path -Path $BuildRoot -ChildPath 'out') -ItemType 'Directory' -Force | Select-Object -ExpandProperty 'FullName' # Invoke the module schema tests $result = Invoke-IBHModuleSchemaTest -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName -TextFileExtension $IBHConfig.SchemaTask.TextFileExtension -ExcludePath $IBHConfig.SchemaTask.ExcludePath -OutputPath $outputPath $Host.UI.WriteLine() assert ($result.FailedCount -eq 0) ('{0} failure(s) in Module Schema tests' -f $result.FailedCount) } # Synopsis: Invoke the script analyzer for the PowerShell module. task AnalyzerTest { $Host.UI.WriteLine() # Create output folder $outputPath = New-Item -Path (Join-Path -Path $BuildRoot -ChildPath 'out') -ItemType 'Directory' -Force | Select-Object -ExpandProperty 'FullName' # Invoke the script analyzer, run all defined rules $result = Invoke-IBHScriptAnalyzerTest -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName -Rule $IBHConfig.AnalyzerTestTask.ScriptAnalyzerRules -ExcludePath $IBHConfig.AnalyzerTestTask.ExcludePath -OutputPath $outputPath $Host.UI.WriteLine() assert ($result.FailedCount -eq 0) ('{0} failure(s) in Script Analyzer tests' -f $result.FailedCount) } # Synopsis: Verify if the module is ready to be released. task Approve { if ($IBHConfig.ApproveTask.Enabled) { $moduleVersion = Get-IBHModuleVersion -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName $gitPendingFile = Get-IBHGitPendingFile assert ($gitPendingFile -eq 0) ('Module is not ready to release, {0} pending file(s) are present in the repo!' -f $gitPendingFile) $gitBranch = Get-IBHGitBranch assert ($gitBranch -eq $IBHConfig.ApproveTask.BranchName) ('Module is not ready to release, git branch should be on {0} but is {1}! (git checkout {0})' -f $IBHConfig.ApproveTask.BranchName, $gitBranch) $gitBehindBy = Get-IBHGitBehindBy assert ($gitBehindBy -eq 0) ('Module is not ready to release, git branch is behind by {0}! (git pull)' -f $gitBehindBy) $gitAheadBy = Get-IBHGitAheadBy assert ($gitAheadBy -eq 0) ('Module is not ready to release, git branch is ahead by {0}! (git push)' -f $gitAheadBy) $changeLogVersion = Test-IBHChangeLogVersion -BuildRoot $IBHConfig.BuildRoot -ModuleVersion $moduleVersion -ReleaseDate ([DateTime]::Now) assert $changeLogVersion ('Module is not ready to release, CHANGELOG.md does not contain the current version and/or date! (## {0} - {1:yyyy-MM-dd})' -f $moduleVersion, [DateTime]::Now) $gitLocalTag = Test-IBHGitLocalTag -ModuleVersion $moduleVersion assert $gitLocalTag ('Module is not ready to release, tag {0} does not exist or is not on the last commit! (git tag {0})' -f $moduleVersion) $gitRemoteTag = Test-IBHGitRemoteTag -ModuleVersion $moduleVersion assert $gitRemoteTag ('Module is not ready to release, tag {0} does not exist on origin! (git push --tag)' -f $moduleVersion) if (-not [System.String]::IsNullOrEmpty($IBHConfig.SolutionName)) { $solutionVersion = Test-IBHSolutionVersion -BuildRoot $IBHConfig.BuildRoot -SolutionName $IBHConfig.SolutionName -ModuleVersion $moduleVersion assert $solutionVersion ('Solution assembly info version does not match the module version {0}!' -f $moduleVersion) } if ($IBHConfig.GalleryTask.Enabled) { $galleryNames = Get-PSRepository | Select-Object -ExpandProperty 'Name' assert ($galleryNames -contains $IBHConfig.GalleryTask.Name) ('Module is not ready to release, PowerShell Gallery {0} is not registered! (Register-PSRepository -Name "{0}" ...)' -f $IBHConfig.GalleryTask.Name) } } else { Write-Warning 'Approve task is disabled, no approval tests before release!' } } # Synopsis: Release the module to the source code repository. task Repository Build, Approve, { if ($IBHConfig.RepositoryTask.Enabled) { $token = $null if ($null -ne $IBHConfig.RepositoryTask.Token) { $token = $IBHConfig.RepositoryTask.Token } elseif ($null -ne $IBHConfig.RepositoryTask.TokenCallback) { $token = & $IBHConfig.RepositoryTask.TokenCallback } assert ($null -ne $token -and $token -is [System.Security.SecureString]) 'Repository Token is missing, please set one of the following variables: $IBHConfig.RepositoryTask.Token or $IBHConfig.RepositoryTask.TokenCallback' $publishIBHRepository = @{ BuildRoot = $IBHConfig.BuildRoot ModuleName = $IBHConfig.ModuleName ModuleVersion = Get-IBHModuleVersion -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName RepositoryType = $IBHConfig.RepositoryTask.Type RepositoryUser = $IBHConfig.RepositoryTask.User RepositoryName = $IBHConfig.RepositoryTask.Name RepositoryToken = $token } Publish-IBHRepository @publishIBHRepository } else { Write-Warning 'Repository task is disabled, no release to the repository!' } } # Synopsis: Release the module to the PowerShell Gallery. task Gallery Build, Approve, { if ($IBHConfig.GalleryTask.Enabled) { $token = $null if ($null -ne $IBHConfig.GalleryTask.Token) { $token = $IBHConfig.GalleryTask.Token } elseif ($null -ne $IBHConfig.GalleryTask.TokenCallback) { $token = & $IBHConfig.GalleryTask.TokenCallback } assert ($null -ne $token -and $token -is [System.Security.SecureString]) 'Gallery Token is missing, please set one of the following variables: $IBHConfig.GalleryTask.Token or $IBHConfig.GalleryTask.TokenCallback' $publishIBHGallerySplat = @{ BuildRoot = $IBHConfig.BuildRoot ModuleName = $IBHConfig.ModuleName ModuleVersion = Get-IBHModuleVersion -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName GalleryUser = $IBHConfig.GalleryTask.User GalleryName = $IBHConfig.GalleryTask.Name GalleryToken = $token } Publish-IBHGallery @publishIBHGallerySplat } else { Write-Warning 'Gallery task is disabled, no release to the gallery!' } } # Synopsis: Release the module to the local file system as zip file. task ZipFile Build, Approve, { if ($IBHConfig.ZipFileTask.Enabled) { $publishIBHZipFileSplat = @{ BuildRoot = $IBHConfig.BuildRoot ModuleName = $IBHConfig.ModuleName ModuleVersion = Get-IBHModuleVersion -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName } Publish-IBHZipFile @publishIBHZipFileSplat } else { Write-Warning 'ZipFile task is disabled, no release to the local file system!' } } # Synopsis: Deploy a beta version as revision to the local module repository. task Deploy Build, { # Get the module version $sourceVersion = Get-IBHModuleVersion -BuildRoot $IBHConfig.BuildRoot -ModuleName $IBHConfig.ModuleName # Get the latest installed module version $targetVersion = Get-ChildItem -Path $IBHConfig.DeployTask.ModulePaths -Directory | Where-Object { $_.Name -eq $IBHConfig.ModuleName } | Get-ChildItem -Directory | ForEach-Object { [System.Version] $_.Name } | Sort-Object -Descending | Select-Object -First 1 # No version found, start with 0.0.0 if ([System.String]::IsNullOrEmpty($targetVersion)) { $targetVersion = [System.Version] '0.0.0' } # Increase the revision by one $targetVersion = [System.Version] ('{0}.{1}.{2}.{3}' -f $targetVersion.Major, $targetVersion.Minor, $targetVersion.Build, ($targetVersion.Revision + 1)) # Define the output path $Host.UI.WriteLine() foreach ($modulePath in $IBHConfig.DeployTask.ModulePaths) { $sourcePath = '{0}\{1}\*' -f $IBHConfig.BuildRoot, $IBHConfig.ModuleName $targetPath = '{0}\{1}\{2}' -f $modulePath, $IBHConfig.ModuleName, $targetVersion $targetFile = '{0}\{1}.psd1' -f $targetPath, $IBHConfig.ModuleName $Host.UI.WriteLine((' {0} {1} -> {2}' -f $IBHConfig.ModuleName, $targetVersion, $targetPath)) # Create the output folder New-Item -Path $targetPath -ItemType 'Directory' -Force | Out-Null # Deploy the module with recursive copy Copy-Item -Path $sourcePath -Destination $targetPath -Recurse -Force # Path the module definition $definition = Get-Content -Path $targetFile $definition = $definition -replace "ModuleVersion = '$sourceVersion'", "ModuleVersion = '$targetVersion'" $definition | Set-Content -Path $targetFile -Encoding 'UTF8' } $Host.UI.WriteLine() } |