From d3b3c24d65fb63a042da84a8396a15b85f904451 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 09:59:58 -0800 Subject: [PATCH 01/23] Changes to Pode.build to support net9 --- pode.build.ps1 | 1619 ++++++++++++++++++++------------------ src/Listener/Pode.csproj | 2 +- 2 files changed, 867 insertions(+), 754 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index d82731d5c..eea1b6799 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -22,997 +22,1110 @@ param( $UICulture = 'en-US' ) -# Fix for PS7.5 Preview - https://github.com/PowerShell/PowerShell/issues/23868 -$ProgressPreference = 'SilentlyContinue' -<# -# Dependency Versions -#> -$Versions = @{ - Pester = '5.6.1' - MkDocs = '1.6.0' - PSCoveralls = '1.0.0' - SevenZip = '18.5.0.20180730' - DotNet = '8.0' - MkDocsTheme = '9.5.23' - PlatyPS = '0.14.2' -} +# Check if the script is running under Invoke-Build +if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BuildRoot') -or $null -ne $BuildRoot)) { -<# -# Helper Functions -#> -function Test-PodeBuildIsWindows { - $v = $PSVersionTable - return ($v.Platform -ilike '*win*' -or ($null -eq $v.Platform -and $v.PSEdition -ieq 'desktop')) -} + # Dependency Versions + $Versions = @{ + Pester = '5.6.1' + MkDocs = '1.6.1' + PSCoveralls = '1.0.0' + SevenZip = '18.5.0.20180730' + DotNet = '9.0' + MkDocsTheme = '9.5.44' + PlatyPS = '0.14.2' + } -function Test-PodeBuildIsGitHub { - return (![string]::IsNullOrWhiteSpace($env:GITHUB_REF)) -} -function Test-PodeBuildCanCodeCoverage { - return (@('1', 'true') -icontains $env:PODE_RUN_CODE_COVERAGE) -} + $NetVersions = 'netstandard2.0', 'netstandard2.1', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0' + #Unsupported .NET Framework version 'net4.0', 'net4.5', 'net4.5.1', 'net4.5.2', 'net4.6', 'net4.6.1', 'net4.6.2', 'net4.7', 'net4.7.1', 'net4.7.2', 'net4.8' -function Get-PodeBuildService { - return 'github-actions' -} + # Helper Functions + function Test-PodeBuildIsWindows { + $v = $PSVersionTable + return ($v.Platform -ilike '*win*' -or ($null -eq $v.Platform -and $v.PSEdition -ieq 'desktop')) + } -function Test-PodeBuildCommand($cmd) { - $path = $null + function Test-PodeBuildIsGitHub { + return (![string]::IsNullOrWhiteSpace($env:GITHUB_REF)) + } - if (Test-PodeBuildIsWindows) { - $path = (Get-Command $cmd -ErrorAction Ignore) + function Test-PodeBuildCanCodeCoverage { + return (@('1', 'true') -icontains $env:PODE_RUN_CODE_COVERAGE) } - else { - $path = (which $cmd) + + function Get-PodeBuildService { + return 'github-actions' } - return (![string]::IsNullOrWhiteSpace($path)) -} + function Test-PodeBuildCommand($cmd) { + $path = $null -function Get-PodeBuildBranch { - return ($env:GITHUB_REF -ireplace 'refs\/heads\/', '') -} + if (Test-PodeBuildIsWindows) { + $path = (Get-Command $cmd -ErrorAction Ignore) + } + else { + $path = (which $cmd) + } -function Invoke-PodeBuildInstall($name, $version) { - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + return (![string]::IsNullOrWhiteSpace($path)) + } - if (Test-PodeBuildIsWindows) { - if (Test-PodeBuildCommand 'choco') { - choco install $name --version $version -y --no-progress - } + function Get-PodeBuildBranch { + return ($env:GITHUB_REF -ireplace 'refs\/heads\/', '') } - else { - if (Test-PodeBuildCommand 'brew') { - brew install $name - } - elseif (Test-PodeBuildCommand 'apt-get') { - sudo apt-get install $name -y + + function Invoke-PodeBuildInstall($name, $version) { + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + if (Test-PodeBuildIsWindows) { + if (Test-PodeBuildCommand 'choco') { + choco install $name --version $version -y --no-progress + } } - elseif (Test-PodeBuildCommand 'yum') { - sudo yum install $name -y + else { + if (Test-PodeBuildCommand 'brew') { + brew install $name + } + elseif (Test-PodeBuildCommand 'apt-get') { + sudo apt-get install $name -y + } + elseif (Test-PodeBuildCommand 'yum') { + sudo yum install $name -y + } } } -} -function Install-PodeBuildModule($name) { - if ($null -ne ((Get-Module -ListAvailable $name) | Where-Object { $_.Version -ieq $Versions[$name] })) { - return + function Install-PodeBuildModule($name) { + if ($null -ne ((Get-Module -ListAvailable $name) | Where-Object { $_.Version -ieq $Versions[$name] })) { + return + } + + Write-Host "Installing $($name) v$($Versions[$name])" + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Install-Module -Name "$($name)" -Scope CurrentUser -RequiredVersion "$($Versions[$name])" -Force -SkipPublisherCheck } - Write-Host "Installing $($name) v$($Versions[$name])" - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - Install-Module -Name "$($name)" -Scope CurrentUser -RequiredVersion "$($Versions[$name])" -Force -SkipPublisherCheck -} + function Invoke-PodeBuildDotnetBuild { + param ( + [string]$target + ) -function Invoke-PodeBuildDotnetBuild($target) { - # Retrieve the highest installed SDK version - $majorVersion = ([version](dotnet --version)).Major + # Verify if the target is a known .NET version + if ($target -notin $NetVersions) { + Write-Host "Unknown target framework '$target'. Please specify a valid .NET framework." + return + } - # Determine if the target framework is compatible - $isCompatible = $False - switch ($majorVersion) { - 8 { if ($target -in @('net6.0', 'netstandard2.0', 'net8.0')) { $isCompatible = $True } } - 7 { if ($target -in @('net6.0', 'netstandard2.0')) { $isCompatible = $True } } - 6 { if ($target -in @('net6.0', 'netstandard2.0')) { $isCompatible = $True } } - } + # Retrieve the installed SDK versions + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + + # Map target frameworks to minimum SDK versions + $targetSdkMap = @{ + 'netstandard2.0' = 2 + 'netstandard2.1' = 3 + 'netcoreapp3.1' = 3 + 'net5.0' = 5 + 'net6.0' = 6 + 'net7.0' = 7 + 'net8.0' = 8 + 'net9.0' = 9 + } - # Skip build if not compatible - if ($isCompatible) { - Write-Host "SDK for target framework $target is compatible with the installed SDKs" - } - else { - Write-Host "SDK for target framework $target is not compatible with the installed SDKs. Skipping build." - return - } - if ($Version) { - Write-Host "Assembly Version $Version" - $AssemblyVersion = "-p:Version=$Version" - } - else { - $AssemblyVersion = '' - } + # Determine if the target framework is compatible + $isCompatible = $False - dotnet publish --configuration Release --self-contained --framework $target $AssemblyVersion --output ../Libs/$target - if (!$?) { - throw "dotnet publish failed for $($target)" - } + if ($targetSdkMap.ContainsKey($target)) { + $requiredSdkVersion = $targetSdkMap[$target] -} + foreach ($sdkVersion in $sdkVersions) { + $sdkMajor = ([version]$sdkVersion).Major + if ($sdkMajor -ge $requiredSdkVersion) { + $isCompatible = $True + break + } + } + } + elseif ($target -like 'net4*') { + # .NET Framework targets require MSBuild, typically available with Visual Studio + $msbuildPath = Get-Command msbuild -ErrorAction SilentlyContinue + if ($msbuildPath) { + $isCompatible = $True + } + else { + Write-Host 'MSBuild is not available. Cannot build .NET Framework targets.' + return + } + } -function Get-PodeBuildPwshEOL { - $eol = Invoke-RestMethod -Uri 'https://endoflife.date/api/powershell.json' -Headers @{ Accept = 'application/json' } - return @{ - eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' - supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' - } -} + if ($isCompatible) { + Write-Host "SDK for target framework '$target' is compatible with the installed SDKs." + } + else { + Write-Host "SDK for target framework '$target' is not compatible with the installed SDKs. Skipping build." + return + } -function Test-PodeBuildOSWindows { - return ($IsWindows -or - ![string]::IsNullOrEmpty($env:ProgramFiles) -or - (($PSVersionTable.Keys -contains 'PSEdition') -and ($PSVersionTable.PSEdition -eq 'Desktop'))) -} + # Optionally set assembly version + if ($Version) { + Write-Host "Assembly Version: $Version" + $AssemblyVersion = "-p:Version=$Version" + } + else { + $AssemblyVersion = '' + } -function Get-PodeBuildOSPwshName { - if (Test-PodeBuildOSWindows) { - return 'win' - } + # Execute dotnet publish or MSBuild depending on the target + if ($target -like 'net4*') { + # Use MSBuild for .NET Framework targets + $projectFile = 'YourProject.csproj' # Replace with your actual project file + & msbuild $projectFile /p:Configuration=Release /p:TargetFramework=$target $AssemblyVersion /p:OutputPath="../Libs/$target" + } + else { + # Use dotnet publish for .NET Core and .NET 5+ + dotnet publish --configuration Release --self-contained --framework $target $AssemblyVersion --output ../Libs/$target + } - if ($IsLinux) { - return 'linux' + if (!$?) { + throw "Build failed for target framework '$target'." + } } - if ($IsMacOS) { - return 'osx' + function Get-PodeBuildPwshEOL { + $uri = 'https://endoflife.date/api/powershell.json' + try { + $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } + return @{ + eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' + supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' + } + } + catch { + Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" + return @{ + eol = '' + supported = '' + } + } } -} -function Get-PodeBuildOSPwshArchitecture { - $arch = [string]::Empty - # windows - if (Test-PodeBuildOSWindows) { - $arch = $env:PROCESSOR_ARCHITECTURE + function Get-PodeBuildDotNetEOL { + $uri = 'https://endoflife.date/api/dotnet.json' + try { + $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } + return @{ + eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' + supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' + } + } + catch { + Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" + return @{ + eol = '' + supported = '' + } + } } - - # unix - if ($IsLinux -or $IsMacOS) { - $arch = uname -m + function Test-PodeBuildOSWindows { + return ($IsWindows -or + ![string]::IsNullOrEmpty($env:ProgramFiles) -or + (($PSVersionTable.Keys -contains 'PSEdition') -and ($PSVersionTable.PSEdition -eq 'Desktop'))) } - Write-Host "OS Architecture: $($arch)" + function Get-PodeBuildOSPwshName { + if (Test-PodeBuildOSWindows) { + return 'win' + } + + if ($IsLinux) { + return 'linux' + } - # convert to pwsh arch - switch ($arch.ToLowerInvariant()) { - 'amd64' { return 'x64' } - 'x86' { return 'x86' } - 'x86_64' { return 'x64' } - 'armv7*' { return 'arm32' } - 'aarch64*' { return 'arm64' } - 'arm64' { return 'arm64' } - 'arm64*' { return 'arm64' } - 'armv8*' { return 'arm64' } - default { throw "Unsupported architecture: $($arch)" } + if ($IsMacOS) { + return 'osx' + } } -} -function Convert-PodeBuildOSPwshTagToVersion { - $result = Invoke-RestMethod -Uri "https://aka.ms/pwsh-buildinfo-$($PowerShellVersion)" - return $result.ReleaseTag -ireplace '^v' -} + function Get-PodeBuildOSPwshArchitecture { + $arch = [string]::Empty -function Install-PodeBuildPwshWindows($target) { - $installFolder = "$($env:ProgramFiles)\PowerShell\7" + # windows + if (Test-PodeBuildOSWindows) { + $arch = $env:PROCESSOR_ARCHITECTURE + } - if (Test-Path $installFolder) { - Remove-Item $installFolder -Recurse -Force -ErrorAction Stop + # unix + if ($IsLinux -or $IsMacOS) { + $arch = uname -m + } + + Write-Host "OS Architecture: $($arch)" + + # convert to pwsh arch + switch ($arch.ToLowerInvariant()) { + 'amd64' { return 'x64' } + 'x86' { return 'x86' } + 'x86_64' { return 'x64' } + 'armv7*' { return 'arm32' } + 'aarch64*' { return 'arm64' } + 'arm64' { return 'arm64' } + 'arm64*' { return 'arm64' } + 'armv8*' { return 'arm64' } + default { throw "Unsupported architecture: $($arch)" } + } } - Copy-Item -Path "$($target)\" -Destination "$($installFolder)\" -Recurse -ErrorAction Stop -} + function Convert-PodeBuildOSPwshTagToVersion { + $result = Invoke-RestMethod -Uri "https://aka.ms/pwsh-buildinfo-$($PowerShellVersion)" + return $result.ReleaseTag -ireplace '^v' + } -function Install-PodeBuildPwshUnix($target) { - $targetFullPath = Join-Path -Path $target -ChildPath 'pwsh' - $null = chmod 755 $targetFullPath + function Install-PodeBuildPwshWindows($target) { + $installFolder = "$($env:ProgramFiles)\PowerShell\7" - $symlink = $null - if ($IsMacOS) { - $symlink = '/usr/local/bin/pwsh' - } - else { - $symlink = '/usr/bin/pwsh' - } + if (Test-Path $installFolder) { + Remove-Item $installFolder -Recurse -Force -ErrorAction Stop + } - $uid = id -u - if ($uid -ne '0') { - $sudo = 'sudo' - } - else { - $sudo = '' + Copy-Item -Path "$($target)\" -Destination "$($installFolder)\" -Recurse -ErrorAction Stop } - # Make symbolic link point to installed path - & $sudo ln -fs $targetFullPath $symlink -} + function Install-PodeBuildPwshUnix($target) { + $targetFullPath = Join-Path -Path $target -ChildPath 'pwsh' + $null = chmod 755 $targetFullPath -function Get-PodeBuildCurrentPwshVersion { - return ("$(pwsh -v)" -split ' ')[1].Trim() -} + $symlink = $null + if ($IsMacOS) { + $symlink = '/usr/local/bin/pwsh' + } + else { + $symlink = '/usr/bin/pwsh' + } + + $uid = id -u + if ($uid -ne '0') { + $sudo = 'sudo' + } + else { + $sudo = '' + } -function Invoke-PodeBuildDockerBuild($tag, $file) { - docker build -t badgerati/pode:$tag -f $file . - if (!$?) { - throw "docker build failed for $($tag)" + # Make symbolic link point to installed path + & $sudo ln -fs $targetFullPath $symlink } - docker tag badgerati/pode:$tag docker.pkg.github.com/badgerati/pode/pode:$tag - if (!$?) { - throw "docker tag failed for $($tag)" + function Get-PodeBuildCurrentPwshVersion { + return ("$(pwsh -v)" -split ' ')[1].Trim() } -} -function Split-PodeBuildPwshPath { - if (Test-PodeBuildOSWindows) { - return $env:PSModulePath -split ';' + function Invoke-PodeBuildDockerBuild($tag, $file) { + docker build -t badgerati/pode:$tag -f $file . + if (!$?) { + throw "docker build failed for $($tag)" + } + + docker tag badgerati/pode:$tag docker.pkg.github.com/badgerati/pode/pode:$tag + if (!$?) { + throw "docker tag failed for $($tag)" + } } - else { - return $env:PSModulePath -split ':' + + function Split-PodeBuildPwshPath { + if (Test-PodeBuildOSWindows) { + return $env:PSModulePath -split ';' + } + else { + return $env:PSModulePath -split ':' + } } -} -<# + <# # Helper Tasks #> -# Synopsis: Stamps the version onto the Module -Task StampVersion { - $pwshVersions = Get-PodeBuildPwshEOL + # Synopsis: Stamps the version onto the Module + Task StampVersion { + $pwshVersions = Get-PodeBuildPwshEOL (Get-Content ./pkg/Pode.psd1) | ForEach-Object { $_ -replace '\$version\$', $Version -replace '\$versionsUntested\$', $pwshVersions.eol -replace '\$versionsSupported\$', $pwshVersions.supported -replace '\$buildyear\$', ((get-date).Year) } | Set-Content ./pkg/Pode.psd1 (Get-Content ./pkg/Pode.Internal.psd1) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./pkg/Pode.Internal.psd1 (Get-Content ./packers/choco/pode_template.nuspec) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./packers/choco/pode.nuspec (Get-Content ./packers/choco/tools/ChocolateyInstall_template.ps1) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./packers/choco/tools/ChocolateyInstall.ps1 -} + } -# Synopsis: Generating a Checksum of the Zip -Task PrintChecksum { - $Script:Checksum = (Get-FileHash "./deliverable/$Version-Binaries.zip" -Algorithm SHA256).Hash - Write-Host "Checksum: $($Checksum)" -} + # Synopsis: Generating a Checksum of the Zip + Task PrintChecksum { + $Script:Checksum = (Get-FileHash "./deliverable/$Version-Binaries.zip" -Algorithm SHA256).Hash + Write-Host "Checksum: $($Checksum)" + } -<# + <# # Dependencies #> -# Synopsis: Installs Chocolatey -Task ChocoDeps -If (Test-PodeBuildIsWindows) { - if (!(Test-PodeBuildCommand 'choco')) { - Set-ExecutionPolicy Bypass -Scope Process -Force - Invoke-Expression ([System.Net.WebClient]::new().DownloadString('https://chocolatey.org/install.ps1')) + # Synopsis: Installs Chocolatey + Task ChocoDeps -If (Test-PodeBuildIsWindows) { + if (!(Test-PodeBuildCommand 'choco')) { + Set-ExecutionPolicy Bypass -Scope Process -Force + Invoke-Expression ([System.Net.WebClient]::new().DownloadString('https://chocolatey.org/install.ps1')) + } } -} -# Synopsis: Install dependencies for packaging -Task PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, { - if (!(Test-PodeBuildCommand '7z')) { - Invoke-PodeBuildInstall '7zip' $Versions.SevenZip + # Synopsis: Install dependencies for packaging + Task PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, { + if (!(Test-PodeBuildCommand '7z')) { + Invoke-PodeBuildInstall '7zip' $Versions.SevenZip + } } -} -# Synopsis: Install dependencies for compiling/building -Task BuildDeps { - # install dotnet - if (Test-PodeBuildIsWindows) { - $dotnet = 'dotnet' - } - else { - $dotnet = "dotnet-sdk-$($Versions.DotNet)" - } + # Synopsis: Install dependencies for compiling/building + Task BuildDeps { + # install dotnet + if (Test-PodeBuildIsWindows) { + $dotnet = 'dotnet' + } + else { + $dotnet = "dotnet-sdk-$($Versions.DotNet)" + } - if (!(Test-PodeBuildCommand 'dotnet')) { - Invoke-PodeBuildInstall $dotnet $Versions.DotNet + if (!(Test-PodeBuildCommand 'dotnet')) { + Invoke-PodeBuildInstall $dotnet $Versions.DotNet + } } -} -# Synopsis: Install dependencies for running tests -Task TestDeps { - # install pester - Install-PodeBuildModule Pester + # Synopsis: Install dependencies for running tests + Task TestDeps { + # install pester + Install-PodeBuildModule Pester - # install PSCoveralls - if (Test-PodeBuildCanCodeCoverage) { - Install-PodeBuildModule PSCoveralls + # install PSCoveralls + if (Test-PodeBuildCanCodeCoverage) { + Install-PodeBuildModule PSCoveralls + } } -} -# Synopsis: Install dependencies for documentation -Task DocsDeps ChocoDeps, { - # install mkdocs - if (!(Test-PodeBuildCommand 'mkdocs')) { - Invoke-PodeBuildInstall 'mkdocs' $Versions.MkDocs - } + # Synopsis: Install dependencies for documentation + Task DocsDeps ChocoDeps, { + # install mkdocs + if (!(Test-PodeBuildCommand 'mkdocs')) { + Invoke-PodeBuildInstall 'mkdocs' $Versions.MkDocs + } + + $_installed = (pip list --format json --disable-pip-version-check | ConvertFrom-Json) + if (($_installed | Where-Object { $_.name -ieq 'mkdocs-material' -and $_.version -ieq $Versions.MkDocsTheme } | Measure-Object).Count -eq 0) { + pip install "mkdocs-material==$($Versions.MkDocsTheme)" --force-reinstall --disable-pip-version-check --quiet + } - $_installed = (pip list --format json --disable-pip-version-check | ConvertFrom-Json) - if (($_installed | Where-Object { $_.name -ieq 'mkdocs-material' -and $_.version -ieq $Versions.MkDocsTheme } | Measure-Object).Count -eq 0) { - pip install "mkdocs-material==$($Versions.MkDocsTheme)" --force-reinstall --disable-pip-version-check --quiet + # install platyps + Install-PodeBuildModule PlatyPS } - # install platyps - Install-PodeBuildModule PlatyPS -} + Task IndexSamples { + $examplesPath = './examples' + if (!(Test-Path -PathType Container -Path $examplesPath)) { + return + } -Task IndexSamples { - $examplesPath = './examples' - if (!(Test-Path -PathType Container -Path $examplesPath)) { - return + # List of directories to exclude + $sampleMarkDownPath = './docs/Getting-Started/Samples.md' + $excludeDirs = @('scripts', 'views', 'static', 'public', 'assets', 'timers', 'modules', + 'Authentication', 'certs', 'logs', 'relative', 'routes', 'issues') + + # Convert exlusion list into single regex pattern for directory matching + $dirSeparator = [IO.Path]::DirectorySeparatorChar + $excludeDirs = "\$($dirSeparator)($($excludeDirs -join '|'))\$($dirSeparator)" + + # build the page content + Get-ChildItem -Path $examplesPath -Filter *.ps1 -Recurse -File -Force | + Where-Object { + $_.FullName -inotmatch $excludeDirs + } | + Sort-Object -Property FullName | + ForEach-Object { + Write-Verbose "Processing Sample: $($_.FullName)" + + # get the script help + $help = Get-Help -Name $_.FullName -ErrorAction Stop + + # add help content + $urlFileName = ($_.FullName -isplit 'examples')[1].Trim('\/') -replace '[\\/]', '/' + $markdownContent += "## [$($_.BaseName)](https://github.com/Badgerati/Pode/blob/develop/examples/$($urlFileName))`n`n" + $markdownContent += "**Synopsis**`n`n$($help.Synopsis)`n`n" + $markdownContent += "**Description**`n`n$($help.Description.Text)`n`n" + } + + Write-Output "Write Markdown document for the sample files to $($sampleMarkDownPath)" + Set-Content -Path $sampleMarkDownPath -Value "# Sample Scripts`n`n$($markdownContent)" -Force } - # List of directories to exclude - $sampleMarkDownPath = './docs/Getting-Started/Samples.md' - $excludeDirs = @('scripts', 'views', 'static', 'public', 'assets', 'timers', 'modules', - 'Authentication', 'certs', 'logs', 'relative', 'routes', 'issues') + <# +# Building +#> + + # Synopsis: Build the .NET Listener + Task Build BuildDeps, { + if (Test-Path ./src/Libs) { + Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null + } - # Convert exlusion list into single regex pattern for directory matching - $dirSeparator = [IO.Path]::DirectorySeparatorChar - $excludeDirs = "\$($dirSeparator)($($excludeDirs -join '|'))\$($dirSeparator)" + # Retrieve supported .NET versions + $eol = Get-PodeBuildDotNetEOL - # build the page content - Get-ChildItem -Path $examplesPath -Filter *.ps1 -Recurse -File -Force | - Where-Object { - $_.FullName -inotmatch $excludeDirs - } | - Sort-Object -Property FullName | - ForEach-Object { - Write-Verbose "Processing Sample: $($_.FullName)" + $targetFrameworks = @() - # get the script help - $help = Get-Help -Name $_.FullName -ErrorAction Stop + if (![string]::IsNullOrEmpty($eol.supported)) { - # add help content - $urlFileName = ($_.FullName -isplit 'examples')[1].Trim('\/') -replace '[\\/]', '/' - $markdownContent += "## [$($_.BaseName)](https://github.com/Badgerati/Pode/blob/develop/examples/$($urlFileName))`n`n" - $markdownContent += "**Synopsis**`n`n$($help.Synopsis)`n`n" - $markdownContent += "**Description**`n`n$($help.Description.Text)`n`n" + # Parse supported versions into an array + $supportedVersions = $eol['supported'] -split ',' + + # Construct target framework monikers + $targetFrameworks += ($supportedVersions | ForEach-Object { "net$_.0" }) } - Write-Output "Write Markdown document for the sample files to $($sampleMarkDownPath)" - Set-Content -Path $sampleMarkDownPath -Value "# Sample Scripts`n`n$($markdownContent)" -Force -} + # Optionally include netstandard2.0 + $targetFrameworks += 'netstandard2.0' -<# -# Building -#> -# Synopsis: Build the .NET Listener -Task Build BuildDeps, { - if (Test-Path ./src/Libs) { - Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null - } + # Retrieve the SDK version being used + $sdkVersion = dotnet --version + + # Display the SDK version + Write-Output "Building target framework '$($targetFrameworks -join "','")' using .NET SDK version '$sdkVersion'" + + # Build for supported target frameworks + try { + Push-Location ./src/Listener + foreach ($target in $targetFrameworks) { + Invoke-PodeBuildDotnetBuild -target $target + Write-Host + Write-Host "***********************" -ForegroundColor DarkMagenta + + } + } + finally { + Pop-Location + } - try { - Push-Location ./src/Listener - Invoke-PodeBuildDotnetBuild -target 'netstandard2.0' - Invoke-PodeBuildDotnetBuild -target 'net6.0' - Invoke-PodeBuildDotnetBuild -target 'net8.0' - } - finally { - Pop-Location } -} -<# + <# # Packaging #> -# Synopsis: Creates a Zip of the Module -Task 7Zip -If (Test-PodeBuildIsWindows) PackDeps, StampVersion, { - exec { & 7z -tzip a $Version-Binaries.zip ./pkg/* } -}, PrintChecksum - -#Synopsis: Create the Deliverable folder -Task DeliverableFolder { - $path = './deliverable' - if (Test-Path $path) { - Remove-Item -Path $path -Recurse -Force | Out-Null - } + # Synopsis: Creates a Zip of the Module + Task 7Zip -If (Test-PodeBuildIsWindows) PackDeps, StampVersion, { + exec { & 7z -tzip a $Version-Binaries.zip ./pkg/* } + }, PrintChecksum - # create the deliverable dir - New-Item -Path $path -ItemType Directory -Force | Out-Null -} - -# Synopsis: Creates a Zip of the Module -Task Compress PackageFolder, StampVersion, DeliverableFolder, { - $path = './deliverable' - if (Test-Path $path) { - Remove-Item -Path $path -Recurse -Force | Out-Null - } - # create the pkg dir - New-Item -Path $path -ItemType Directory -Force | Out-Null - Compress-Archive -Path './pkg/*' -DestinationPath "$path/$Version-Binaries.zip" -}, PrintChecksum - -# Synopsis: Creates a Chocolately package of the Module -Task ChocoPack -If (Test-PodeBuildIsWindows) PackDeps, PackageFolder, StampVersion, DeliverableFolder, { - exec { choco pack ./packers/choco/pode.nuspec } - Move-Item -Path "pode.$Version.nupkg" -Destination './deliverable' -} + #Synopsis: Create the Deliverable folder + Task DeliverableFolder { + $path = './deliverable' + if (Test-Path $path) { + Remove-Item -Path $path -Recurse -Force | Out-Null + } -# Synopsis: Create docker tags -Task DockerPack PackageFolder, StampVersion, { - # check if github and windows, and output warning - if ((Test-PodeBuildIsGitHub) -and (Test-PodeBuildIsWindows)) { - Write-Warning 'Docker images are not built on GitHub Windows runners, and Docker is in Windows container only mode. Exiting task.' - return + # create the deliverable dir + New-Item -Path $path -ItemType Directory -Force | Out-Null } - try { - # Try to get the Docker version to check if Docker is installed - docker --version - } - catch { - # If Docker is not available, exit the task - Write-Warning 'Docker is not installed or not available in the PATH. Exiting task.' - return - } + # Synopsis: Creates a Zip of the Module + Task Compress PackageFolder, StampVersion, DeliverableFolder, { + $path = './deliverable' + if (Test-Path $path) { + Remove-Item -Path $path -Recurse -Force | Out-Null + } + # create the pkg dir + New-Item -Path $path -ItemType Directory -Force | Out-Null + Compress-Archive -Path './pkg/*' -DestinationPath "$path/$Version-Binaries.zip" + }, PrintChecksum + + # Synopsis: Creates a Chocolately package of the Module + Task ChocoPack -If (Test-PodeBuildIsWindows) PackDeps, PackageFolder, StampVersion, DeliverableFolder, { + exec { choco pack ./packers/choco/pode.nuspec } + Move-Item -Path "pode.$Version.nupkg" -Destination './deliverable' + } + + # Synopsis: Create docker tags + Task DockerPack PackageFolder, StampVersion, { + # check if github and windows, and output warning + if ((Test-PodeBuildIsGitHub) -and (Test-PodeBuildIsWindows)) { + Write-Warning 'Docker images are not built on GitHub Windows runners, and Docker is in Windows container only mode. Exiting task.' + return + } + + try { + # Try to get the Docker version to check if Docker is installed + docker --version + } + catch { + # If Docker is not available, exit the task + Write-Warning 'Docker is not installed or not available in the PATH. Exiting task.' + return + } - Invoke-PodeBuildDockerBuild -Tag $Version -File './Dockerfile' - Invoke-PodeBuildDockerBuild -Tag 'latest' -File './Dockerfile' - Invoke-PodeBuildDockerBuild -Tag "$Version-alpine" -File './alpine.dockerfile' - Invoke-PodeBuildDockerBuild -Tag 'latest-alpine' -File './alpine.dockerfile' + Invoke-PodeBuildDockerBuild -Tag $Version -File './Dockerfile' + Invoke-PodeBuildDockerBuild -Tag 'latest' -File './Dockerfile' + Invoke-PodeBuildDockerBuild -Tag "$Version-alpine" -File './alpine.dockerfile' + Invoke-PodeBuildDockerBuild -Tag 'latest-alpine' -File './alpine.dockerfile' - if (!(Test-PodeBuildIsGitHub)) { - Invoke-PodeBuildDockerBuild -Tag "$Version-arm32" -File './arm32.dockerfile' - Invoke-PodeBuildDockerBuild -Tag 'latest-arm32' -File './arm32.dockerfile' - } - else { - Write-Warning 'Docker images for ARM32 are not built on GitHub runners due to having the wrong OS architecture. Skipping.' + if (!(Test-PodeBuildIsGitHub)) { + Invoke-PodeBuildDockerBuild -Tag "$Version-arm32" -File './arm32.dockerfile' + Invoke-PodeBuildDockerBuild -Tag 'latest-arm32' -File './arm32.dockerfile' + } + else { + Write-Warning 'Docker images for ARM32 are not built on GitHub runners due to having the wrong OS architecture. Skipping.' + } } -} -# Synopsis: Package up the Module -Task Pack Compress, ChocoPack, DockerPack + # Synopsis: Package up the Module + Task Pack Compress, ChocoPack, DockerPack -# Synopsis: Package up the Module into a /pkg folder -Task PackageFolder Build, { - $path = './pkg' - if (Test-Path $path) { - Remove-Item -Path $path -Recurse -Force | Out-Null - } + # Synopsis: Package up the Module into a /pkg folder + Task PackageFolder Build, { + $path = './pkg' + if (Test-Path $path) { + Remove-Item -Path $path -Recurse -Force | Out-Null + } - # create the pkg dir - New-Item -Path $path -ItemType Directory -Force | Out-Null + # create the pkg dir + New-Item -Path $path -ItemType Directory -Force | Out-Null - # which source folders do we need? create them and copy their contents - $folders = @('Private', 'Public', 'Misc', 'Libs', 'Locales') - $folders | ForEach-Object { - New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null - Copy-Item -Path "./src/$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null - } + # which source folders do we need? create them and copy their contents + $folders = @('Private', 'Public', 'Misc', 'Libs', 'Locales') + $folders | ForEach-Object { + New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null + Copy-Item -Path "./src/$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null + } - # which route folders to we need? create them and copy their contents - $folders = @('licenses') - $folders | ForEach-Object { - New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null - Copy-Item -Path "./$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null - } + # which route folders to we need? create them and copy their contents + $folders = @('licenses') + $folders | ForEach-Object { + New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null + Copy-Item -Path "./$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null + } - # copy general files - $files = @('src/Pode.psm1', 'src/Pode.psd1', 'src/Pode.Internal.psm1', 'src/Pode.Internal.psd1', 'LICENSE.txt') - $files | ForEach-Object { - Copy-Item -Path "./$($_)" -Destination $path -Force | Out-Null + # copy general files + $files = @('src/Pode.psm1', 'src/Pode.psd1', 'src/Pode.Internal.psm1', 'src/Pode.Internal.psd1', 'LICENSE.txt') + $files | ForEach-Object { + Copy-Item -Path "./$($_)" -Destination $path -Force | Out-Null + } } -} -<# + <# # Testing #> -# Synopsis: Run the tests -Task TestNoBuild TestDeps, { - $p = (Get-Command Invoke-Pester) - if ($null -eq $p -or $p.Version -ine $Versions.Pester) { - Remove-Module Pester -Force -ErrorAction Ignore - Import-Module Pester -Force -RequiredVersion $Versions.Pester - } - - # for windows, output current netsh excluded ports - if (Test-PodeBuildIsWindows) { - netsh int ipv4 show excludedportrange protocol=tcp | Out-Default - } - if ($UICulture -ne ([System.Threading.Thread]::CurrentThread.CurrentUICulture) ) { - $originalUICulture = [System.Threading.Thread]::CurrentThread.CurrentUICulture - Write-Output "Original UICulture is $originalUICulture" - Write-Output "Set UICulture to $UICulture" - # set new UICulture - [System.Threading.Thread]::CurrentThread.CurrentUICulture = $UICulture - } - $Script:TestResultFile = "$($pwd)/TestResults.xml" - - # get default from static property - $configuration = [PesterConfiguration]::Default - $configuration.run.path = @('./tests/unit', './tests/integration') - $configuration.run.PassThru = $true - $configuration.TestResult.OutputFormat = 'NUnitXml' - $configuration.Output.Verbosity = $PesterVerbosity - $configuration.TestResult.OutputPath = $Script:TestResultFile + # Synopsis: Run the tests + Task TestNoBuild TestDeps, { + $p = (Get-Command Invoke-Pester) + if ($null -eq $p -or $p.Version -ine $Versions.Pester) { + Remove-Module Pester -Force -ErrorAction Ignore + Import-Module Pester -Force -RequiredVersion $Versions.Pester + } - # if run code coverage if enabled - if (Test-PodeBuildCanCodeCoverage) { - $srcFiles = (Get-ChildItem "$($pwd)/src/*.ps1" -Recurse -Force).FullName - $configuration.CodeCoverage.Enabled = $true - $configuration.CodeCoverage.Path = $srcFiles - $Script:TestStatus = Invoke-Pester -Configuration $configuration - } - else { - $Script:TestStatus = Invoke-Pester -Configuration $configuration - } - if ($originalUICulture) { - Write-Output "Restore UICulture to $originalUICulture" - # restore original UICulture - [System.Threading.Thread]::CurrentThread.CurrentUICulture = $originalUICulture - } -}, PushCodeCoverage, CheckFailedTests + # for windows, output current netsh excluded ports + if (Test-PodeBuildIsWindows) { + netsh int ipv4 show excludedportrange protocol=tcp | Out-Default + } + if ($UICulture -ne ([System.Threading.Thread]::CurrentThread.CurrentUICulture) ) { + $originalUICulture = [System.Threading.Thread]::CurrentThread.CurrentUICulture + Write-Output "Original UICulture is $originalUICulture" + Write-Output "Set UICulture to $UICulture" + # set new UICulture + [System.Threading.Thread]::CurrentThread.CurrentUICulture = $UICulture + } + $Script:TestResultFile = "$($pwd)/TestResults.xml" + + # get default from static property + $configuration = [PesterConfiguration]::Default + $configuration.run.path = @('./tests/unit', './tests/integration') + $configuration.run.PassThru = $true + $configuration.TestResult.OutputFormat = 'NUnitXml' + $configuration.Output.Verbosity = $PesterVerbosity + $configuration.TestResult.OutputPath = $Script:TestResultFile + + # if run code coverage if enabled + if (Test-PodeBuildCanCodeCoverage) { + $srcFiles = (Get-ChildItem "$($pwd)/src/*.ps1" -Recurse -Force).FullName + $configuration.CodeCoverage.Enabled = $true + $configuration.CodeCoverage.Path = $srcFiles + $Script:TestStatus = Invoke-Pester -Configuration $configuration + } + else { + $Script:TestStatus = Invoke-Pester -Configuration $configuration + } + if ($originalUICulture) { + Write-Output "Restore UICulture to $originalUICulture" + # restore original UICulture + [System.Threading.Thread]::CurrentThread.CurrentUICulture = $originalUICulture + } + }, PushCodeCoverage, CheckFailedTests -# Synopsis: Run tests after a build -Task Test Build, TestNoBuild + # Synopsis: Run tests after a build + Task Test Build, TestNoBuild -# Synopsis: Check if any of the tests failed -Task CheckFailedTests { - if ($TestStatus.FailedCount -gt 0) { - throw "$($TestStatus.FailedCount) tests failed" + # Synopsis: Check if any of the tests failed + Task CheckFailedTests { + if ($TestStatus.FailedCount -gt 0) { + throw "$($TestStatus.FailedCount) tests failed" + } } -} -# Synopsis: If AppyVeyor or GitHub, push code coverage stats -Task PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { - try { - $service = Get-PodeBuildService - $branch = Get-PodeBuildBranch + # Synopsis: If AppyVeyor or GitHub, push code coverage stats + Task PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { + try { + $service = Get-PodeBuildService + $branch = Get-PodeBuildBranch - Write-Host "Pushing coverage for $($branch) from $($service)" - $coverage = New-CoverallsReport -Coverage $Script:TestStatus.CodeCoverage -ServiceName $service -BranchName $branch - Publish-CoverallsReport -Report $coverage -ApiToken $env:PODE_COVERALLS_TOKEN - } - catch { - $_.Exception | Out-Default + Write-Host "Pushing coverage for $($branch) from $($service)" + $coverage = New-CoverallsReport -Coverage $Script:TestStatus.CodeCoverage -ServiceName $service -BranchName $branch + Publish-CoverallsReport -Report $coverage -ApiToken $env:PODE_COVERALLS_TOKEN + } + catch { + $_.Exception | Out-Default + } } -} -<# + <# # Docs #> -# Synopsis: Run the documentation locally -Task Docs DocsDeps, DocsHelpBuild, { - mkdocs serve --open -} + # Synopsis: Run the documentation locally + Task Docs DocsDeps, DocsHelpBuild, { + mkdocs serve --open + } -# Synopsis: Build the function help documentation -Task DocsHelpBuild IndexSamples, DocsDeps, Build, { - # import the local module - Remove-Module Pode -Force -ErrorAction Ignore | Out-Null - Import-Module ./src/Pode.psm1 -Force | Out-Null + # Synopsis: Build the function help documentation + Task DocsHelpBuild IndexSamples, DocsDeps, Build, { + # import the local module + Remove-Module Pode -Force -ErrorAction Ignore | Out-Null + Import-Module ./src/Pode.psm1 -Force | Out-Null - # build the function docs - $path = './docs/Functions' - $map = @{} + # build the function docs + $path = './docs/Functions' + $map = @{} (Get-Module Pode).ExportedFunctions.Keys | ForEach-Object { - $type = [System.IO.Path]::GetFileNameWithoutExtension((Split-Path -Leaf -Path (Get-Command $_ -Module Pode).ScriptBlock.File)) - New-MarkdownHelp -Command $_ -OutputFolder (Join-Path $path $type) -Force -Metadata @{ PodeType = $type } -AlphabeticParamsOrder | Out-Null - $map[$_] = $type - } + $type = [System.IO.Path]::GetFileNameWithoutExtension((Split-Path -Leaf -Path (Get-Command $_ -Module Pode).ScriptBlock.File)) + New-MarkdownHelp -Command $_ -OutputFolder (Join-Path $path $type) -Force -Metadata @{ PodeType = $type } -AlphabeticParamsOrder | Out-Null + $map[$_] = $type + } - # update docs to bind links to unlinked functions - $path = Join-Path $pwd 'docs' - Get-ChildItem -Path $path -Recurse -Filter '*.md' | ForEach-Object { - $depth = ($_.FullName.Replace($path, [string]::Empty).trim('\/') -split '[\\/]').Length - $updated = $false + # update docs to bind links to unlinked functions + $path = Join-Path $pwd 'docs' + Get-ChildItem -Path $path -Recurse -Filter '*.md' | ForEach-Object { + $depth = ($_.FullName.Replace($path, [string]::Empty).trim('\/') -split '[\\/]').Length + $updated = $false - $content = (Get-Content -Path $_.FullName | ForEach-Object { - $line = $_ + $content = (Get-Content -Path $_.FullName | ForEach-Object { + $line = $_ - while ($line -imatch '\[`(?[a-z]+\-pode[a-z]+)`\](?([^(]|$))') { - $updated = $true - $name = $Matches['name'] - $char = $Matches['char'] - $line = ($line -ireplace "\[``$($name)``\]([^(]|$)", "[``$($name)``]($('../' * $depth)Functions/$($map[$name])/$($name))$($char)") - } + while ($line -imatch '\[`(?[a-z]+\-pode[a-z]+)`\](?([^(]|$))') { + $updated = $true + $name = $Matches['name'] + $char = $Matches['char'] + $line = ($line -ireplace "\[``$($name)``\]([^(]|$)", "[``$($name)``]($('../' * $depth)Functions/$($map[$name])/$($name))$($char)") + } - $line - }) + $line + }) - if ($updated) { - $content | Out-File -FilePath $_.FullName -Force -Encoding ascii + if ($updated) { + $content | Out-File -FilePath $_.FullName -Force -Encoding ascii + } } - } - # remove the module - Remove-Module Pode -Force -ErrorAction Ignore | Out-Null -} + # remove the module + Remove-Module Pode -Force -ErrorAction Ignore | Out-Null + } -# Synopsis: Build the documentation -Task DocsBuild DocsDeps, DocsHelpBuild, { - mkdocs build --quiet -} + # Synopsis: Build the documentation + Task DocsBuild DocsDeps, DocsHelpBuild, { + mkdocs build --quiet + } -<# + <# # Clean-up #> -# Synopsis: Clean the build enviroment -Task Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs + # Synopsis: Clean the build enviroment + Task Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs -# Synopsis: Clean the Deliverable folder -Task CleanDeliverable { - $path = './deliverable' - if (Test-Path -Path $path -PathType Container) { - Write-Host 'Removing ./deliverable folder' - Remove-Item -Path $path -Recurse -Force | Out-Null + # Synopsis: Clean the Deliverable folder + Task CleanDeliverable { + $path = './deliverable' + if (Test-Path -Path $path -PathType Container) { + Write-Host 'Removing ./deliverable folder' + Remove-Item -Path $path -Recurse -Force | Out-Null + } + Write-Host "Cleanup $path done" } - Write-Host "Cleanup $path done" -} -# Synopsis: Clean the pkg directory -Task CleanPkg { - $path = './pkg' - if ((Test-Path -Path $path -PathType Container )) { - Write-Host 'Removing ./pkg folder' - Remove-Item -Path $path -Recurse -Force | Out-Null - } + # Synopsis: Clean the pkg directory + Task CleanPkg { + $path = './pkg' + if ((Test-Path -Path $path -PathType Container )) { + Write-Host 'Removing ./pkg folder' + Remove-Item -Path $path -Recurse -Force | Out-Null + } - if ((Test-Path -Path .\packers\choco\tools\ChocolateyInstall.ps1 -PathType Leaf )) { - Write-Host 'Removing .\packers\choco\tools\ChocolateyInstall.ps1' - Remove-Item -Path .\packers\choco\tools\ChocolateyInstall.ps1 - } + if ((Test-Path -Path .\packers\choco\tools\ChocolateyInstall.ps1 -PathType Leaf )) { + Write-Host 'Removing .\packers\choco\tools\ChocolateyInstall.ps1' + Remove-Item -Path .\packers\choco\tools\ChocolateyInstall.ps1 + } - if ((Test-Path -Path .\packers\choco\pode.nuspec -PathType Leaf )) { - Write-Host 'Removing .\packers\choco\pode.nuspec' - Remove-Item -Path .\packers\choco\pode.nuspec + if ((Test-Path -Path .\packers\choco\pode.nuspec -PathType Leaf )) { + Write-Host 'Removing .\packers\choco\pode.nuspec' + Remove-Item -Path .\packers\choco\pode.nuspec + } + + Write-Host "Cleanup $path done" } - Write-Host "Cleanup $path done" -} + # Synopsis: Clean the libs folder + Task CleanLibs { + $path = './src/Libs' + if (Test-Path -Path $path -PathType Container) { + Write-Host "Removing $path contents" + Remove-Item -Path $path -Recurse -Force | Out-Null + } -# Synopsis: Clean the libs folder -Task CleanLibs { - $path = './src/Libs' - if (Test-Path -Path $path -PathType Container) { - Write-Host "Removing $path contents" - Remove-Item -Path $path -Recurse -Force | Out-Null + Write-Host "Cleanup $path done" } - Write-Host "Cleanup $path done" -} + # Synopsis: Clean the Listener folder + Task CleanListener { + $path = './src/Listener/bin' + if (Test-Path -Path $path -PathType Container) { + Write-Host "Removing $path contents" + Remove-Item -Path $path -Recurse -Force | Out-Null + } -# Synopsis: Clean the Listener folder -Task CleanListener { - $path = './src/Listener/bin' - if (Test-Path -Path $path -PathType Container) { - Write-Host "Removing $path contents" - Remove-Item -Path $path -Recurse -Force | Out-Null + Write-Host "Cleanup $path done" } - Write-Host "Cleanup $path done" -} - -Task CleanDocs { - $path = './docs/Getting-Started/Samples.md' - if (Test-Path -Path $path -PathType Leaf) { - Write-Host "Removing $path" - Remove-Item -Path $path -Force | Out-Null + Task CleanDocs { + $path = './docs/Getting-Started/Samples.md' + if (Test-Path -Path $path -PathType Leaf) { + Write-Host "Removing $path" + Remove-Item -Path $path -Force | Out-Null + } } -} -<# + <# # Local module management #> -# Synopsis: Install Pode Module locally -Task Install-Module -If ($Version) Pack, { - $PSPaths = Split-PodeBuildPwshPath + # Synopsis: Install Pode Module locally + Task Install-Module -If ($Version) Pack, { + $PSPaths = Split-PodeBuildPwshPath - $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" - if (Test-Path $dest) { - Remove-Item -Path $dest -Recurse -Force | Out-Null - } + $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" + if (Test-Path $dest) { + Remove-Item -Path $dest -Recurse -Force | Out-Null + } - # create the dest dir - New-Item -Path $dest -ItemType Directory -Force | Out-Null - $path = './pkg' + # create the dest dir + New-Item -Path $dest -ItemType Directory -Force | Out-Null + $path = './pkg' - # copy over folders - $folders = @('Private', 'Public', 'Misc', 'Libs', 'licenses', 'Locales') - $folders | ForEach-Object { - Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force -Recurse | Out-Null - } + # copy over folders + $folders = @('Private', 'Public', 'Misc', 'Libs', 'licenses', 'Locales') + $folders | ForEach-Object { + Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force -Recurse | Out-Null + } - # copy over general files - $files = @('Pode.psm1', 'Pode.psd1', 'Pode.Internal.psm1', 'Pode.Internal.psd1', 'LICENSE.txt') - $files | ForEach-Object { - Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force | Out-Null + # copy over general files + $files = @('Pode.psm1', 'Pode.psd1', 'Pode.Internal.psm1', 'Pode.Internal.psd1', 'LICENSE.txt') + $files | ForEach-Object { + Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force | Out-Null + } + + Write-Host "Deployed to $dest" } - Write-Host "Deployed to $dest" -} + # Synopsis: Remove the Pode Module from the local registry + Task Remove-Module { + if (!$Version) { + throw 'Parameter -Version is required' + } -# Synopsis: Remove the Pode Module from the local registry -Task Remove-Module { - if (!$Version) { - throw 'Parameter -Version is required' - } + $PSPaths = Split-PodeBuildPwshPath - $PSPaths = Split-PodeBuildPwshPath + $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" + if (!(Test-Path $dest)) { + Write-Warning "Directory $dest doesn't exist" + } - $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" - if (!(Test-Path $dest)) { - Write-Warning "Directory $dest doesn't exist" + Write-Host "Deleting module from $dest" + Remove-Item -Path $dest -Recurse -Force | Out-Null } - Write-Host "Deleting module from $dest" - Remove-Item -Path $dest -Recurse -Force | Out-Null -} - -<# + <# # PowerShell setup #> -# Synopsis: Setup the PowerShell environment -Task SetupPowerShell { - # code for this step is altered versions of the code found here: - # - https://github.com/bjompen/UpdatePWSHAction/blob/main/UpgradePwsh.ps1 - # - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 + # Synopsis: Setup the PowerShell environment + Task SetupPowerShell { + # code for this step is altered versions of the code found here: + # - https://github.com/bjompen/UpdatePWSHAction/blob/main/UpgradePwsh.ps1 + # - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 - # fail if no version supplied - if ([string]::IsNullOrWhiteSpace($PowerShellVersion)) { - throw 'No PowerShell version supplied to set up' - } + # fail if no version supplied + if ([string]::IsNullOrWhiteSpace($PowerShellVersion)) { + throw 'No PowerShell version supplied to set up' + } - # is the version valid? - $tags = @('preview', 'lts', 'daily', 'stable') - if (($PowerShellVersion -inotin $tags) -and ($PowerShellVersion -inotmatch '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$')) { - throw "Invalid PowerShell version supplied: $($PowerShellVersion)" - } + # is the version valid? + $tags = @('preview', 'lts', 'daily', 'stable') + if (($PowerShellVersion -inotin $tags) -and ($PowerShellVersion -inotmatch '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$')) { + throw "Invalid PowerShell version supplied: $($PowerShellVersion)" + } - # tag version or literal version? - $isTagVersion = $PowerShellVersion -iin $tags - if ($isTagVersion) { - Write-Host "Release tag: $($PowerShellVersion)" - $PowerShellVersion = Convert-PodeBuildOSPwshTagToVersion - } - Write-Host "Release version: $($PowerShellVersion)" + # tag version or literal version? + $isTagVersion = $PowerShellVersion -iin $tags + if ($isTagVersion) { + Write-Host "Release tag: $($PowerShellVersion)" + $PowerShellVersion = Convert-PodeBuildOSPwshTagToVersion + } + Write-Host "Release version: $($PowerShellVersion)" - # base/prefix versions - $atoms = $PowerShellVersion -split '\-' - $baseVersion = $atoms[0] + # base/prefix versions + $atoms = $PowerShellVersion -split '\-' + $baseVersion = $atoms[0] - # do nothing if the current version is the version we're trying to set up - $currentVersion = Get-PodeBuildCurrentPwshVersion - Write-Host "Current PowerShell version: $($currentVersion)" + # do nothing if the current version is the version we're trying to set up + $currentVersion = Get-PodeBuildCurrentPwshVersion + Write-Host "Current PowerShell version: $($currentVersion)" - if ($baseVersion -ieq $currentVersion) { - Write-Host "PowerShell version $($PowerShellVersion) is already installed" - return - } + if ($baseVersion -ieq $currentVersion) { + Write-Host "PowerShell version $($PowerShellVersion) is already installed" + return + } - # build the package name - $arch = Get-PodeBuildOSPwshArchitecture - $os = Get-PodeBuildOSPwshName + # build the package name + $arch = Get-PodeBuildOSPwshArchitecture + $os = Get-PodeBuildOSPwshName - $packageName = (@{ - win = "PowerShell-$($PowerShellVersion)-$($os)-$($arch).zip" - linux = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" - osx = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" - })[$os] + $packageName = (@{ + win = "PowerShell-$($PowerShellVersion)-$($os)-$($arch).zip" + linux = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" + osx = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" + })[$os] - # build the URL - $urls = @{ - Old = "https://pscoretestdata.blob.core.windows.net/v$($PowerShellVersion -replace '\.', '-')/$($packageName)" - New = "https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install/v$($PowerShellVersion)/$($packageName)" - } + # build the URL + $urls = @{ + Old = "https://pscoretestdata.blob.core.windows.net/v$($PowerShellVersion -replace '\.', '-')/$($packageName)" + New = "https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install/v$($PowerShellVersion)/$($packageName)" + } - # download the package to a temp location - $outputFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $packageName - $downloadParams = @{ - Uri = $urls.New - OutFile = $outputFile - ErrorAction = 'Stop' - } + # download the package to a temp location + $outputFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $packageName + $downloadParams = @{ + Uri = $urls.New + OutFile = $outputFile + ErrorAction = 'Stop' + } - Write-Host "Output file: $($outputFile)" + Write-Host "Output file: $($outputFile)" - # retry the download 6 times, with a sleep of 10s between each attempt, and altering between old and new URLs - $counter = 0 - $success = $false + # retry the download 6 times, with a sleep of 10s between each attempt, and altering between old and new URLs + $counter = 0 + $success = $false - do { - try { - $counter++ - Write-Host "Attempt $($counter) of 6" + do { + try { + $counter++ + Write-Host "Attempt $($counter) of 6" - # use new URL for odd attempts, and old URL for even attempts - if ($counter % 2 -eq 0) { - $downloadParams.Uri = $urls.Old - } - else { - $downloadParams.Uri = $urls.New - } + # use new URL for odd attempts, and old URL for even attempts + if ($counter % 2 -eq 0) { + $downloadParams.Uri = $urls.Old + } + else { + $downloadParams.Uri = $urls.New + } - # download the package - Write-Host "Attempting download of $($packageName) from $($downloadParams.Uri)" - Invoke-WebRequest @downloadParams + # download the package + Write-Host "Attempting download of $($packageName) from $($downloadParams.Uri)" + Invoke-WebRequest @downloadParams - $success = $true - Write-Host "Downloaded $($packageName) successfully" - } - catch { - $success = $false - if ($counter -ge 6) { - throw "Failed to download PowerShell package after 6 attempts. Error: $($_.Exception.Message)" + $success = $true + Write-Host "Downloaded $($packageName) successfully" + } + catch { + $success = $false + if ($counter -ge 6) { + throw "Failed to download PowerShell package after 6 attempts. Error: $($_.Exception.Message)" + } + + Start-Sleep -Seconds 5 } + } while (!$success) - Start-Sleep -Seconds 5 + # create target folder for package + $targetFolder = Join-Path -Path (Resolve-Path ~).Path -ChildPath ($packageName -ireplace '\.tar$') + if (!(Test-Path $targetFolder)) { + $null = New-Item -Path $targetFolder -ItemType Directory -Force } - } while (!$success) - # create target folder for package - $targetFolder = Join-Path -Path (Resolve-Path ~).Path -ChildPath ($packageName -ireplace '\.tar$') - if (!(Test-Path $targetFolder)) { - $null = New-Item -Path $targetFolder -ItemType Directory -Force - } + # extract the package + switch ($os) { + 'win' { + Expand-Archive -Path $outputFile -DestinationPath $targetFolder -Force + } - # extract the package - switch ($os) { - 'win' { - Expand-Archive -Path $outputFile -DestinationPath $targetFolder -Force + { $_ -iin 'linux', 'osx' } { + $null = tar -xzf $outputFile -C $targetFolder + } } - { $_ -iin 'linux', 'osx' } { - $null = tar -xzf $outputFile -C $targetFolder + # install the package + Write-Host "Installing PowerShell $($PowerShellVersion) to $($targetFolder)" + if (Test-PodeBuildOSWindows) { + Install-PodeBuildPwshWindows -Target $targetFolder + } + else { + Install-PodeBuildPwshUnix -Target $targetFolder } } - # install the package - Write-Host "Installing PowerShell $($PowerShellVersion) to $($targetFolder)" - if (Test-PodeBuildOSWindows) { - Install-PodeBuildPwshWindows -Target $targetFolder - } - else { - Install-PodeBuildPwshUnix -Target $targetFolder - } -} - -<# + <# # Release Notes #> -# Synopsis: Build the Release Notes -task ReleaseNotes { - if ([string]::IsNullOrWhiteSpace($ReleaseNoteVersion)) { - Write-Host 'Please provide a ReleaseNoteVersion' -ForegroundColor Red - return - } + # Synopsis: Build the Release Notes + task ReleaseNotes { + if ([string]::IsNullOrWhiteSpace($ReleaseNoteVersion)) { + Write-Host 'Please provide a ReleaseNoteVersion' -ForegroundColor Red + return + } - # get the PRs for the ReleaseNoteVersion - $prs = gh search prs --milestone $ReleaseNoteVersion --repo badgerati/pode --merged --limit 200 --json 'number,title,labels,author' | ConvertFrom-Json + # get the PRs for the ReleaseNoteVersion + $prs = gh search prs --milestone $ReleaseNoteVersion --repo badgerati/pode --merged --limit 200 --json 'number,title,labels,author' | ConvertFrom-Json - # group PRs into categories, filtering out some internal PRs - $categories = [ordered]@{ - Features = @() - Enhancements = @() - Bugs = @() - Documentation = @() - } + # group PRs into categories, filtering out some internal PRs + $categories = [ordered]@{ + Features = @() + Enhancements = @() + Bugs = @() + Documentation = @() + } - $dependabot = @{} + $dependabot = @{} - foreach ($pr in $prs) { - if ($pr.labels.name -icontains 'superseded') { - continue - } + foreach ($pr in $prs) { + if ($pr.labels.name -icontains 'superseded') { + continue + } - $label = ($pr.labels[0].name -split ' ')[0] - if ($label -iin @('new-release', 'internal-code')) { - continue - } + $label = ($pr.labels[0].name -split ' ')[0] + if ($label -iin @('new-release', 'internal-code')) { + continue + } - if ([string]::IsNullOrWhiteSpace($label)) { - $label = 'misc' - } + if ([string]::IsNullOrWhiteSpace($label)) { + $label = 'misc' + } - switch ($label.ToLowerInvariant()) { - 'feature' { $label = 'Features' } - 'enhancement' { $label = 'Enhancements' } - 'bug' { $label = 'Bugs' } - } + switch ($label.ToLowerInvariant()) { + 'feature' { $label = 'Features' } + 'enhancement' { $label = 'Enhancements' } + 'bug' { $label = 'Bugs' } + } - if (!$categories.Contains($label)) { - $categories[$label] = @() - } + if (!$categories.Contains($label)) { + $categories[$label] = @() + } - if ($pr.author.login -ilike '*dependabot*') { - if ($pr.title -imatch 'Bump (?\S+) from (?[0-9\.]+) to (?[0-9\.]+)') { - if (!$dependabot.ContainsKey($Matches['name'])) { - $dependabot[$Matches['name']] = @{ - Name = $Matches['name'] - Number = $pr.number - From = [version]$Matches['from'] - To = [version]$Matches['to'] - } - } - else { - $item = $dependabot[$Matches['name']] - if ([int]$pr.number -gt [int]$item.Number) { - $item.Number = $pr.number - } - if ([version]$Matches['from'] -lt $item.From) { - $item.From = [version]$Matches['from'] + if ($pr.author.login -ilike '*dependabot*') { + if ($pr.title -imatch 'Bump (?\S+) from (?[0-9\.]+) to (?[0-9\.]+)') { + if (!$dependabot.ContainsKey($Matches['name'])) { + $dependabot[$Matches['name']] = @{ + Name = $Matches['name'] + Number = $pr.number + From = [version]$Matches['from'] + To = [version]$Matches['to'] + } } - if ([version]$Matches['to'] -gt $item.To) { - $item.To = [version]$Matches['to'] + else { + $item = $dependabot[$Matches['name']] + if ([int]$pr.number -gt [int]$item.Number) { + $item.Number = $pr.number + } + if ([version]$Matches['from'] -lt $item.From) { + $item.From = [version]$Matches['from'] + } + if ([version]$Matches['to'] -gt $item.To) { + $item.To = [version]$Matches['to'] + } } + + continue } + } - continue + $titles = @($pr.title).Trim() + if ($pr.title.Contains(';')) { + $titles = ($pr.title -split ';').Trim() } - } - $titles = @($pr.title).Trim() - if ($pr.title.Contains(';')) { - $titles = ($pr.title -split ';').Trim() - } + $author = $null + if (($pr.author.login -ine 'badgerati') -and ($pr.author.login -inotlike '*dependabot*')) { + $author = $pr.author.login + } - $author = $null - if (($pr.author.login -ine 'badgerati') -and ($pr.author.login -inotlike '*dependabot*')) { - $author = $pr.author.login - } + foreach ($title in $titles) { + $str = "* #$($pr.number): $($title -replace '`', "'")" + if (![string]::IsNullOrWhiteSpace($author)) { + $str += " (thanks @$($author)!)" + } - foreach ($title in $titles) { - $str = "* #$($pr.number): $($title -replace '`', "'")" - if (![string]::IsNullOrWhiteSpace($author)) { - $str += " (thanks @$($author)!)" + if ($str -imatch '\s+(docs|documentation)\s+') { + $categories['Documentation'] += $str + } + else { + $categories[$label] += $str + } } + } - if ($str -imatch '\s+(docs|documentation)\s+') { - $categories['Documentation'] += $str - } - else { - $categories[$label] += $str + # add dependabot aggregated PRs + if ($dependabot.Count -gt 0) { + $label = 'dependencies' + if (!$categories.Contains($label)) { + $categories[$label] = @() } - } - } - # add dependabot aggregated PRs - if ($dependabot.Count -gt 0) { - $label = 'dependencies' - if (!$categories.Contains($label)) { - $categories[$label] = @() + foreach ($dep in $dependabot.Values) { + $categories[$label] += "* #$($dep.Number): Bump $($dep.Name) from $($dep.From) to $($dep.To)" + } } - foreach ($dep in $dependabot.Values) { - $categories[$label] += "* #$($dep.Number): Bump $($dep.Name) from $($dep.From) to $($dep.To)" - } - } + # output the release notes + Write-Host "# v$($ReleaseNoteVersion)`n" - # output the release notes - Write-Host "# v$($ReleaseNoteVersion)`n" + $culture = (Get-Culture).TextInfo + foreach ($category in $categories.Keys) { + if ($categories[$category].Length -eq 0) { + continue + } - $culture = (Get-Culture).TextInfo - foreach ($category in $categories.Keys) { - if ($categories[$category].Length -eq 0) { - continue + Write-Host "### $($culture.ToTitleCase($category))" + $categories[$category] | Sort-Object | ForEach-Object { Write-Host $_ } + Write-Host '' } - - Write-Host "### $($culture.ToTitleCase($category))" - $categories[$category] | Sort-Object | ForEach-Object { Write-Host $_ } - Write-Host '' } +} +else { + Write-Host 'This script is intended to be run with Invoke-Build. Please use Invoke-Build to execute the tasks defined in this script.' -ForegroundColor Yellow } \ No newline at end of file diff --git a/src/Listener/Pode.csproj b/src/Listener/Pode.csproj index 3932c1dc7..45760ac6e 100644 --- a/src/Listener/Pode.csproj +++ b/src/Listener/Pode.csproj @@ -1,6 +1,6 @@ - netstandard2.0;net6.0;net8.0 + netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0; $(NoWarn);SYSLIB0001 7.3 From e60e93d2d1bf92a4db19776da285fba4866ca7ee Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 10:09:44 -0800 Subject: [PATCH 02/23] fix github issue --- .github/workflows/ci-powershell.yml | 2 +- .github/workflows/ci-pwsh7_2.yml | 2 +- .github/workflows/ci-pwsh_lts.yml | 2 +- .github/workflows/ci-pwsh_preview.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-powershell.yml b/.github/workflows/ci-powershell.yml index c3cf4b313..d02acd9aa 100644 --- a/.github/workflows/ci-powershell.yml +++ b/.github/workflows/ci-powershell.yml @@ -40,7 +40,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 'latest' # Automatically picks the latest available .NET SDK - name: Install Invoke-Build shell: powershell diff --git a/.github/workflows/ci-pwsh7_2.yml b/.github/workflows/ci-pwsh7_2.yml index 468043c36..c5c0cb357 100644 --- a/.github/workflows/ci-pwsh7_2.yml +++ b/.github/workflows/ci-pwsh7_2.yml @@ -42,7 +42,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 'latest' # Automatically picks the latest available .NET SDK - name: Setup Powershell - Unix shell: pwsh diff --git a/.github/workflows/ci-pwsh_lts.yml b/.github/workflows/ci-pwsh_lts.yml index c0fa8a682..0cb4336d9 100644 --- a/.github/workflows/ci-pwsh_lts.yml +++ b/.github/workflows/ci-pwsh_lts.yml @@ -42,7 +42,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 'latest' # Automatically picks the latest available .NET SDK - name: Setup Powershell - Unix shell: pwsh diff --git a/.github/workflows/ci-pwsh_preview.yml b/.github/workflows/ci-pwsh_preview.yml index 81bb80c3d..977c19c57 100644 --- a/.github/workflows/ci-pwsh_preview.yml +++ b/.github/workflows/ci-pwsh_preview.yml @@ -42,7 +42,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 'latest' # Automatically picks the latest available .NET SDK - name: Setup Powershell - Unix shell: pwsh From 359c408224187d8bdb1a29495b19260528f7f526 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 10:12:34 -0800 Subject: [PATCH 03/23] latest is not supported rollback to 9.x --- .github/workflows/ci-powershell.yml | 2 +- .github/workflows/ci-pwsh7_2.yml | 2 +- .github/workflows/ci-pwsh_lts.yml | 2 +- .github/workflows/ci-pwsh_preview.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-powershell.yml b/.github/workflows/ci-powershell.yml index d02acd9aa..1b071fe4a 100644 --- a/.github/workflows/ci-powershell.yml +++ b/.github/workflows/ci-powershell.yml @@ -40,7 +40,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 'latest' # Automatically picks the latest available .NET SDK + dotnet-version: 9.x - name: Install Invoke-Build shell: powershell diff --git a/.github/workflows/ci-pwsh7_2.yml b/.github/workflows/ci-pwsh7_2.yml index c5c0cb357..8d37e5af5 100644 --- a/.github/workflows/ci-pwsh7_2.yml +++ b/.github/workflows/ci-pwsh7_2.yml @@ -42,7 +42,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 'latest' # Automatically picks the latest available .NET SDK + dotnet-version: 9.x - name: Setup Powershell - Unix shell: pwsh diff --git a/.github/workflows/ci-pwsh_lts.yml b/.github/workflows/ci-pwsh_lts.yml index 0cb4336d9..29a74a2df 100644 --- a/.github/workflows/ci-pwsh_lts.yml +++ b/.github/workflows/ci-pwsh_lts.yml @@ -42,7 +42,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 'latest' # Automatically picks the latest available .NET SDK + dotnet-version: 9.x - name: Setup Powershell - Unix shell: pwsh diff --git a/.github/workflows/ci-pwsh_preview.yml b/.github/workflows/ci-pwsh_preview.yml index 977c19c57..6abca6cde 100644 --- a/.github/workflows/ci-pwsh_preview.yml +++ b/.github/workflows/ci-pwsh_preview.yml @@ -42,7 +42,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 'latest' # Automatically picks the latest available .NET SDK + dotnet-version: 9.x - name: Setup Powershell - Unix shell: pwsh From 02c5731308d81e2ea387a02c41336afd69fe32e1 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 10:15:42 -0800 Subject: [PATCH 04/23] Update ci-coverage.yml --- .github/workflows/ci-coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index 0841de82c..8847cfab6 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -37,7 +37,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.x - name: Install Invoke-Build shell: pwsh From 7790c7d664c88a467e126a0ca31d0afb67554ca4 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 10:32:22 -0800 Subject: [PATCH 05/23] Update pode.build.ps1 --- pode.build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index eea1b6799..187612895 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -703,7 +703,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Build the function help documentation - Task DocsHelpBuild IndexSamples, DocsDeps, Build, { + Task DocsHelpBuild IndexSamples, DocsDeps, { # import the local module Remove-Module Pode -Force -ErrorAction Ignore | Out-Null Import-Module ./src/Pode.psm1 -Force | Out-Null From 0377351a1240f38228fd158c40cb0f6ad79774c7 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 10:38:52 -0800 Subject: [PATCH 06/23] fix doc build --- .github/workflows/ci-docs.yml | 5 +++++ pode.build.ps1 | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index d88abaa84..dc2aaf2b1 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -36,6 +36,11 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.x + - name: Install Invoke-Build shell: pwsh run: | diff --git a/pode.build.ps1 b/pode.build.ps1 index 187612895..eea1b6799 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -703,7 +703,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Build the function help documentation - Task DocsHelpBuild IndexSamples, DocsDeps, { + Task DocsHelpBuild IndexSamples, DocsDeps, Build, { # import the local module Remove-Module Pode -Force -ErrorAction Ignore | Out-Null Import-Module ./src/Pode.psm1 -Force | Out-Null From 9a4615fe07869bd1ed2e03d7bab8e0fe9933a9d1 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 13 Nov 2024 15:16:19 -0800 Subject: [PATCH 07/23] improvements --- pode.build.ps1 | 23 ++++++++++++++++++----- src/Listener/Pode.csproj | 30 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index eea1b6799..459dd6cb6 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -32,7 +32,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet MkDocs = '1.6.1' PSCoveralls = '1.0.0' SevenZip = '18.5.0.20180730' - DotNet = '9.0' + DotNet = 'auto' MkDocsTheme = '9.5.44' PlatyPS = '0.14.2' } @@ -213,12 +213,21 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet function Get-PodeBuildDotNetEOL { + param( + [switch] + $LastVersion + ) $uri = 'https://endoflife.date/api/dotnet.json' try { $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } - return @{ - eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' - supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' + if ($LastVersion) { + return (($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle)[0] + } + else { + return @{ + eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' + supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' + } } } catch { @@ -384,6 +393,10 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet # Synopsis: Install dependencies for compiling/building Task BuildDeps { + if ($Versions.DotNet -eq 'auto') { + $Versions.DotNet = Get-PodeBuildDotNetEOL -LastVersion + } + # install dotnet if (Test-PodeBuildIsWindows) { $dotnet = 'dotnet' @@ -502,7 +515,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet foreach ($target in $targetFrameworks) { Invoke-PodeBuildDotnetBuild -target $target Write-Host - Write-Host "***********************" -ForegroundColor DarkMagenta + Write-Host '***********************' -ForegroundColor DarkMagenta } } diff --git a/src/Listener/Pode.csproj b/src/Listener/Pode.csproj index 45760ac6e..0505565c6 100644 --- a/src/Listener/Pode.csproj +++ b/src/Listener/Pode.csproj @@ -1,7 +1,35 @@ - netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0; + netstandard2.0;netstandard2.1 $(NoWarn);SYSLIB0001 7.3 + + + $(TargetFrameworks);netcoreapp3.1 + + + + $(TargetFrameworks);net5.0 + + + + $(TargetFrameworks);net6.0 + + + + $(TargetFrameworks);net7.0 + + + + $(TargetFrameworks);net8.0 + + + + $(TargetFrameworks);net9.0 + + + + $(TargetFrameworks);net10.0 + From d0d8687a1fc450fc18bfa34e5dc8ad48512e42b5 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 08:08:37 -0800 Subject: [PATCH 08/23] Update pode.build.ps1 --- pode.build.ps1 | 259 ++++++++++++++++++++++++++++--------------------- 1 file changed, 150 insertions(+), 109 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 459dd6cb6..b1c9915a1 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -19,7 +19,15 @@ param( $ReleaseNoteVersion, [string] - $UICulture = 'en-US' + $UICulture = 'en-US', + + [string[]] + [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] + $TargetFrameworks, + + [string] + [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] + $SdkVersion ) @@ -32,15 +40,12 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet MkDocs = '1.6.1' PSCoveralls = '1.0.0' SevenZip = '18.5.0.20180730' - DotNet = 'auto' + DotNet = @($(if ($null -eq $TargetFrameworks) { 'auto' } else { $TargetFrameworks })) MkDocsTheme = '9.5.44' PlatyPS = '0.14.2' } - $NetVersions = 'netstandard2.0', 'netstandard2.1', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0' - #Unsupported .NET Framework version 'net4.0', 'net4.5', 'net4.5.1', 'net4.5.2', 'net4.6', 'net4.6.1', 'net4.6.2', 'net4.7', 'net4.7.1', 'net4.7.2', 'net4.8' - # Helper Functions function Test-PodeBuildIsWindows { $v = $PSVersionTable @@ -107,86 +112,92 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet Install-Module -Name "$($name)" -Scope CurrentUser -RequiredVersion "$($Versions[$name])" -Force -SkipPublisherCheck } + function Get-TargetFramework { + param( + [string] + $TargetFrameworks + ) + + switch ($TargetFrameworks) { + 'netstandard2.0' { return 2 } + 'netstandard2.1' { return 3 } + 'netcoreapp3.0' { return 3 } + 'net5.0' { return 5 } + 'net6.0' { return 6 } + 'net7.0' { return 7 } + 'net8.0' { return 8 } + 'net9.0' { return 9 } + default { + Write-Warning "$TargetFrameworks is not a valid Framework. Rollback to netstandard2.0" + return 2 + } + } + } + + + function Get-TargetFrameworkName { + param( + $Version + ) + + switch ( $Version) { + '2' { return 'netstandard2.0' } + '3' { return 'netstandard2.1' } + '5' { return 'net5.0' } + '6' { return 'net6.0' } + '7' { return 'net7.0' } + '8' { return 'net8.0' } + '9' { return 'net9.0' } + default { + Write-Warning "$Version is not a valid Framework. Rollback to netstandard2.0" + return 'netstandard2.0' + } + } + } + function Invoke-PodeBuildDotnetBuild { param ( [string]$target ) - # Verify if the target is a known .NET version - if ($target -notin $NetVersions) { - Write-Host "Unknown target framework '$target'. Please specify a valid .NET framework." - return - } - # Retrieve the installed SDK versions $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique - + if ([string]::IsNullOrEmpty($AvailableSdkVersion)) { + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + } + else { + $majorVersions = $sdkVersions.Where( { ([version]$_).Major -ge (Get-TargetFramework -TargetFrameworks $AvailableSdkVersion) } ) | Sort-Object -Descending | Select-Object -Unique + } # Map target frameworks to minimum SDK versions - $targetSdkMap = @{ - 'netstandard2.0' = 2 - 'netstandard2.1' = 3 - 'netcoreapp3.1' = 3 - 'net5.0' = 5 - 'net6.0' = 6 - 'net7.0' = 7 - 'net8.0' = 8 - 'net9.0' = 9 + + if ($null -eq $majorVersions) { + Write-Error "The requested '$AvailableSdkVersion' framework is not available." + return } + $requiredSdkVersion = Get-TargetFramework -TargetFrameworks $target # Determine if the target framework is compatible - $isCompatible = $False - - if ($targetSdkMap.ContainsKey($target)) { - $requiredSdkVersion = $targetSdkMap[$target] - - foreach ($sdkVersion in $sdkVersions) { - $sdkMajor = ([version]$sdkVersion).Major - if ($sdkMajor -ge $requiredSdkVersion) { - $isCompatible = $True - break - } - } - } - elseif ($target -like 'net4*') { - # .NET Framework targets require MSBuild, typically available with Visual Studio - $msbuildPath = Get-Command msbuild -ErrorAction SilentlyContinue - if ($msbuildPath) { - $isCompatible = $True - } - else { - Write-Host 'MSBuild is not available. Cannot build .NET Framework targets.' - return - } - } + $isCompatible = $majorVersions -ge $requiredSdkVersion if ($isCompatible) { - Write-Host "SDK for target framework '$target' is compatible with the installed SDKs." + Write-Output "SDK for target framework '$target' is compatible with the '$AvailableSdkVersion' framework." } else { - Write-Host "SDK for target framework '$target' is not compatible with the installed SDKs. Skipping build." + Write-Warning "SDK for target framework '$target' is not compatible with the '$AvailableSdkVersion' framework. Skipping build." return } # Optionally set assembly version if ($Version) { - Write-Host "Assembly Version: $Version" + Write-Output "Assembly Version: $Version" $AssemblyVersion = "-p:Version=$Version" } else { $AssemblyVersion = '' } - # Execute dotnet publish or MSBuild depending on the target - if ($target -like 'net4*') { - # Use MSBuild for .NET Framework targets - $projectFile = 'YourProject.csproj' # Replace with your actual project file - & msbuild $projectFile /p:Configuration=Release /p:TargetFramework=$target $AssemblyVersion /p:OutputPath="../Libs/$target" - } - else { - # Use dotnet publish for .NET Core and .NET 5+ - dotnet publish --configuration Release --self-contained --framework $target $AssemblyVersion --output ../Libs/$target - } + # Use dotnet publish for .NET Core and .NET 5+ + dotnet publish --configuration Release --self-contained --framework $target $AssemblyVersion --output ../Libs/$target if (!$?) { throw "Build failed for target framework '$target'." @@ -215,12 +226,12 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet function Get-PodeBuildDotNetEOL { param( [switch] - $LastVersion + $LatestVersion ) $uri = 'https://endoflife.date/api/dotnet.json' try { $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } - if ($LastVersion) { + if ($LatestVersion) { return (($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle)[0] } else { @@ -357,7 +368,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Stamps the version onto the Module - Task StampVersion { + Add-BuildTask StampVersion { $pwshVersions = Get-PodeBuildPwshEOL (Get-Content ./pkg/Pode.psd1) | ForEach-Object { $_ -replace '\$version\$', $Version -replace '\$versionsUntested\$', $pwshVersions.eol -replace '\$versionsSupported\$', $pwshVersions.supported -replace '\$buildyear\$', ((get-date).Year) } | Set-Content ./pkg/Pode.psd1 (Get-Content ./pkg/Pode.Internal.psd1) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./pkg/Pode.Internal.psd1 @@ -366,7 +377,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Generating a Checksum of the Zip - Task PrintChecksum { + Add-BuildTask PrintChecksum { $Script:Checksum = (Get-FileHash "./deliverable/$Version-Binaries.zip" -Algorithm SHA256).Hash Write-Host "Checksum: $($Checksum)" } @@ -377,7 +388,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Installs Chocolatey - Task ChocoDeps -If (Test-PodeBuildIsWindows) { + Add-BuildTask ChocoDeps -If (Test-PodeBuildIsWindows) { if (!(Test-PodeBuildCommand 'choco')) { Set-ExecutionPolicy Bypass -Scope Process -Force Invoke-Expression ([System.Net.WebClient]::new().DownloadString('https://chocolatey.org/install.ps1')) @@ -385,33 +396,60 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Install dependencies for packaging - Task PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, { + Add-BuildTask PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, { if (!(Test-PodeBuildCommand '7z')) { Invoke-PodeBuildInstall '7zip' $Versions.SevenZip } } # Synopsis: Install dependencies for compiling/building - Task BuildDeps { - if ($Versions.DotNet -eq 'auto') { - $Versions.DotNet = Get-PodeBuildDotNetEOL -LastVersion + Add-BuildTask BuildDeps { + if ([string]::IsNullOrEmpty($SdkVersion)) { + $_sdkVersion = Get-PodeBuildDotNetEOL -LatestVersion + } + else { + $_sdkVersion = $SdkVersion } # install dotnet if (Test-PodeBuildIsWindows) { $dotnet = 'dotnet' } + elseif (Test-PodeBuildCommand 'brew') { + $dotnet = 'dotnet-sdk' + } else { - $dotnet = "dotnet-sdk-$($Versions.DotNet)" + $dotnet = "dotnet-sdk-$_sdkVersion" } if (!(Test-PodeBuildCommand 'dotnet')) { - Invoke-PodeBuildInstall $dotnet $Versions.DotNet + Invoke-PodeBuildInstall $dotnet $_sdkVersion + } + elseif (![string]::IsNullOrEmpty($SdkVersion)) { + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { + Invoke-PodeBuildInstall $dotnet $SdkVersion + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { + Write-Error "The requested framework '$SdkVersion' is not available." + return + } + + } + else { + $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions + Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." + return + } } + $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $_sdkVersion + } # Synopsis: Install dependencies for running tests - Task TestDeps { + Add-BuildTask TestDeps { # install pester Install-PodeBuildModule Pester @@ -422,7 +460,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Install dependencies for documentation - Task DocsDeps ChocoDeps, { + Add-BuildTask DocsDeps ChocoDeps, { # install mkdocs if (!(Test-PodeBuildCommand 'mkdocs')) { Invoke-PodeBuildInstall 'mkdocs' $Versions.MkDocs @@ -437,7 +475,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet Install-PodeBuildModule PlatyPS } - Task IndexSamples { + Add-BuildTask IndexSamples { $examplesPath = './examples' if (!(Test-Path -PathType Container -Path $examplesPath)) { return @@ -480,34 +518,37 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Build the .NET Listener - Task Build BuildDeps, { + Add-BuildTask Build BuildDeps, { if (Test-Path ./src/Libs) { Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null } + if ($Versions.DotNet -eq 'auto') { + # Retrieve supported .NET versions + $eol = Get-PodeBuildDotNetEOL - # Retrieve supported .NET versions - $eol = Get-PodeBuildDotNetEOL - - $targetFrameworks = @() + $targetFrameworks = @() - if (![string]::IsNullOrEmpty($eol.supported)) { + if (![string]::IsNullOrEmpty($eol.supported)) { - # Parse supported versions into an array - $supportedVersions = $eol['supported'] -split ',' + # Parse supported versions into an array + $supportedVersions = $eol['supported'] -split ',' - # Construct target framework monikers - $targetFrameworks += ($supportedVersions | ForEach-Object { "net$_.0" }) + # Construct target framework monikers + $targetFrameworks += ($supportedVersions | ForEach-Object { "net$_.0" }) + } + } + else { + $targetFrameworks = $Versions.DotNet } - # Optionally include netstandard2.0 $targetFrameworks += 'netstandard2.0' # Retrieve the SDK version being used - $sdkVersion = dotnet --version + # $dotnetVersion = dotnet --version # Display the SDK version - Write-Output "Building target framework '$($targetFrameworks -join "','")' using .NET SDK version '$sdkVersion'" + Write-Output "Building targets '$($targetFrameworks -join "','")' using .NET '$AvailableSdkVersion' framework." # Build for supported target frameworks try { @@ -531,12 +572,12 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Creates a Zip of the Module - Task 7Zip -If (Test-PodeBuildIsWindows) PackDeps, StampVersion, { + Add-BuildTask 7Zip -If (Test-PodeBuildIsWindows) PackDeps, StampVersion, { exec { & 7z -tzip a $Version-Binaries.zip ./pkg/* } }, PrintChecksum #Synopsis: Create the Deliverable folder - Task DeliverableFolder { + Add-BuildTask DeliverableFolder { $path = './deliverable' if (Test-Path $path) { Remove-Item -Path $path -Recurse -Force | Out-Null @@ -547,7 +588,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Creates a Zip of the Module - Task Compress PackageFolder, StampVersion, DeliverableFolder, { + Add-BuildTask Compress PackageFolder, StampVersion, DeliverableFolder, { $path = './deliverable' if (Test-Path $path) { Remove-Item -Path $path -Recurse -Force | Out-Null @@ -558,13 +599,13 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet }, PrintChecksum # Synopsis: Creates a Chocolately package of the Module - Task ChocoPack -If (Test-PodeBuildIsWindows) PackDeps, PackageFolder, StampVersion, DeliverableFolder, { + Add-BuildTask ChocoPack -If (Test-PodeBuildIsWindows) PackDeps, PackageFolder, StampVersion, DeliverableFolder, { exec { choco pack ./packers/choco/pode.nuspec } Move-Item -Path "pode.$Version.nupkg" -Destination './deliverable' } # Synopsis: Create docker tags - Task DockerPack PackageFolder, StampVersion, { + Add-BuildTask DockerPack PackageFolder, StampVersion, { # check if github and windows, and output warning if ((Test-PodeBuildIsGitHub) -and (Test-PodeBuildIsWindows)) { Write-Warning 'Docker images are not built on GitHub Windows runners, and Docker is in Windows container only mode. Exiting task.' @@ -596,10 +637,10 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Package up the Module - Task Pack Compress, ChocoPack, DockerPack + Add-BuildTask Pack Compress, ChocoPack, DockerPack # Synopsis: Package up the Module into a /pkg folder - Task PackageFolder Build, { + Add-BuildTask PackageFolder Build, { $path = './pkg' if (Test-Path $path) { Remove-Item -Path $path -Recurse -Force | Out-Null @@ -635,7 +676,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Run the tests - Task TestNoBuild TestDeps, { + Add-BuildTask TestNoBuild TestDeps, { $p = (Get-Command Invoke-Pester) if ($null -eq $p -or $p.Version -ine $Versions.Pester) { Remove-Module Pester -Force -ErrorAction Ignore @@ -681,17 +722,17 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet }, PushCodeCoverage, CheckFailedTests # Synopsis: Run tests after a build - Task Test Build, TestNoBuild + Add-BuildTask Test Build, TestNoBuild # Synopsis: Check if any of the tests failed - Task CheckFailedTests { + Add-BuildTask CheckFailedTests { if ($TestStatus.FailedCount -gt 0) { throw "$($TestStatus.FailedCount) tests failed" } } # Synopsis: If AppyVeyor or GitHub, push code coverage stats - Task PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { + Add-BuildTask PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { try { $service = Get-PodeBuildService $branch = Get-PodeBuildBranch @@ -711,12 +752,12 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Run the documentation locally - Task Docs DocsDeps, DocsHelpBuild, { + Add-BuildTask Docs DocsDeps, DocsHelpBuild, { mkdocs serve --open } # Synopsis: Build the function help documentation - Task DocsHelpBuild IndexSamples, DocsDeps, Build, { + Add-BuildTask DocsHelpBuild IndexSamples, DocsDeps, Build, { # import the local module Remove-Module Pode -Force -ErrorAction Ignore | Out-Null Import-Module ./src/Pode.psm1 -Force | Out-Null @@ -760,7 +801,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Build the documentation - Task DocsBuild DocsDeps, DocsHelpBuild, { + Add-BuildTask DocsBuild DocsDeps, DocsHelpBuild, { mkdocs build --quiet } @@ -770,10 +811,10 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Clean the build enviroment - Task Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs + Add-BuildTask Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs # Synopsis: Clean the Deliverable folder - Task CleanDeliverable { + Add-BuildTask CleanDeliverable { $path = './deliverable' if (Test-Path -Path $path -PathType Container) { Write-Host 'Removing ./deliverable folder' @@ -783,7 +824,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Clean the pkg directory - Task CleanPkg { + Add-BuildTask CleanPkg { $path = './pkg' if ((Test-Path -Path $path -PathType Container )) { Write-Host 'Removing ./pkg folder' @@ -804,7 +845,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Clean the libs folder - Task CleanLibs { + Add-BuildTask CleanLibs { $path = './src/Libs' if (Test-Path -Path $path -PathType Container) { Write-Host "Removing $path contents" @@ -815,7 +856,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Clean the Listener folder - Task CleanListener { + Add-BuildTask CleanListener { $path = './src/Listener/bin' if (Test-Path -Path $path -PathType Container) { Write-Host "Removing $path contents" @@ -825,7 +866,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet Write-Host "Cleanup $path done" } - Task CleanDocs { + Add-BuildTask CleanDocs { $path = './docs/Getting-Started/Samples.md' if (Test-Path -Path $path -PathType Leaf) { Write-Host "Removing $path" @@ -837,7 +878,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Install Pode Module locally - Task Install-Module -If ($Version) Pack, { + Add-BuildTask Install-Module -If ($Version) Pack, { $PSPaths = Split-PodeBuildPwshPath $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" @@ -865,7 +906,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet } # Synopsis: Remove the Pode Module from the local registry - Task Remove-Module { + Add-BuildTask Remove-Module { if (!$Version) { throw 'Parameter -Version is required' } @@ -887,7 +928,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet #> # Synopsis: Setup the PowerShell environment - Task SetupPowerShell { + Add-BuildTask SetupPowerShell { # code for this step is altered versions of the code found here: # - https://github.com/bjompen/UpdatePWSHAction/blob/main/UpgradePwsh.ps1 # - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 From 09c192eddbb3fb4a0688f9d2337156e5b5e088b8 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 18:31:45 -0800 Subject: [PATCH 09/23] Update pode.build.ps1 --- pode.build.ps1 | 776 ++++++++++++++++++++++++++++++------------------- 1 file changed, 474 insertions(+), 302 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index b1c9915a1..26ba5a630 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -1,3 +1,87 @@ +<# +.SYNOPSIS + Build script for the Pode project, defining tasks for compilation, testing, packaging, and deployment. + +.DESCRIPTION + This script uses Invoke-Build to automate the Pode project build process across different environments (Windows, macOS, Linux). + It includes tasks for setting up dependencies, compiling .NET targets, running tests, generating documentation, and packaging. + +.PARAMETER Version + Specifies the project version for stamping, packaging, and documentation. Defaults to '0.0.0'. + +.PARAMETER PesterVerbosity + Sets the verbosity level for Pester tests. Options: None, Normal, Detailed, Diagnostic. + +.PARAMETER PowerShellVersion + Defines the target PowerShell version for installation, e.g., 'lts' or a specific version. + +.PARAMETER ReleaseNoteVersion + Specifies the release version for generating release notes. + +.PARAMETER UICulture + Sets the culture for running tests, defaulting to 'en-US'. + +.PARAMETER TargetFrameworks + Specifies the target .NET frameworks for building the project, e.g., netstandard2.0, net8.0. + +.PARAMETER SdkVersion + Sets the SDK version used for building .NET projects, defaulting to net8.0. + +.NOTES + This build script requires Invoke-Build. Below is a list of all available tasks: + + - Default: Lists all available tasks. + - StampVersion: Stamps the specified version onto the module. + - PrintChecksum: Generates and displays a checksum of the ZIP archive. + - ChocoDeps: Installs Chocolatey (for Windows). + - PackDeps: Installs dependencies required for packaging. + - BuildDeps: Installs dependencies required for building/compiling. + - TestDeps: Installs dependencies required for testing. + - DocsDeps: Installs dependencies required for documentation generation. + - IndexSamples: Indexes sample files for documentation. + - Build: Builds the .NET Listener for specified frameworks. + - 7Zip: Creates a ZIP archive of the module (Windows only). + - DeliverableFolder: Creates a folder for deliverables. + - Compress: Compresses the module into a ZIP format for distribution. + - ChocoPack: Creates a Chocolatey package of the module (Windows only). + - DockerPack: Builds Docker images for the module. + - Pack: Packages the module, including ZIP, Chocolatey, and Docker. + - PackageFolder: Creates the `pkg` folder for module packaging. + - TestNoBuild: Runs tests without building, including Pester tests. + - Test: Runs tests after building the project. + - CheckFailedTests: Checks if any tests failed and throws an error if so. + - PushCodeCoverage: Pushes code coverage results to a coverage service. + - Docs: Serves the documentation locally for review. + - DocsHelpBuild: Builds function help documentation. + - DocsBuild: Builds the documentation for distribution. + - Clean: Cleans the build environment, removing all generated files. + - CleanDeliverable: Removes the `deliverable` folder. + - CleanPkg: Removes the `pkg` folder. + - CleanLibs: Removes the `Libs` folder under `src`. + - CleanListener: Removes the Listener folder. + - CleanDocs: Cleans up generated documentation files. + - Install-Module: Installs the Pode module locally. + - Remove-Module: Removes the Pode module from the local registry. + - SetupPowerShell: Sets up the PowerShell environment for the build. + - ReleaseNotes: Generates release notes based on merged pull requests. + +.EXAMPLE + Invoke-Build -Task Default + # Displays a list of all available tasks. + + Invoke-Build -Task Build -Version '1.2.3' + # Compiles the project for the specified version. + + Invoke-Build -Task Test + # Runs tests on the project, including Pester tests. + + Invoke-Build -Task Docs + # Builds and serves the documentation locally. + +.LINK + For more information, visit https://github.com/Badgerati/Pode +#> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '')] @@ -23,343 +107,462 @@ param( [string[]] [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] - $TargetFrameworks, + $TargetFrameworks = @('netstandard2.0', 'net8.0' ), [string] [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] - $SdkVersion + $SdkVersion = 'net8.0' ) +# Dependency Versions +$Versions = @{ + Pester = '5.6.1' + MkDocs = '1.6.1' + PSCoveralls = '1.0.0' + SevenZip = '18.5.0.20180730' + DotNet = $SdkVersion + MkDocsTheme = '9.5.44' + PlatyPS = '0.14.2' +} -# Check if the script is running under Invoke-Build -if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BuildRoot') -or $null -ne $BuildRoot)) { - # Dependency Versions - $Versions = @{ - Pester = '5.6.1' - MkDocs = '1.6.1' - PSCoveralls = '1.0.0' - SevenZip = '18.5.0.20180730' - DotNet = @($(if ($null -eq $TargetFrameworks) { 'auto' } else { $TargetFrameworks })) - MkDocsTheme = '9.5.44' - PlatyPS = '0.14.2' - } +# Helper Functions +function Test-PodeBuildIsWindows { + $v = $PSVersionTable + return ($v.Platform -ilike '*win*' -or ($null -eq $v.Platform -and $v.PSEdition -ieq 'desktop')) +} +function Test-PodeBuildIsGitHub { + return (![string]::IsNullOrWhiteSpace($env:GITHUB_REF)) +} - # Helper Functions - function Test-PodeBuildIsWindows { - $v = $PSVersionTable - return ($v.Platform -ilike '*win*' -or ($null -eq $v.Platform -and $v.PSEdition -ieq 'desktop')) - } +function Test-PodeBuildCanCodeCoverage { + return (@('1', 'true') -icontains $env:PODE_RUN_CODE_COVERAGE) +} - function Test-PodeBuildIsGitHub { - return (![string]::IsNullOrWhiteSpace($env:GITHUB_REF)) - } +function Get-PodeBuildService { + return 'github-actions' +} - function Test-PodeBuildCanCodeCoverage { - return (@('1', 'true') -icontains $env:PODE_RUN_CODE_COVERAGE) - } +function Test-PodeBuildCommand($cmd) { + $path = $null - function Get-PodeBuildService { - return 'github-actions' + if (Test-PodeBuildIsWindows) { + $path = (Get-Command $cmd -ErrorAction Ignore) + } + else { + $path = (which $cmd) } - function Test-PodeBuildCommand($cmd) { - $path = $null + return (![string]::IsNullOrWhiteSpace($path)) +} - if (Test-PodeBuildIsWindows) { - $path = (Get-Command $cmd -ErrorAction Ignore) +function Get-PodeBuildBranch { + return ($env:GITHUB_REF -ireplace 'refs\/heads\/', '') +} + +function Invoke-PodeBuildInstall($name, $version) { + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + if (Test-PodeBuildIsWindows) { + if (Test-PodeBuildCommand 'choco') { + choco install $name --version $version -y --no-progress } - else { - $path = (which $cmd) + } + else { + if (Test-PodeBuildCommand 'brew') { + brew install $name + } + elseif (Test-PodeBuildCommand 'apt-get') { + sudo apt-get install $name -y + } + elseif (Test-PodeBuildCommand 'yum') { + sudo yum install $name -y } - - return (![string]::IsNullOrWhiteSpace($path)) } +} - function Get-PodeBuildBranch { - return ($env:GITHUB_REF -ireplace 'refs\/heads\/', '') +function Install-PodeBuildModule($name) { + if ($null -ne ((Get-Module -ListAvailable $name) | Where-Object { $_.Version -ieq $Versions[$name] })) { + return } - function Invoke-PodeBuildInstall($name, $version) { - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Write-Host "Installing $($name) v$($Versions[$name])" + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Install-Module -Name "$($name)" -Scope CurrentUser -RequiredVersion "$($Versions[$name])" -Force -SkipPublisherCheck +} - if (Test-PodeBuildIsWindows) { - if (Test-PodeBuildCommand 'choco') { - choco install $name --version $version -y --no-progress - } - } - else { - if (Test-PodeBuildCommand 'brew') { - brew install $name - } - elseif (Test-PodeBuildCommand 'apt-get') { - sudo apt-get install $name -y - } - elseif (Test-PodeBuildCommand 'yum') { - sudo yum install $name -y - } +function Get-TargetFramework { + param( + [string] + $TargetFrameworks + ) + + switch ($TargetFrameworks) { + 'netstandard2.0' { return 2 } + 'netstandard2.1' { return 3 } + 'netcoreapp3.0' { return 3 } + 'net5.0' { return 5 } + 'net6.0' { return 6 } + 'net7.0' { return 7 } + 'net8.0' { return 8 } + 'net9.0' { return 9 } + default { + Write-Warning "$TargetFrameworks is not a valid Framework. Rollback to netstandard2.0" + return 2 } } +} - function Install-PodeBuildModule($name) { - if ($null -ne ((Get-Module -ListAvailable $name) | Where-Object { $_.Version -ieq $Versions[$name] })) { - return - } - Write-Host "Installing $($name) v$($Versions[$name])" - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - Install-Module -Name "$($name)" -Scope CurrentUser -RequiredVersion "$($Versions[$name])" -Force -SkipPublisherCheck - } +function Get-TargetFrameworkName { + param( + $Version + ) - function Get-TargetFramework { - param( - [string] - $TargetFrameworks - ) - - switch ($TargetFrameworks) { - 'netstandard2.0' { return 2 } - 'netstandard2.1' { return 3 } - 'netcoreapp3.0' { return 3 } - 'net5.0' { return 5 } - 'net6.0' { return 6 } - 'net7.0' { return 7 } - 'net8.0' { return 8 } - 'net9.0' { return 9 } - default { - Write-Warning "$TargetFrameworks is not a valid Framework. Rollback to netstandard2.0" - return 2 - } + switch ( $Version) { + '2' { return 'netstandard2.0' } + '3' { return 'netstandard2.1' } + '5' { return 'net5.0' } + '6' { return 'net6.0' } + '7' { return 'net7.0' } + '8' { return 'net8.0' } + '9' { return 'net9.0' } + default { + Write-Warning "$Version is not a valid Framework. Rollback to netstandard2.0" + return 'netstandard2.0' } } +} +function Invoke-PodeBuildDotnetBuild { + param ( + [string]$target + ) - function Get-TargetFrameworkName { - param( - $Version - ) - - switch ( $Version) { - '2' { return 'netstandard2.0' } - '3' { return 'netstandard2.1' } - '5' { return 'net5.0' } - '6' { return 'net6.0' } - '7' { return 'net7.0' } - '8' { return 'net8.0' } - '9' { return 'net9.0' } - default { - Write-Warning "$Version is not a valid Framework. Rollback to netstandard2.0" - return 'netstandard2.0' - } - } + # Retrieve the installed SDK versions + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + if ([string]::IsNullOrEmpty($AvailableSdkVersion)) { + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique } + else { + $majorVersions = $sdkVersions.Where( { ([version]$_).Major -ge (Get-TargetFramework -TargetFrameworks $AvailableSdkVersion) } ) | Sort-Object -Descending | Select-Object -Unique + } + # Map target frameworks to minimum SDK versions - function Invoke-PodeBuildDotnetBuild { - param ( - [string]$target - ) + if ($null -eq $majorVersions) { + Write-Error "The requested '$AvailableSdkVersion' framework is not available." + return + } + $requiredSdkVersion = Get-TargetFramework -TargetFrameworks $target - # Retrieve the installed SDK versions - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - if ([string]::IsNullOrEmpty($AvailableSdkVersion)) { - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique - } - else { - $majorVersions = $sdkVersions.Where( { ([version]$_).Major -ge (Get-TargetFramework -TargetFrameworks $AvailableSdkVersion) } ) | Sort-Object -Descending | Select-Object -Unique - } - # Map target frameworks to minimum SDK versions + # Determine if the target framework is compatible + $isCompatible = $majorVersions -ge $requiredSdkVersion - if ($null -eq $majorVersions) { - Write-Error "The requested '$AvailableSdkVersion' framework is not available." - return - } - $requiredSdkVersion = Get-TargetFramework -TargetFrameworks $target + if ($isCompatible) { + Write-Output "SDK for target framework '$target' is compatible with the '$AvailableSdkVersion' framework." + } + else { + Write-Warning "SDK for target framework '$target' is not compatible with the '$AvailableSdkVersion' framework. Skipping build." + return + } - # Determine if the target framework is compatible - $isCompatible = $majorVersions -ge $requiredSdkVersion + # Optionally set assembly version + if ($Version) { + Write-Output "Assembly Version: $Version" + $AssemblyVersion = "-p:Version=$Version" + } + else { + $AssemblyVersion = '' + } - if ($isCompatible) { - Write-Output "SDK for target framework '$target' is compatible with the '$AvailableSdkVersion' framework." - } - else { - Write-Warning "SDK for target framework '$target' is not compatible with the '$AvailableSdkVersion' framework. Skipping build." - return - } + # Use dotnet publish for .NET Core and .NET 5+ + dotnet publish --configuration Release --self-contained --framework $target $AssemblyVersion --output ../Libs/$target - # Optionally set assembly version - if ($Version) { - Write-Output "Assembly Version: $Version" - $AssemblyVersion = "-p:Version=$Version" + if (!$?) { + throw "Build failed for target framework '$target'." + } +} + +function Get-PodeBuildPwshEOL { + $uri = 'https://endoflife.date/api/powershell.json' + try { + $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } + return @{ + eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' + supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' } - else { - $AssemblyVersion = '' + } + catch { + Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" + return @{ + eol = '' + supported = '' } + } +} - # Use dotnet publish for .NET Core and .NET 5+ - dotnet publish --configuration Release --self-contained --framework $target $AssemblyVersion --output ../Libs/$target - if (!$?) { - throw "Build failed for target framework '$target'." +function Get-PodeBuildDotNetEOL { + param( + [switch] + $LatestVersion + ) + $uri = 'https://endoflife.date/api/dotnet.json' + try { + $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } + if ($LatestVersion) { + return (($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle)[0] } - } - - function Get-PodeBuildPwshEOL { - $uri = 'https://endoflife.date/api/powershell.json' - try { - $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } + else { return @{ eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' } } - catch { - Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" - return @{ - eol = '' - supported = '' - } + } + catch { + Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" + return @{ + eol = '' + supported = '' } } +} - function Get-PodeBuildDotNetEOL { - param( - [switch] - $LatestVersion - ) - $uri = 'https://endoflife.date/api/dotnet.json' - try { - $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } - if ($LatestVersion) { - return (($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle)[0] - } - else { - return @{ - eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' - supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' - } - } - } - catch { - Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" - return @{ - eol = '' - supported = '' - } - } - } - function Test-PodeBuildOSWindows { - return ($IsWindows -or - ![string]::IsNullOrEmpty($env:ProgramFiles) -or +function Test-PodeBuildOSWindows { + return ($IsWindows -or + ![string]::IsNullOrEmpty($env:ProgramFiles) -or (($PSVersionTable.Keys -contains 'PSEdition') -and ($PSVersionTable.PSEdition -eq 'Desktop'))) +} + +function Get-PodeBuildOSPwshName { + if (Test-PodeBuildOSWindows) { + return 'win' } - function Get-PodeBuildOSPwshName { - if (Test-PodeBuildOSWindows) { - return 'win' - } + if ($IsLinux) { + return 'linux' + } - if ($IsLinux) { - return 'linux' - } + if ($IsMacOS) { + return 'osx' + } +} - if ($IsMacOS) { - return 'osx' - } +function Get-PodeBuildOSPwshArchitecture { + $arch = [string]::Empty + + # windows + if (Test-PodeBuildOSWindows) { + $arch = $env:PROCESSOR_ARCHITECTURE } - function Get-PodeBuildOSPwshArchitecture { - $arch = [string]::Empty + # unix + if ($IsLinux -or $IsMacOS) { + $arch = uname -m + } - # windows - if (Test-PodeBuildOSWindows) { - $arch = $env:PROCESSOR_ARCHITECTURE - } + Write-Host "OS Architecture: $($arch)" + + # convert to pwsh arch + switch ($arch.ToLowerInvariant()) { + 'amd64' { return 'x64' } + 'x86' { return 'x86' } + 'x86_64' { return 'x64' } + 'armv7*' { return 'arm32' } + 'aarch64*' { return 'arm64' } + 'arm64' { return 'arm64' } + 'arm64*' { return 'arm64' } + 'armv8*' { return 'arm64' } + default { throw "Unsupported architecture: $($arch)" } + } +} - # unix - if ($IsLinux -or $IsMacOS) { - $arch = uname -m - } +function Convert-PodeBuildOSPwshTagToVersion { + $result = Invoke-RestMethod -Uri "https://aka.ms/pwsh-buildinfo-$($PowerShellVersion)" + return $result.ReleaseTag -ireplace '^v' +} - Write-Host "OS Architecture: $($arch)" +function Install-PodeBuildPwshWindows($target) { + $installFolder = "$($env:ProgramFiles)\PowerShell\7" - # convert to pwsh arch - switch ($arch.ToLowerInvariant()) { - 'amd64' { return 'x64' } - 'x86' { return 'x86' } - 'x86_64' { return 'x64' } - 'armv7*' { return 'arm32' } - 'aarch64*' { return 'arm64' } - 'arm64' { return 'arm64' } - 'arm64*' { return 'arm64' } - 'armv8*' { return 'arm64' } - default { throw "Unsupported architecture: $($arch)" } - } + if (Test-Path $installFolder) { + Remove-Item $installFolder -Recurse -Force -ErrorAction Stop } - function Convert-PodeBuildOSPwshTagToVersion { - $result = Invoke-RestMethod -Uri "https://aka.ms/pwsh-buildinfo-$($PowerShellVersion)" - return $result.ReleaseTag -ireplace '^v' - } + Copy-Item -Path "$($target)\" -Destination "$($installFolder)\" -Recurse -ErrorAction Stop +} - function Install-PodeBuildPwshWindows($target) { - $installFolder = "$($env:ProgramFiles)\PowerShell\7" +function Install-PodeBuildPwshUnix($target) { + $targetFullPath = Join-Path -Path $target -ChildPath 'pwsh' + $null = chmod 755 $targetFullPath - if (Test-Path $installFolder) { - Remove-Item $installFolder -Recurse -Force -ErrorAction Stop - } + $symlink = $null + if ($IsMacOS) { + $symlink = '/usr/local/bin/pwsh' + } + else { + $symlink = '/usr/bin/pwsh' + } - Copy-Item -Path "$($target)\" -Destination "$($installFolder)\" -Recurse -ErrorAction Stop + $uid = id -u + if ($uid -ne '0') { + $sudo = 'sudo' + } + else { + $sudo = '' } - function Install-PodeBuildPwshUnix($target) { - $targetFullPath = Join-Path -Path $target -ChildPath 'pwsh' - $null = chmod 755 $targetFullPath + # Make symbolic link point to installed path + & $sudo ln -fs $targetFullPath $symlink +} - $symlink = $null - if ($IsMacOS) { - $symlink = '/usr/local/bin/pwsh' - } - else { - $symlink = '/usr/bin/pwsh' - } +<# +.SYNOPSIS + Retrieves the currently installed PowerShell version. - $uid = id -u - if ($uid -ne '0') { - $sudo = 'sudo' - } - else { - $sudo = '' - } +.DESCRIPTION + This function runs the `pwsh -v` command and parses the output to return only the version number. + This is useful for verifying the PowerShell version in the build environment. + +.OUTPUTS + [string] - The current PowerShell version. + +.EXAMPLE + $version = Get-PodeBuildCurrentPwshVersion + Write-Host "Current PowerShell version: $version" + +.NOTES + This function assumes that `pwsh` is available in the system PATH. +#> +function Get-PodeBuildCurrentPwshVersion { + # Run pwsh command, split by spaces, and return the version component + return ("$(pwsh -v)" -split ' ')[1].Trim() +} + +<# +.SYNOPSIS + Builds a Docker image and tags it for the Pode project. + +.DESCRIPTION + This function uses the Docker CLI to build an image for Pode, then tags it for GitHub Packages. + The function takes a tag and a Dockerfile path as parameters to build and tag the Docker image. + +.PARAMETER Tag + The Docker image tag, typically a version number or label (e.g., 'latest'). + +.PARAMETER File + The path to the Dockerfile to use for building the image. + +.EXAMPLE + Invoke-PodeBuildDockerBuild -Tag '1.0.0' -File './Dockerfile' + # Builds a Docker image using './Dockerfile' and tags it as 'badgerati/pode:1.0.0'. - # Make symbolic link point to installed path - & $sudo ln -fs $targetFullPath $symlink +.NOTES + Requires Docker to be installed and available in the system PATH. +#> +function Invoke-PodeBuildDockerBuild { + param ( + [string] + $Tag, + [string] + $File + ) + + # Build the Docker image with the specified tag and Dockerfile + docker build -t badgerati/pode:$tTag -f $File . + if (!$?) { + throw "docker build failed for $($Tag)" } - function Get-PodeBuildCurrentPwshVersion { - return ("$(pwsh -v)" -split ' ')[1].Trim() + # Tag the image for GitHub Packages + docker tag badgerati/pode:$Tag docker.pkg.github.com/badgerati/pode/pode:$Tag + if (!$?) { + throw "docker tag failed for $($Tag)" } +} - function Invoke-PodeBuildDockerBuild($tag, $file) { - docker build -t badgerati/pode:$tag -f $file . - if (!$?) { - throw "docker build failed for $($tag)" - } - docker tag badgerati/pode:$tag docker.pkg.github.com/badgerati/pode/pode:$tag - if (!$?) { - throw "docker tag failed for $($tag)" - } +<# +.SYNOPSIS + Splits the PSModulePath environment variable into an array of paths. + +.DESCRIPTION + This function checks the operating system and splits the PSModulePath variable based on the appropriate separator: + ';' for Windows and ':' for Unix-based systems. + +.OUTPUTS + [string[]] - An array of paths from the PSModulePath variable. + +.EXAMPLE + $paths = Split-PodeBuildPwshPath + foreach ($path in $paths) { + Write-Host $path } - function Split-PodeBuildPwshPath { - if (Test-PodeBuildOSWindows) { - return $env:PSModulePath -split ';' - } - else { - return $env:PSModulePath -split ':' - } +.NOTES + This function enables cross-platform support by handling path separators for Windows and Unix-like systems. +#> +function Split-PodeBuildPwshPath { + # Check if OS is Windows, then split PSModulePath by ';', otherwise use ':' + if (Test-PodeBuildOSWindows) { + return $env:PSModulePath -split ';' + } + else { + return $env:PSModulePath -split ':' + } +} + + + +# Check if the script is running under Invoke-Build +if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BuildRoot') -or $null -ne $BuildRoot)) { + + + Add-BuildTask Default { + Write-Host 'Tasks in the Build Script:' -ForegroundColor DarkMagenta + Write-Host + Write-Host 'Primary Tasks:' -ForegroundColor Green + Write-Host '- Default: Lists all available tasks.' + Write-Host '- Build: Builds the .NET Listener for specified frameworks.' + Write-Host '- Pack: Packages the module, including ZIP, Chocolatey, and Docker.' + Write-Host '- Test: Runs tests after building the project.' + Write-Host '- Clean: Cleans the build environment, removing all generated files.' + Write-Host '- Install-Module: Installs the Pode module locally.' + Write-Host '- Remove-Module: Removes the Pode module from the local registry.' + Write-Host '- DocsBuild: Builds the documentation for distribution.' + Write-Host '- TestNoBuild: Runs tests without building, including Pester tests.' + + + Write-Host + Write-Host 'Other Tasks:' -ForegroundColor Green + Write-Host '- StampVersion: Stamps the specified version onto the module.' + Write-Host '- PrintChecksum: Generates and displays a checksum of the ZIP archive.' + Write-Host '- ChocoDeps: Installs Chocolatey (for Windows).' + Write-Host '- PackDeps: Installs dependencies required for packaging.' + Write-Host '- BuildDeps: Installs dependencies required for building/compiling.' + Write-Host '- TestDeps: Installs dependencies required for testing.' + Write-Host '- DocsDeps: Installs dependencies required for documentation generation.' + Write-Host '- IndexSamples: Indexes sample files for documentation.' + Write-Host '- 7Zip: Creates a ZIP archive of the module (Windows only).' + Write-Host '- DeliverableFolder: Creates a folder for deliverables.' + Write-Host '- Compress: Compresses the module into a ZIP format for distribution.' + Write-Host '- ChocoPack: Creates a Chocolatey package of the module (Windows only).' + Write-Host '- DockerPack: Builds Docker images for the module.' + Write-Host "- PackageFolder: Creates the `pkg` folder for module packaging." + Write-Host '- CheckFailedTests: Checks if any tests failed and throws an error if so.' + Write-Host '- PushCodeCoverage: Pushes code coverage results to a coverage service.' + Write-Host '- Docs: Serves the documentation locally for review.' + Write-Host '- DocsHelpBuild: Builds function help documentation.' + Write-Host "- CleanDeliverable: Removes the `deliverable` folder." + Write-Host "- CleanPkg: Removes the `pkg` folder." + Write-Host "- CleanLibs: Removes the `Libs` folder under `src`." + Write-Host '- CleanListener: Removes the Listener folder.' + Write-Host '- CleanDocs: Cleans up generated documentation files.' + Write-Host '- SetupPowerShell: Sets up the PowerShell environment for the build.' + Write-Host '- ReleaseNotes: Generates release notes based on merged pull requests.' } @@ -404,12 +607,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet # Synopsis: Install dependencies for compiling/building Add-BuildTask BuildDeps { - if ([string]::IsNullOrEmpty($SdkVersion)) { - $_sdkVersion = Get-PodeBuildDotNetEOL -LatestVersion - } - else { - $_sdkVersion = $SdkVersion - } + # install dotnet if (Test-PodeBuildIsWindows) { @@ -419,32 +617,24 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet $dotnet = 'dotnet-sdk' } else { - $dotnet = "dotnet-sdk-$_sdkVersion" + $dotnet = "dotnet-sdk-$SdkVersion" } if (!(Test-PodeBuildCommand 'dotnet')) { - Invoke-PodeBuildInstall $dotnet $_sdkVersion - } - elseif (![string]::IsNullOrEmpty($SdkVersion)) { - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique - if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Invoke-PodeBuildInstall $dotnet $SdkVersion - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique - if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Write-Error "The requested framework '$SdkVersion' is not available." - return - } + Invoke-PodeBuildInstall $dotnet $SdkVersion + } - } - else { - $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions - Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." - return - } + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions + + if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { + Write-Error "The requested framework '$SdkVersion' is not available." + return + } + elseif ($majorVersions -gt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { + Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." } - $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $_sdkVersion } @@ -522,26 +712,8 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet if (Test-Path ./src/Libs) { Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null } - if ($Versions.DotNet -eq 'auto') { - # Retrieve supported .NET versions - $eol = Get-PodeBuildDotNetEOL - - $targetFrameworks = @() - if (![string]::IsNullOrEmpty($eol.supported)) { - # Parse supported versions into an array - $supportedVersions = $eol['supported'] -split ',' - - # Construct target framework monikers - $targetFrameworks += ($supportedVersions | ForEach-Object { "net$_.0" }) - } - } - else { - $targetFrameworks = $Versions.DotNet - } - # Optionally include netstandard2.0 - $targetFrameworks += 'netstandard2.0' # Retrieve the SDK version being used From a5deebe58e2aa90cc7d3ea880302803d92cd8121 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 18:58:46 -0800 Subject: [PATCH 10/23] fixes --- pode.build.ps1 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 26ba5a630..6d213de1c 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -111,7 +111,7 @@ param( [string] [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] - $SdkVersion = 'net8.0' + $SdkVersion = 'net9.0' ) # Dependency Versions @@ -607,8 +607,6 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet # Synopsis: Install dependencies for compiling/building Add-BuildTask BuildDeps { - - # install dotnet if (Test-PodeBuildIsWindows) { $dotnet = 'dotnet' @@ -629,8 +627,15 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Write-Error "The requested framework '$SdkVersion' is not available." - return + Invoke-PodeBuildInstall $dotnet $SdkVersion + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions + + if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { + Write-Error "The requested framework '$SdkVersion' is not available." + return + } } elseif ($majorVersions -gt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." From 114b9cb95798e28ade73dff4d427f91c45bca530 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 19:20:02 -0800 Subject: [PATCH 11/23] more comments --- pode.build.ps1 | 168 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 123 insertions(+), 45 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 6d213de1c..d49d65c7f 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -302,34 +302,7 @@ function Get-PodeBuildPwshEOL { } } - -function Get-PodeBuildDotNetEOL { - param( - [switch] - $LatestVersion - ) - $uri = 'https://endoflife.date/api/dotnet.json' - try { - $eol = Invoke-RestMethod -Uri $uri -Headers @{ Accept = 'application/json' } - if ($LatestVersion) { - return (($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle)[0] - } - else { - return @{ - eol = ($eol | Where-Object { [datetime]$_.eol -lt [datetime]::Now }).cycle -join ',' - supported = ($eol | Where-Object { [datetime]$_.eol -ge [datetime]::Now }).cycle -join ',' - } - } - } - catch { - Write-Warning "Invoke-RestMethod to $uri failed: $($_.ErrorDetails.Message)" - return @{ - eol = '' - supported = '' - } - } -} - + function Test-PodeBuildOSWindows { return ($IsWindows -or @@ -351,54 +324,158 @@ function Get-PodeBuildOSPwshName { } } +<# +.SYNOPSIS + Determines the OS architecture for the current system. + +.DESCRIPTION + This function detects the operating system's architecture and converts it into a format + compatible with PowerShell installation requirements. It handles both Windows and Unix-based + systems and maps various architecture identifiers to PowerShell-supported names (e.g., 'x64', 'arm64'). + +.OUTPUTS + [string] - The architecture string, such as 'x64', 'x86', 'arm64', or 'arm32'. + +.EXAMPLE + $arch = Get-PodeBuildOSPwshArchitecture + Write-Host "Current architecture: $arch" + +.NOTES + - For Windows, the architecture is derived from the `PROCESSOR_ARCHITECTURE` environment variable. + - For Unix-based systems, the architecture is determined using the `uname -m` command. + - If the architecture is not supported, the function throws an exception. +#> function Get-PodeBuildOSPwshArchitecture { + # Initialize architecture variable $arch = [string]::Empty - # windows + # Detect architecture on Windows if (Test-PodeBuildOSWindows) { $arch = $env:PROCESSOR_ARCHITECTURE } - # unix + # Detect architecture on Unix-based systems (Linux/macOS) if ($IsLinux -or $IsMacOS) { $arch = uname -m } + # Output detected architecture for debugging Write-Host "OS Architecture: $($arch)" - # convert to pwsh arch + # Convert detected architecture to a PowerShell-compatible format switch ($arch.ToLowerInvariant()) { - 'amd64' { return 'x64' } - 'x86' { return 'x86' } - 'x86_64' { return 'x64' } - 'armv7*' { return 'arm32' } - 'aarch64*' { return 'arm64' } - 'arm64' { return 'arm64' } - 'arm64*' { return 'arm64' } - 'armv8*' { return 'arm64' } - default { throw "Unsupported architecture: $($arch)" } + 'amd64' { return 'x64' } # 64-bit architecture (AMD64) + 'x86' { return 'x86' } # 32-bit architecture + 'x86_64' { return 'x64' } # 64-bit architecture (x86_64) + 'armv7*' { return 'arm32' } # 32-bit ARM architecture + 'aarch64*' { return 'arm64' } # 64-bit ARM architecture + 'arm64' { return 'arm64' } # Explicit ARM64 + 'arm64*' { return 'arm64' } # Pattern matching for ARM64 + 'armv8*' { return 'arm64' } # ARM v8 series + default { throw "Unsupported architecture: $($arch)" } # Throw exception for unsupported architectures } } + +<# +.SYNOPSIS + Converts a PowerShell tag to a version number. + +.DESCRIPTION + This function retrieves PowerShell build information for a specified tag by querying + an online API. It then extracts and returns the release version associated with the tag. + +.PARAMETER PowerShellVersion + The PowerShell version tag to retrieve build information for (e.g., 'lts', 'stable', or a specific version). + +.OUTPUTS + [string] - The extracted version number corresponding to the provided tag. + +.EXAMPLE + $version = Convert-PodeBuildOSPwshTagToVersion + Write-Host "Resolved PowerShell version: $version" + +.NOTES + This function depends on internet connectivity to query the build information API. +#> function Convert-PodeBuildOSPwshTagToVersion { + # Query PowerShell build info API with the specified tag $result = Invoke-RestMethod -Uri "https://aka.ms/pwsh-buildinfo-$($PowerShellVersion)" + + # Extract and return the release tag without the leading 'v' return $result.ReleaseTag -ireplace '^v' } -function Install-PodeBuildPwshWindows($target) { +<# +.SYNOPSIS + Installs PowerShell on a Windows system. + +.DESCRIPTION + This function installs PowerShell by copying files from a specified target directory + to the standard installation folder on a Windows system. It first removes any existing + installation in the Target directory. + +.PARAMETER Target + The directory containing the PowerShell installation files. + +.EXAMPLE + Install-PodeBuildPwshWindows -Target 'C:\Temp\PowerShell' + # Installs PowerShell from the 'C:\Temp\PowerShell' directory. + +.NOTES + This function requires administrative privileges to modify the Program Files directory. +#> +function Install-PodeBuildPwshWindows { + param ( + [string] + $Target + ) + + # Define the installation folder path $installFolder = "$($env:ProgramFiles)\PowerShell\7" + # Remove the existing installation, if any if (Test-Path $installFolder) { Remove-Item $installFolder -Recurse -Force -ErrorAction Stop } - Copy-Item -Path "$($target)\" -Destination "$($installFolder)\" -Recurse -ErrorAction Stop + # Copy the new PowerShell files to the installation folder + Copy-Item -Path "$($Target)\" -Destination "$($installFolder)\" -Recurse -ErrorAction Stop } -function Install-PodeBuildPwshUnix($target) { - $targetFullPath = Join-Path -Path $target -ChildPath 'pwsh' + +<# +.SYNOPSIS + Installs PowerShell on a Unix-based system. + +.DESCRIPTION + This function installs PowerShell on Unix-based systems by copying files from a specified Target directory, + setting appropriate permissions, and creating a symbolic link to the PowerShell binary. + +.PARAMETER Target + The directory containing the PowerShell installation files. + +.EXAMPLE + Install-PodeBuildPwshUnix -Target '/tmp/powershell' + # Installs PowerShell from the '/tmp/powershell' directory. + +.NOTES + - This function requires administrative privileges to create symbolic links in system directories. + - The `sudo` command is used if the script is not run as root. +#> +function Install-PodeBuildPwshUnix { + param ( + [string] + $Target + ) + + # Define the full path to the PowerShell binary + $targetFullPath = Join-Path -Path $Target -ChildPath 'pwsh' + + # Set executable permissions on the PowerShell binary $null = chmod 755 $targetFullPath + # Determine the symbolic link location based on the operating system $symlink = $null if ($IsMacOS) { $symlink = '/usr/local/bin/pwsh' @@ -407,6 +484,7 @@ function Install-PodeBuildPwshUnix($target) { $symlink = '/usr/bin/pwsh' } + # Check if the script is run as root $uid = id -u if ($uid -ne '0') { $sudo = 'sudo' @@ -415,7 +493,7 @@ function Install-PodeBuildPwshUnix($target) { $sudo = '' } - # Make symbolic link point to installed path + # Create a symbolic link to the PowerShell binary & $sudo ln -fs $targetFullPath $symlink } From 3bbb732c735f5ffdada18118a600f6ff381fd0bb Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 19:24:25 -0800 Subject: [PATCH 12/23] Update pode.build.ps1 --- pode.build.ps1 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index d49d65c7f..b82996d8c 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -302,7 +302,7 @@ function Get-PodeBuildPwshEOL { } } - + function Test-PodeBuildOSWindows { return ($IsWindows -or @@ -696,11 +696,16 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet $dotnet = "dotnet-sdk-$SdkVersion" } - if (!(Test-PodeBuildCommand 'dotnet')) { + # if (!(Test-PodeBuildCommand 'dotnet')) { + # Invoke-PodeBuildInstall $dotnet $SdkVersion + # } + try { + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + } + catch { Invoke-PodeBuildInstall $dotnet $SdkVersion + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } } - - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions From 170bc4a4831fb7ee0e21211206931b2294cb44c9 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 19:50:08 -0800 Subject: [PATCH 13/23] Update pode.build.ps1 --- pode.build.ps1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pode.build.ps1 b/pode.build.ps1 index b82996d8c..e9589c393 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -699,6 +699,19 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet # if (!(Test-PodeBuildCommand 'dotnet')) { # Invoke-PodeBuildInstall $dotnet $SdkVersion # } + + if (Test-PodeBuildIsGitHub){ + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions + + if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { + Write-Error "The requested framework '$SdkVersion' is not available." + return + } + return + } + try { $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } } From c46e295f994728bada9a401533c76f097895e57c Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 19:54:08 -0800 Subject: [PATCH 14/23] Update pode.build.ps1 --- pode.build.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/pode.build.ps1 b/pode.build.ps1 index e9589c393..5fae53506 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -702,6 +702,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet if (Test-PodeBuildIsGitHub){ $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + Write-Warning $sdkVersions $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions From 65344081c188f283b3b8770de4288fe7d91aa8ae Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 19:56:22 -0800 Subject: [PATCH 15/23] Update pode.build.ps1 --- pode.build.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/pode.build.ps1 b/pode.build.ps1 index 5fae53506..0d5cd3cff 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -702,6 +702,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet if (Test-PodeBuildIsGitHub){ $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + dotnet --list-sdks Write-Warning $sdkVersions $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions From 5447d5e8b62b93426e469cf061a10b5cfdadb598 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 20:01:07 -0800 Subject: [PATCH 16/23] Update pode.build.ps1 --- pode.build.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 0d5cd3cff..b9c7b69ca 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -702,11 +702,12 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet if (Test-PodeBuildIsGitHub){ $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - dotnet --list-sdks + dotnet --list-sdks Write-Warning $sdkVersions $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + Write-Warning "Majorversion=$majorVersions" $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions - + Write-Warning "AvailableSdkVersion=$AvailableSdkVersion" if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { Write-Error "The requested framework '$SdkVersion' is not available." return From b27548473da017422f8c27005d432a1b64a613f4 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 20:04:35 -0800 Subject: [PATCH 17/23] Update pode.build.ps1 --- pode.build.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index b9c7b69ca..9fe535d33 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -704,7 +704,7 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } dotnet --list-sdks Write-Warning $sdkVersions - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] Write-Warning "Majorversion=$majorVersions" $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions Write-Warning "AvailableSdkVersion=$AvailableSdkVersion" @@ -722,13 +722,13 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet Invoke-PodeBuildInstall $dotnet $SdkVersion $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } } - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { Invoke-PodeBuildInstall $dotnet $SdkVersion $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique + $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { From 307f4667a541f4937a37f869d2826eb5215783cf Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 20:07:21 -0800 Subject: [PATCH 18/23] Update pode.build.ps1 --- pode.build.ps1 | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 9fe535d33..9e567edf1 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -700,21 +700,17 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet # Invoke-PodeBuildInstall $dotnet $SdkVersion # } - if (Test-PodeBuildIsGitHub){ + <# if (Test-PodeBuildIsGitHub){ $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - dotnet --list-sdks - Write-Warning $sdkVersions $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] - Write-Warning "Majorversion=$majorVersions" $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions - Write-Warning "AvailableSdkVersion=$AvailableSdkVersion" if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { Write-Error "The requested framework '$SdkVersion' is not available." return } return } - +#> try { $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } } From e9e4ec6f181a09f97148b046ae89d3a663bd2e06 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 20:24:59 -0800 Subject: [PATCH 19/23] Update pode.build.ps1 --- pode.build.ps1 | 312 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 296 insertions(+), 16 deletions(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 9e567edf1..2fbde429a 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -107,7 +107,7 @@ param( [string[]] [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] - $TargetFrameworks = @('netstandard2.0', 'net8.0' ), + $TargetFrameworks = @('netstandard2.0', 'net8.0','net9.0'), [string] [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] @@ -127,23 +127,132 @@ $Versions = @{ # Helper Functions + +<# +.SYNOPSIS + Checks if the current environment is running on Windows. + +.DESCRIPTION + This function determines if the current PowerShell session is running on Windows. + It inspects `$PSVersionTable.Platform` and `$PSVersionTable.PSEdition` to verify the OS, + returning `$true` for Windows and `$false` for other platforms. + +.OUTPUTS + [bool] - Returns `$true` if the current environment is Windows, otherwise `$false`. + +.EXAMPLE + if (Test-PodeBuildIsWindows) { + Write-Host "This script is running on Windows." + } + +.NOTES + - Useful for cross-platform scripts to conditionally execute Windows-specific commands. + - The `$PSVersionTable.Platform` variable may be `$null` in certain cases, so `$PSEdition` is used as an additional check. +#> function Test-PodeBuildIsWindows { $v = $PSVersionTable return ($v.Platform -ilike '*win*' -or ($null -eq $v.Platform -and $v.PSEdition -ieq 'desktop')) } +<# +.SYNOPSIS + Checks if the script is running in a GitHub Actions environment. + +.DESCRIPTION + This function verifies if the script is running in a GitHub Actions environment + by checking if the `GITHUB_REF` environment variable is defined and not empty. + It returns `$true` if the variable is present, indicating a GitHub Actions environment. + +.OUTPUTS + [bool] - Returns `$true` if the script is running on GitHub Actions, otherwise `$false`. + +.EXAMPLE + if (Test-PodeBuildIsGitHub) { + Write-Host "Running in GitHub Actions." + } + +.NOTES + - This function is useful for CI/CD pipelines to identify if the script is running in GitHub Actions. + - Assumes that `GITHUB_REF` is always set in a GitHub Actions environment. +#> function Test-PodeBuildIsGitHub { return (![string]::IsNullOrWhiteSpace($env:GITHUB_REF)) } +<# +.SYNOPSIS + Checks if code coverage is enabled for the build. + +.DESCRIPTION + This function checks if code coverage is enabled by evaluating the `PODE_RUN_CODE_COVERAGE` + environment variable. If the variable contains '1' or 'true' (case-insensitive), it returns `$true`; + otherwise, it returns `$false`. + +.OUTPUTS + [bool] - Returns `$true` if code coverage is enabled, otherwise `$false`. + +.EXAMPLE + if (Test-PodeBuildCanCodeCoverage) { + Write-Host "Code coverage is enabled for this build." + } + +.NOTES + - Useful for conditional logic in build scripts that should only execute code coverage-related tasks if enabled. + - The `PODE_RUN_CODE_COVERAGE` variable is typically set by the CI/CD environment or the user. +#> function Test-PodeBuildCanCodeCoverage { return (@('1', 'true') -icontains $env:PODE_RUN_CODE_COVERAGE) } +<# +.SYNOPSIS + Returns the name of the CI/CD service being used for the build. + +.DESCRIPTION + This function returns a string representing the CI/CD service in use. + Currently, it always returns 'github-actions', indicating that the build + is running in GitHub Actions. + +.OUTPUTS + [string] - The name of the CI/CD service, which is 'github-actions'. + +.EXAMPLE + $service = Get-PodeBuildService + Write-Host "The build service is: $service" + # Output: The build service is: github-actions + +.NOTES + - This function is useful for identifying the CI/CD service in logs or reporting. + - Future modifications could extend this function to detect other CI/CD services. +#> function Get-PodeBuildService { return 'github-actions' } +<# +.SYNOPSIS + Checks if a specified command is available on the system. + +.DESCRIPTION + This function checks if a given command is available in the system's PATH. + On Windows, it uses `Get-Command`, and on Unix-based systems, it uses `which`. + It returns `$true` if the command exists and `$false` if it does not. + +.PARAMETER cmd + The name of the command to check for availability (e.g., 'choco', 'brew'). + +.OUTPUTS + [bool] - Returns `$true` if the command is found, otherwise `$false`. + +.EXAMPLE + if (Test-PodeBuildCommand -Cmd 'git') { + Write-Host "Git is available." + } + +.NOTES + - This function supports both Windows and Unix-based platforms. + - Requires `Test-PodeBuildIsWindows` to detect the OS type. +#> function Test-PodeBuildCommand($cmd) { $path = $null @@ -157,10 +266,59 @@ function Test-PodeBuildCommand($cmd) { return (![string]::IsNullOrWhiteSpace($path)) } +<# +.SYNOPSIS + Retrieves the branch name from the GitHub Actions environment variable. + +.DESCRIPTION + This function extracts the branch name from the `GITHUB_REF` environment variable, + which is commonly set in GitHub Actions workflows. It removes the 'refs/heads/' prefix + from the branch reference, leaving only the branch name. + +.OUTPUTS + [string] - The name of the GitHub branch. + +.EXAMPLE + $branch = Get-PodeBuildBranch + Write-Host "Current branch: $branch" + # Output example: Current branch: main + +.NOTES + - Only relevant in environments where `GITHUB_REF` is defined (e.g., GitHub Actions). + - Returns an empty string if `GITHUB_REF` is not set. +#> function Get-PodeBuildBranch { return ($env:GITHUB_REF -ireplace 'refs\/heads\/', '') } +<# +.SYNOPSIS + Installs a specified package using the appropriate package manager for the OS. + +.DESCRIPTION + This function installs a specified package at a given version using platform-specific + package managers. For Windows, it uses Chocolatey (`choco`). On Unix-based systems, + it checks for `brew`, `apt-get`, and `yum` to handle installations. The function sets + the security protocol to TLS 1.2 to ensure secure connections during the installation. + +.PARAMETER name + The name of the package to install (e.g., 'git'). + +.PARAMETER version + The version of the package to install, required only for Chocolatey on Windows. + +.OUTPUTS + None. + +.EXAMPLE + Invoke-PodeBuildInstall -Name 'git' -Version '2.30.0' + # Installs version 2.30.0 of Git on Windows if Chocolatey is available. + +.NOTES + - Requires administrator or sudo privileges on Unix-based systems. + - This function supports package installation on both Windows and Unix-based systems. + - If `choco` is available, it will use `choco` for Windows, and `brew`, `apt-get`, or `yum` for Unix-based systems. +#> function Invoke-PodeBuildInstall($name, $version) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 @@ -182,6 +340,30 @@ function Invoke-PodeBuildInstall($name, $version) { } } +<# +.SYNOPSIS + Installs a specified PowerShell module if it is not already installed at the required version. + +.DESCRIPTION + This function checks if the specified PowerShell module is available in the current session + at the specified version. If not, it installs the module using the PowerShell Gallery, setting + the security protocol to TLS 1.2. The module is installed in the current user's scope. + +.PARAMETER name + The name of the PowerShell module to check and install. + +.OUTPUTS + None. + +.EXAMPLE + Install-PodeBuildModule -Name 'Pester' + # Installs the 'Pester' module if the specified version is not already installed. + +.NOTES + - Uses `$Versions` hashtable to look up the required version for the module. + - Requires internet access to download modules from the PowerShell Gallery. + - The `-SkipPublisherCheck` parameter bypasses publisher verification; use with caution. +#> function Install-PodeBuildModule($name) { if ($null -ne ((Get-Module -ListAvailable $name) | Where-Object { $_.Version -ieq $Versions[$name] })) { return @@ -192,6 +374,29 @@ function Install-PodeBuildModule($name) { Install-Module -Name "$($name)" -Scope CurrentUser -RequiredVersion "$($Versions[$name])" -Force -SkipPublisherCheck } +<# +.SYNOPSIS + Converts a .NET target framework identifier to a numeric version. + +.DESCRIPTION + This function maps common .NET target framework identifiers (e.g., 'netstandard2.0', 'net6.0') to their + numeric equivalents. It is used to ensure compatibility by returning the framework version number as an integer. + +.PARAMETER TargetFrameworks + The target framework identifier (e.g., 'netstandard2.0', 'net6.0'). + +.OUTPUTS + [int] - The numeric version of the target framework. Defaults to 2 if an unrecognized framework is provided. + +.EXAMPLE + $version = Get-TargetFramework -TargetFrameworks 'net6.0' + Write-Host "Target framework version: $version" + # Output: Target framework version: 6 + +.NOTES + - Returns 2 (netstandard2.0) by default if the input framework is not recognized. + - This function is useful in build scripts that require target framework versioning. +#> function Get-TargetFramework { param( [string] @@ -214,7 +419,29 @@ function Get-TargetFramework { } } +<# +.SYNOPSIS + Converts a .NET target framework version number to a framework identifier. +.DESCRIPTION + This function maps a numeric version to a .NET target framework identifier (e.g., '2' to 'netstandard2.0'). + If the version number is not recognized, it defaults to 'netstandard2.0'. + +.PARAMETER Version + The numeric version of the .NET target framework (e.g., 2, 6, 8). + +.OUTPUTS + [string] - The target framework identifier (e.g., 'netstandard2.0'). + +.EXAMPLE + $frameworkName = Get-TargetFrameworkName -Version 6 + Write-Host "Target framework name: $frameworkName" + # Output: Target framework name: net6.0 + +.NOTES + - Returns 'netstandard2.0' by default if an unrecognized version is provided. + - Useful for converting numeric framework versions to identifier strings in build processes. +#> function Get-TargetFrameworkName { param( $Version @@ -284,6 +511,30 @@ function Invoke-PodeBuildDotnetBuild { } } +<# +.SYNOPSIS + Retrieves the end-of-life (EOL) and supported versions of PowerShell. + +.DESCRIPTION + This function queries an online API to retrieve the EOL and supported versions of PowerShell. + It uses the `Invoke-RestMethod` cmdlet to access data from endoflife.date and returns an object + with comma-separated lists of supported and EOL PowerShell versions based on the current date. + +.OUTPUTS + [hashtable] - A hashtable containing: + - `eol`: Comma-separated string of EOL PowerShell versions. + - `supported`: Comma-separated string of supported PowerShell versions. + +.EXAMPLE + $pwshEOLInfo = Get-PodeBuildPwshEOL + Write-Host "Supported PowerShell versions: $($pwshEOLInfo.supported)" + Write-Host "EOL PowerShell versions: $($pwshEOLInfo.eol)" + +.NOTES + - Requires internet access to query the endoflife.date API. + - If the request fails, the function returns an empty string for both `eol` and `supported`. + - API URL: https://endoflife.date/api/powershell.json +#> function Get-PodeBuildPwshEOL { $uri = 'https://endoflife.date/api/powershell.json' try { @@ -302,14 +553,58 @@ function Get-PodeBuildPwshEOL { } } +<# +.SYNOPSIS + Checks if the current OS is Windows. +.DESCRIPTION + This function detects whether the current operating system is Windows by checking + the `$IsWindows` automatic variable, the presence of the `$env:ProgramFiles` variable, + and the PowerShell Edition in `$PSVersionTable`. This function returns `$true` if + any of these indicate Windows. +.OUTPUTS + [bool] - Returns `$true` if the OS is Windows, otherwise `$false`. + +.EXAMPLE + if (Test-PodeBuildOSWindows) { + Write-Host "Running on Windows" + } + +.NOTES + - Useful for distinguishing between Windows and Unix-based systems for conditional logic. + - May return `$true` in environments where Windows-related environment variables are present. +#> function Test-PodeBuildOSWindows { return ($IsWindows -or ![string]::IsNullOrEmpty($env:ProgramFiles) -or (($PSVersionTable.Keys -contains 'PSEdition') -and ($PSVersionTable.PSEdition -eq 'Desktop'))) } +<# +.SYNOPSIS + Retrieves the current OS name in a PowerShell-compatible format. + +.DESCRIPTION + This function identifies the current operating system and returns a standardized string + representing the OS name ('win' for Windows, 'linux' for Linux, and 'osx' for macOS). + It relies on the `Test-PodeBuildOSWindows` function for Windows detection and `$IsLinux` + and `$IsMacOS` for Linux and macOS, respectively. + +.OUTPUTS + [string] - A string representing the OS name: + - 'win' for Windows + - 'linux' for Linux + - 'osx' for macOS + +.EXAMPLE + $osName = Get-PodeBuildOSPwshName + Write-Host "Operating system name: $osName" + +.NOTES + - This function enables cross-platform compatibility by standardizing OS name detection. + - For accurate results, ensure `$IsLinux` and `$IsMacOS` variables are defined for Unix-like systems. +#> function Get-PodeBuildOSPwshName { if (Test-PodeBuildOSWindows) { return 'win' @@ -696,21 +991,6 @@ if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParamet $dotnet = "dotnet-sdk-$SdkVersion" } - # if (!(Test-PodeBuildCommand 'dotnet')) { - # Invoke-PodeBuildInstall $dotnet $SdkVersion - # } - - <# if (Test-PodeBuildIsGitHub){ - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] - $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions - if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Write-Error "The requested framework '$SdkVersion' is not available." - return - } - return - } -#> try { $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } } From 8cdc7c82742ab6765ebb7a4bd04acfff58016f36 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Thu, 14 Nov 2024 20:28:23 -0800 Subject: [PATCH 20/23] Update pode.build.ps1 --- pode.build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pode.build.ps1 b/pode.build.ps1 index 2fbde429a..4077c7cbe 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -845,7 +845,7 @@ function Invoke-PodeBuildDockerBuild { ) # Build the Docker image with the specified tag and Dockerfile - docker build -t badgerati/pode:$tTag -f $File . + docker build -t badgerati/pode:$Tag -f $File . if (!$?) { throw "docker build failed for $($Tag)" } From 613ebbf1f2d25c0aa06cfb98a05ce569953b5773 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Fri, 22 Nov 2024 14:16:52 -0800 Subject: [PATCH 21/23] improvements --- .github/workflows/VirusTotal-Releases.yml | 10 + .github/workflows/VirusTotal.yml | 15 +- .github/workflows/ci-coverage.yml | 2 +- .github/workflows/ci-docs.yml | 2 +- .github/workflows/ci-powershell.yml | 2 +- .github/workflows/ci-pwsh7_2.yml | 4 +- .github/workflows/ci-pwsh7_5.yml | 79 ++ .github/workflows/ci-pwsh_lts.yml | 2 +- .github/workflows/ci-pwsh_preview.yml | 2 +- pode.build.ps1 | 1335 ++++++++++----------- 10 files changed, 774 insertions(+), 679 deletions(-) create mode 100644 .github/workflows/ci-pwsh7_5.yml diff --git a/.github/workflows/VirusTotal-Releases.yml b/.github/workflows/VirusTotal-Releases.yml index 44d331890..4e7ffd046 100644 --- a/.github/workflows/VirusTotal-Releases.yml +++ b/.github/workflows/VirusTotal-Releases.yml @@ -9,6 +9,16 @@ jobs: runs-on: ubuntu-latest steps: + - name: Check VIRUSTOTAL_API_KEY + env: + VIRUSTOTAL_API_KEY: ${{ secrets.VIRUSTOTAL_API_KEY }} + run: | + if [ -z "$VIRUSTOTAL_API_KEY" ]; then + echo "VIRUSTOTAL_API_KEY is not set. Exiting workflow." + exit 1 + fi + echo "VIRUSTOTAL_API_KEY is set. Proceeding with the workflow. + - name: Run VirusTotal Scan uses: crazy-max/ghaction-virustotal@v4 with: diff --git a/.github/workflows/VirusTotal.yml b/.github/workflows/VirusTotal.yml index 8faaad8d4..2e1ddc290 100644 --- a/.github/workflows/VirusTotal.yml +++ b/.github/workflows/VirusTotal.yml @@ -19,14 +19,25 @@ on: - cron: '0 12 * * *' env: - INVOKE_BUILD_VERSION: '5.11.1' + INVOKE_BUILD_VERSION: '5.12.0' POWERSHELL_VERSION: 'lts' jobs: build: runs-on: ubuntu-latest - steps: + + + - name: Check VIRUSTOTAL_API_KEY + env: + VIRUSTOTAL_API_KEY: ${{ secrets.VIRUSTOTAL_API_KEY }} + run: | + if [ -z "$VIRUSTOTAL_API_KEY" ]; then + echo "VIRUSTOTAL_API_KEY is not set. Exiting workflow." + exit 1 + fi + echo "VIRUSTOTAL_API_KEY is set. Proceeding with the workflow. + - uses: actions/checkout@v4 - name: Setup .NET diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml index 8847cfab6..c64594877 100644 --- a/.github/workflows/ci-coverage.yml +++ b/.github/workflows/ci-coverage.yml @@ -20,7 +20,7 @@ on: - '.github/workflows/ci-coverage.yml' env: - INVOKE_BUILD_VERSION: '5.11.1' + INVOKE_BUILD_VERSION: '5.12.0' jobs: build: diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index dc2aaf2b1..02ad1c82f 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -24,7 +24,7 @@ on: - 'src/Pode.psd1' env: - INVOKE_BUILD_VERSION: '5.11.1' + INVOKE_BUILD_VERSION: '5.12.0' jobs: build: diff --git a/.github/workflows/ci-powershell.yml b/.github/workflows/ci-powershell.yml index 1b071fe4a..adc4cd1f2 100644 --- a/.github/workflows/ci-powershell.yml +++ b/.github/workflows/ci-powershell.yml @@ -20,7 +20,7 @@ on: - '.github/workflows/ci-powershell.yml' env: - INVOKE_BUILD_VERSION: '5.11.1' + INVOKE_BUILD_VERSION: '5.12.0' jobs: build: diff --git a/.github/workflows/ci-pwsh7_2.yml b/.github/workflows/ci-pwsh7_2.yml index 8d37e5af5..67602bb8b 100644 --- a/.github/workflows/ci-pwsh7_2.yml +++ b/.github/workflows/ci-pwsh7_2.yml @@ -24,8 +24,8 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.11.1' - POWERSHELL_VERSION: '7.2.24' + INVOKE_BUILD_VERSION: '5.12.0' + POWERSHELL_VERSION: '7.5.0' jobs: build: diff --git a/.github/workflows/ci-pwsh7_5.yml b/.github/workflows/ci-pwsh7_5.yml new file mode 100644 index 000000000..b5faba8cd --- /dev/null +++ b/.github/workflows/ci-pwsh7_5.yml @@ -0,0 +1,79 @@ +name: Pode CI - pwsh 7.5 + +on: + push: + branches: + - '*' + - '!gh-pages' + paths: + - 'src/**' + - 'tests/**' + - 'pode.build.ps1' + - '.github/workflows/ci-pwsh7_5.yml' + - 'Dockerfile' + - '*.dockerfile' + pull_request: + branches: + - '*' + paths: + - 'src/**' + - 'tests/**' + - 'pode.build.ps1' + - '.github/workflows/ci-pwsh7_5.yml' + - 'Dockerfile' + - '*.dockerfile' + +env: + INVOKE_BUILD_VERSION: '5.12.1' + POWERSHELL_VERSION: '7.2.24' + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.x + + - name: Setup Powershell - Unix + shell: pwsh + if: runner.os == 'Linux' || runner.os == 'macOS' + run: | + Install-Module -Name InvokeBuild -RequiredVersion $env:INVOKE_BUILD_VERSION -Force + Invoke-Build SetupPowerShell -PowerShellVersion $env:POWERSHELL_VERSION + + - name: Setup Powershell - Windows + shell: PowerShell + if: runner.os == 'Windows' + run: | + Install-Module -Name InvokeBuild -RequiredVersion $env:INVOKE_BUILD_VERSION -Force + Invoke-Build SetupPowerShell -PowerShellVersion $env:POWERSHELL_VERSION + + - name: Output PowerShell version + shell: pwsh + run: | + $PSVersionTable.PSVersion + + - name: Install Invoke-Build + shell: pwsh + run: | + Install-Module -Name InvokeBuild -RequiredVersion $env:INVOKE_BUILD_VERSION -Force + + - name: Run Pester Tests + shell: pwsh + run: | + Invoke-Build Test + + - name: Build Packages + shell: pwsh + run: | + Invoke-Build Pack \ No newline at end of file diff --git a/.github/workflows/ci-pwsh_lts.yml b/.github/workflows/ci-pwsh_lts.yml index 29a74a2df..70ab3d0d3 100644 --- a/.github/workflows/ci-pwsh_lts.yml +++ b/.github/workflows/ci-pwsh_lts.yml @@ -24,7 +24,7 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.11.1' + INVOKE_BUILD_VERSION: '5.12.0' POWERSHELL_VERSION: 'lts' jobs: diff --git a/.github/workflows/ci-pwsh_preview.yml b/.github/workflows/ci-pwsh_preview.yml index 6abca6cde..d9dcee85c 100644 --- a/.github/workflows/ci-pwsh_preview.yml +++ b/.github/workflows/ci-pwsh_preview.yml @@ -24,7 +24,7 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.11.1' + INVOKE_BUILD_VERSION: '5.12.1' POWERSHELL_VERSION: 'Preview' jobs: diff --git a/pode.build.ps1 b/pode.build.ps1 index 4077c7cbe..e2b67f2bd 100644 --- a/pode.build.ps1 +++ b/pode.build.ps1 @@ -106,11 +106,11 @@ param( $UICulture = 'en-US', [string[]] - [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] - $TargetFrameworks = @('netstandard2.0', 'net8.0','net9.0'), + [ValidateSet('netstandard2.0', 'net8.0', 'net9.0', 'net10.0')] + $TargetFrameworks = @('netstandard2.0', 'net8.0', 'net9.0'), [string] - [ValidateSet('netstandard2.0', 'netstandard2.1', 'netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')] + [ValidateSet('netstandard2.0', 'net8.0', 'net9.0', 'net10.0')] $SdkVersion = 'net9.0' ) @@ -389,7 +389,7 @@ function Install-PodeBuildModule($name) { [int] - The numeric version of the target framework. Defaults to 2 if an unrecognized framework is provided. .EXAMPLE - $version = Get-TargetFramework -TargetFrameworks 'net6.0' + $version = Get-PodeTargetFramework -TargetFrameworks 'net6.0' Write-Host "Target framework version: $version" # Output: Target framework version: 6 @@ -397,7 +397,7 @@ function Install-PodeBuildModule($name) { - Returns 2 (netstandard2.0) by default if the input framework is not recognized. - This function is useful in build scripts that require target framework versioning. #> -function Get-TargetFramework { +function Get-PodeTargetFramework { param( [string] $TargetFrameworks @@ -405,13 +405,9 @@ function Get-TargetFramework { switch ($TargetFrameworks) { 'netstandard2.0' { return 2 } - 'netstandard2.1' { return 3 } - 'netcoreapp3.0' { return 3 } - 'net5.0' { return 5 } - 'net6.0' { return 6 } - 'net7.0' { return 7 } 'net8.0' { return 8 } 'net9.0' { return 9 } + 'net10.0' { return 10 } default { Write-Warning "$TargetFrameworks is not a valid Framework. Rollback to netstandard2.0" return 2 @@ -434,7 +430,7 @@ function Get-TargetFramework { [string] - The target framework identifier (e.g., 'netstandard2.0'). .EXAMPLE - $frameworkName = Get-TargetFrameworkName -Version 6 + $frameworkName = Get-PodeTargetFrameworkName -Version 6 Write-Host "Target framework name: $frameworkName" # Output: Target framework name: net6.0 @@ -442,7 +438,7 @@ function Get-TargetFramework { - Returns 'netstandard2.0' by default if an unrecognized version is provided. - Useful for converting numeric framework versions to identifier strings in build processes. #> -function Get-TargetFrameworkName { +function Get-PodeTargetFrameworkName { param( $Version ) @@ -473,7 +469,7 @@ function Invoke-PodeBuildDotnetBuild { $majorVersions = $sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique } else { - $majorVersions = $sdkVersions.Where( { ([version]$_).Major -ge (Get-TargetFramework -TargetFrameworks $AvailableSdkVersion) } ) | Sort-Object -Descending | Select-Object -Unique + $majorVersions = $sdkVersions.Where( { ([version]$_).Major -ge (Get-PodeTargetFramework -TargetFrameworks $AvailableSdkVersion) } ) | Sort-Object -Descending | Select-Object -Unique } # Map target frameworks to minimum SDK versions @@ -481,7 +477,7 @@ function Invoke-PodeBuildDotnetBuild { Write-Error "The requested '$AvailableSdkVersion' framework is not available." return } - $requiredSdkVersion = Get-TargetFramework -TargetFrameworks $target + $requiredSdkVersion = Get-PodeTargetFramework -TargetFrameworks $target # Determine if the target framework is compatible $isCompatible = $majorVersions -ge $requiredSdkVersion @@ -891,847 +887,846 @@ function Split-PodeBuildPwshPath { # Check if the script is running under Invoke-Build -if (($null -ne $PSCmdlet.MyInvocation) -and ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BuildRoot') -or $null -ne $BuildRoot)) { - - - Add-BuildTask Default { - Write-Host 'Tasks in the Build Script:' -ForegroundColor DarkMagenta - Write-Host - Write-Host 'Primary Tasks:' -ForegroundColor Green - Write-Host '- Default: Lists all available tasks.' - Write-Host '- Build: Builds the .NET Listener for specified frameworks.' - Write-Host '- Pack: Packages the module, including ZIP, Chocolatey, and Docker.' - Write-Host '- Test: Runs tests after building the project.' - Write-Host '- Clean: Cleans the build environment, removing all generated files.' - Write-Host '- Install-Module: Installs the Pode module locally.' - Write-Host '- Remove-Module: Removes the Pode module from the local registry.' - Write-Host '- DocsBuild: Builds the documentation for distribution.' - Write-Host '- TestNoBuild: Runs tests without building, including Pester tests.' - - - Write-Host - Write-Host 'Other Tasks:' -ForegroundColor Green - Write-Host '- StampVersion: Stamps the specified version onto the module.' - Write-Host '- PrintChecksum: Generates and displays a checksum of the ZIP archive.' - Write-Host '- ChocoDeps: Installs Chocolatey (for Windows).' - Write-Host '- PackDeps: Installs dependencies required for packaging.' - Write-Host '- BuildDeps: Installs dependencies required for building/compiling.' - Write-Host '- TestDeps: Installs dependencies required for testing.' - Write-Host '- DocsDeps: Installs dependencies required for documentation generation.' - Write-Host '- IndexSamples: Indexes sample files for documentation.' - Write-Host '- 7Zip: Creates a ZIP archive of the module (Windows only).' - Write-Host '- DeliverableFolder: Creates a folder for deliverables.' - Write-Host '- Compress: Compresses the module into a ZIP format for distribution.' - Write-Host '- ChocoPack: Creates a Chocolatey package of the module (Windows only).' - Write-Host '- DockerPack: Builds Docker images for the module.' - Write-Host "- PackageFolder: Creates the `pkg` folder for module packaging." - Write-Host '- CheckFailedTests: Checks if any tests failed and throws an error if so.' - Write-Host '- PushCodeCoverage: Pushes code coverage results to a coverage service.' - Write-Host '- Docs: Serves the documentation locally for review.' - Write-Host '- DocsHelpBuild: Builds function help documentation.' - Write-Host "- CleanDeliverable: Removes the `deliverable` folder." - Write-Host "- CleanPkg: Removes the `pkg` folder." - Write-Host "- CleanLibs: Removes the `Libs` folder under `src`." - Write-Host '- CleanListener: Removes the Listener folder.' - Write-Host '- CleanDocs: Cleans up generated documentation files.' - Write-Host '- SetupPowerShell: Sets up the PowerShell environment for the build.' - Write-Host '- ReleaseNotes: Generates release notes based on merged pull requests.' - } - - - <# +if (($null -eq $PSCmdlet.MyInvocation) -or ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BuildRoot') -and ($null -eq $BuildRoot))) { + Write-Host 'This script is intended to be run with Invoke-Build. Please use Invoke-Build to execute the tasks defined in this script.' -ForegroundColor Yellow + return +} + + +Add-BuildTask Default { + Write-Host 'Tasks in the Build Script:' -ForegroundColor DarkMagenta + Write-Host + Write-Host 'Primary Tasks:' -ForegroundColor Green + Write-Host '- Default: Lists all available tasks.' + Write-Host '- Build: Builds the .NET Listener for specified frameworks.' + Write-Host '- Pack: Packages the module, including ZIP, Chocolatey, and Docker.' + Write-Host '- Test: Runs tests after building the project.' + Write-Host '- Clean: Cleans the build environment, removing all generated files.' + Write-Host '- Install-Module: Installs the Pode module locally.' + Write-Host '- Remove-Module: Removes the Pode module from the local registry.' + Write-Host '- DocsBuild: Builds the documentation for distribution.' + Write-Host '- TestNoBuild: Runs tests without building, including Pester tests.' + + + Write-Host + Write-Host 'Other Tasks:' -ForegroundColor Green + Write-Host '- StampVersion: Stamps the specified version onto the module.' + Write-Host '- PrintChecksum: Generates and displays a checksum of the ZIP archive.' + Write-Host '- ChocoDeps: Installs Chocolatey (for Windows).' + Write-Host '- PackDeps: Installs dependencies required for packaging.' + Write-Host '- BuildDeps: Installs dependencies required for building/compiling.' + Write-Host '- TestDeps: Installs dependencies required for testing.' + Write-Host '- DocsDeps: Installs dependencies required for documentation generation.' + Write-Host '- IndexSamples: Indexes sample files for documentation.' + Write-Host '- 7Zip: Creates a ZIP archive of the module (Windows only).' + Write-Host '- DeliverableFolder: Creates a folder for deliverables.' + Write-Host '- Compress: Compresses the module into a ZIP format for distribution.' + Write-Host '- ChocoPack: Creates a Chocolatey package of the module (Windows only).' + Write-Host '- DockerPack: Builds Docker images for the module.' + Write-Host "- PackageFolder: Creates the `pkg` folder for module packaging." + Write-Host '- CheckFailedTests: Checks if any tests failed and throws an error if so.' + Write-Host '- PushCodeCoverage: Pushes code coverage results to a coverage service.' + Write-Host '- Docs: Serves the documentation locally for review.' + Write-Host '- DocsHelpBuild: Builds function help documentation.' + Write-Host "- CleanDeliverable: Removes the `deliverable` folder." + Write-Host "- CleanPkg: Removes the `pkg` folder." + Write-Host "- CleanLibs: Removes the `Libs` folder under `src`." + Write-Host '- CleanListener: Removes the Listener folder.' + Write-Host '- CleanDocs: Cleans up generated documentation files.' + Write-Host '- SetupPowerShell: Sets up the PowerShell environment for the build.' + Write-Host '- ReleaseNotes: Generates release notes based on merged pull requests.' +} + + +<# # Helper Tasks #> - # Synopsis: Stamps the version onto the Module - Add-BuildTask StampVersion { - $pwshVersions = Get-PodeBuildPwshEOL +# Synopsis: Stamps the version onto the Module +Add-BuildTask StampVersion { + $pwshVersions = Get-PodeBuildPwshEOL (Get-Content ./pkg/Pode.psd1) | ForEach-Object { $_ -replace '\$version\$', $Version -replace '\$versionsUntested\$', $pwshVersions.eol -replace '\$versionsSupported\$', $pwshVersions.supported -replace '\$buildyear\$', ((get-date).Year) } | Set-Content ./pkg/Pode.psd1 (Get-Content ./pkg/Pode.Internal.psd1) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./pkg/Pode.Internal.psd1 (Get-Content ./packers/choco/pode_template.nuspec) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./packers/choco/pode.nuspec (Get-Content ./packers/choco/tools/ChocolateyInstall_template.ps1) | ForEach-Object { $_ -replace '\$version\$', $Version } | Set-Content ./packers/choco/tools/ChocolateyInstall.ps1 - } +} - # Synopsis: Generating a Checksum of the Zip - Add-BuildTask PrintChecksum { - $Script:Checksum = (Get-FileHash "./deliverable/$Version-Binaries.zip" -Algorithm SHA256).Hash - Write-Host "Checksum: $($Checksum)" - } +# Synopsis: Generating a Checksum of the Zip +Add-BuildTask PrintChecksum { + $Script:Checksum = (Get-FileHash "./deliverable/$Version-Binaries.zip" -Algorithm SHA256).Hash + Write-Host "Checksum: $($Checksum)" +} - <# +<# # Dependencies #> - # Synopsis: Installs Chocolatey - Add-BuildTask ChocoDeps -If (Test-PodeBuildIsWindows) { - if (!(Test-PodeBuildCommand 'choco')) { - Set-ExecutionPolicy Bypass -Scope Process -Force - Invoke-Expression ([System.Net.WebClient]::new().DownloadString('https://chocolatey.org/install.ps1')) - } +# Synopsis: Installs Chocolatey +Add-BuildTask ChocoDeps -If (Test-PodeBuildIsWindows) { + if (!(Test-PodeBuildCommand 'choco')) { + Set-ExecutionPolicy Bypass -Scope Process -Force + Invoke-Expression ([System.Net.WebClient]::new().DownloadString('https://chocolatey.org/install.ps1')) } +} - # Synopsis: Install dependencies for packaging - Add-BuildTask PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, { - if (!(Test-PodeBuildCommand '7z')) { - Invoke-PodeBuildInstall '7zip' $Versions.SevenZip - } +# Synopsis: Install dependencies for packaging +Add-BuildTask PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, { + if (!(Test-PodeBuildCommand '7z')) { + Invoke-PodeBuildInstall '7zip' $Versions.SevenZip } +} - # Synopsis: Install dependencies for compiling/building - Add-BuildTask BuildDeps { - # install dotnet - if (Test-PodeBuildIsWindows) { - $dotnet = 'dotnet' - } - elseif (Test-PodeBuildCommand 'brew') { - $dotnet = 'dotnet-sdk' - } - else { - $dotnet = "dotnet-sdk-$SdkVersion" - } +# Synopsis: Install dependencies for compiling/building +Add-BuildTask BuildDeps { + # install dotnet + if (Test-PodeBuildIsWindows) { + $dotnet = 'dotnet' + } + elseif (Test-PodeBuildCommand 'brew') { + $dotnet = 'dotnet-sdk' + } + else { + $dotnet = "dotnet-sdk-$SdkVersion" + } - try { - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - } - catch { - Invoke-PodeBuildInstall $dotnet $SdkVersion - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - } - $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] - $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions + try { + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + } + catch { + Invoke-PodeBuildInstall $dotnet $SdkVersion + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + } + $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] + $script:AvailableSdkVersion = Get-PodeTargetFrameworkName -Version $majorVersions - if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Invoke-PodeBuildInstall $dotnet $SdkVersion - $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } - $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] - $script:AvailableSdkVersion = Get-TargetFrameworkName -Version $majorVersions + if ($majorVersions -lt (Get-PodeTargetFramework -TargetFrameworks $SdkVersion)) { + Invoke-PodeBuildInstall $dotnet $SdkVersion + $sdkVersions = dotnet --list-sdks | ForEach-Object { $_.Split('[')[0].Trim() } + $majorVersions = ($sdkVersions | ForEach-Object { ([version]$_).Major } | Sort-Object -Descending | Select-Object -Unique)[0] + $script:AvailableSdkVersion = Get-PodeTargetFrameworkName -Version $majorVersions - if ($majorVersions -lt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Write-Error "The requested framework '$SdkVersion' is not available." - return - } - } - elseif ($majorVersions -gt (Get-TargetFramework -TargetFrameworks $SdkVersion)) { - Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." + if ($majorVersions -lt (Get-PodeTargetFramework -TargetFrameworks $SdkVersion)) { + Write-Error "The requested framework '$SdkVersion' is not available." + return } - } + elseif ($majorVersions -gt (Get-PodeTargetFramework -TargetFrameworks $SdkVersion)) { + Write-Warning "The requested SDK version '$SdkVersion' is superseded by the installed '$($script:AvailableSdkVersion)' framework." + } + +} - # Synopsis: Install dependencies for running tests - Add-BuildTask TestDeps { - # install pester - Install-PodeBuildModule Pester +# Synopsis: Install dependencies for running tests +Add-BuildTask TestDeps { + # install pester + Install-PodeBuildModule Pester - # install PSCoveralls - if (Test-PodeBuildCanCodeCoverage) { - Install-PodeBuildModule PSCoveralls - } + # install PSCoveralls + if (Test-PodeBuildCanCodeCoverage) { + Install-PodeBuildModule PSCoveralls } +} - # Synopsis: Install dependencies for documentation - Add-BuildTask DocsDeps ChocoDeps, { - # install mkdocs - if (!(Test-PodeBuildCommand 'mkdocs')) { - Invoke-PodeBuildInstall 'mkdocs' $Versions.MkDocs - } +# Synopsis: Install dependencies for documentation +Add-BuildTask DocsDeps ChocoDeps, { + # install mkdocs + if (!(Test-PodeBuildCommand 'mkdocs')) { + Invoke-PodeBuildInstall 'mkdocs' $Versions.MkDocs + } - $_installed = (pip list --format json --disable-pip-version-check | ConvertFrom-Json) - if (($_installed | Where-Object { $_.name -ieq 'mkdocs-material' -and $_.version -ieq $Versions.MkDocsTheme } | Measure-Object).Count -eq 0) { - pip install "mkdocs-material==$($Versions.MkDocsTheme)" --force-reinstall --disable-pip-version-check --quiet - } + $_installed = (pip list --format json --disable-pip-version-check | ConvertFrom-Json) + if (($_installed | Where-Object { $_.name -ieq 'mkdocs-material' -and $_.version -ieq $Versions.MkDocsTheme } | Measure-Object).Count -eq 0) { + pip install "mkdocs-material==$($Versions.MkDocsTheme)" --force-reinstall --disable-pip-version-check --quiet + } - # install platyps - Install-PodeBuildModule PlatyPS + # install platyps + Install-PodeBuildModule PlatyPS +} + +Add-BuildTask IndexSamples { + $examplesPath = './examples' + if (!(Test-Path -PathType Container -Path $examplesPath)) { + return } - Add-BuildTask IndexSamples { - $examplesPath = './examples' - if (!(Test-Path -PathType Container -Path $examplesPath)) { - return - } + # List of directories to exclude + $sampleMarkDownPath = './docs/Getting-Started/Samples.md' + $excludeDirs = @('scripts', 'views', 'static', 'public', 'assets', 'timers', 'modules', + 'Authentication', 'certs', 'logs', 'relative', 'routes', 'issues') - # List of directories to exclude - $sampleMarkDownPath = './docs/Getting-Started/Samples.md' - $excludeDirs = @('scripts', 'views', 'static', 'public', 'assets', 'timers', 'modules', - 'Authentication', 'certs', 'logs', 'relative', 'routes', 'issues') - - # Convert exlusion list into single regex pattern for directory matching - $dirSeparator = [IO.Path]::DirectorySeparatorChar - $excludeDirs = "\$($dirSeparator)($($excludeDirs -join '|'))\$($dirSeparator)" - - # build the page content - Get-ChildItem -Path $examplesPath -Filter *.ps1 -Recurse -File -Force | - Where-Object { - $_.FullName -inotmatch $excludeDirs - } | - Sort-Object -Property FullName | - ForEach-Object { - Write-Verbose "Processing Sample: $($_.FullName)" - - # get the script help - $help = Get-Help -Name $_.FullName -ErrorAction Stop - - # add help content - $urlFileName = ($_.FullName -isplit 'examples')[1].Trim('\/') -replace '[\\/]', '/' - $markdownContent += "## [$($_.BaseName)](https://github.com/Badgerati/Pode/blob/develop/examples/$($urlFileName))`n`n" - $markdownContent += "**Synopsis**`n`n$($help.Synopsis)`n`n" - $markdownContent += "**Description**`n`n$($help.Description.Text)`n`n" - } + # Convert exlusion list into single regex pattern for directory matching + $dirSeparator = [IO.Path]::DirectorySeparatorChar + $excludeDirs = "\$($dirSeparator)($($excludeDirs -join '|'))\$($dirSeparator)" - Write-Output "Write Markdown document for the sample files to $($sampleMarkDownPath)" - Set-Content -Path $sampleMarkDownPath -Value "# Sample Scripts`n`n$($markdownContent)" -Force - } + # build the page content + Get-ChildItem -Path $examplesPath -Filter *.ps1 -Recurse -File -Force | + Where-Object { + $_.FullName -inotmatch $excludeDirs + } | + Sort-Object -Property FullName | + ForEach-Object { + Write-Verbose "Processing Sample: $($_.FullName)" + + # get the script help + $help = Get-Help -Name $_.FullName -ErrorAction Stop - <# + # add help content + $urlFileName = ($_.FullName -isplit 'examples')[1].Trim('\/') -replace '[\\/]', '/' + $markdownContent += "## [$($_.BaseName)](https://github.com/Badgerati/Pode/blob/develop/examples/$($urlFileName))`n`n" + $markdownContent += "**Synopsis**`n`n$($help.Synopsis)`n`n" + $markdownContent += "**Description**`n`n$($help.Description.Text)`n`n" + } + + Write-Output "Write Markdown document for the sample files to $($sampleMarkDownPath)" + Set-Content -Path $sampleMarkDownPath -Value "# Sample Scripts`n`n$($markdownContent)" -Force +} + +<# # Building #> - # Synopsis: Build the .NET Listener - Add-BuildTask Build BuildDeps, { - if (Test-Path ./src/Libs) { - Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null - } +# Synopsis: Build the .NET Listener +Add-BuildTask Build BuildDeps, { + if (Test-Path ./src/Libs) { + Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null + } - # Retrieve the SDK version being used - # $dotnetVersion = dotnet --version + # Retrieve the SDK version being used + # $dotnetVersion = dotnet --version - # Display the SDK version - Write-Output "Building targets '$($targetFrameworks -join "','")' using .NET '$AvailableSdkVersion' framework." + # Display the SDK version + Write-Output "Building targets '$($targetFrameworks -join "','")' using .NET '$AvailableSdkVersion' framework." - # Build for supported target frameworks - try { - Push-Location ./src/Listener - foreach ($target in $targetFrameworks) { - Invoke-PodeBuildDotnetBuild -target $target - Write-Host - Write-Host '***********************' -ForegroundColor DarkMagenta + # Build for supported target frameworks + try { + Push-Location ./src/Listener + foreach ($target in $targetFrameworks) { + Invoke-PodeBuildDotnetBuild -target $target + Write-Host + Write-Host '***********************' -ForegroundColor DarkMagenta - } } - finally { - Pop-Location - } - } + finally { + Pop-Location + } + +} - <# +<# # Packaging #> - # Synopsis: Creates a Zip of the Module - Add-BuildTask 7Zip -If (Test-PodeBuildIsWindows) PackDeps, StampVersion, { - exec { & 7z -tzip a $Version-Binaries.zip ./pkg/* } - }, PrintChecksum +# Synopsis: Creates a Zip of the Module +Add-BuildTask 7Zip -If (Test-PodeBuildIsWindows) PackDeps, StampVersion, { + exec { & 7z -tzip a $Version-Binaries.zip ./pkg/* } +}, PrintChecksum - #Synopsis: Create the Deliverable folder - Add-BuildTask DeliverableFolder { - $path = './deliverable' - if (Test-Path $path) { - Remove-Item -Path $path -Recurse -Force | Out-Null - } - - # create the deliverable dir - New-Item -Path $path -ItemType Directory -Force | Out-Null +#Synopsis: Create the Deliverable folder +Add-BuildTask DeliverableFolder { + $path = './deliverable' + if (Test-Path $path) { + Remove-Item -Path $path -Recurse -Force | Out-Null } - # Synopsis: Creates a Zip of the Module - Add-BuildTask Compress PackageFolder, StampVersion, DeliverableFolder, { - $path = './deliverable' - if (Test-Path $path) { - Remove-Item -Path $path -Recurse -Force | Out-Null - } - # create the pkg dir - New-Item -Path $path -ItemType Directory -Force | Out-Null - Compress-Archive -Path './pkg/*' -DestinationPath "$path/$Version-Binaries.zip" - }, PrintChecksum - - # Synopsis: Creates a Chocolately package of the Module - Add-BuildTask ChocoPack -If (Test-PodeBuildIsWindows) PackDeps, PackageFolder, StampVersion, DeliverableFolder, { - exec { choco pack ./packers/choco/pode.nuspec } - Move-Item -Path "pode.$Version.nupkg" -Destination './deliverable' - } - - # Synopsis: Create docker tags - Add-BuildTask DockerPack PackageFolder, StampVersion, { - # check if github and windows, and output warning - if ((Test-PodeBuildIsGitHub) -and (Test-PodeBuildIsWindows)) { - Write-Warning 'Docker images are not built on GitHub Windows runners, and Docker is in Windows container only mode. Exiting task.' - return - } + # create the deliverable dir + New-Item -Path $path -ItemType Directory -Force | Out-Null +} - try { - # Try to get the Docker version to check if Docker is installed - docker --version - } - catch { - # If Docker is not available, exit the task - Write-Warning 'Docker is not installed or not available in the PATH. Exiting task.' - return - } +# Synopsis: Creates a Zip of the Module +Add-BuildTask Compress PackageFolder, StampVersion, DeliverableFolder, { + $path = './deliverable' + if (Test-Path $path) { + Remove-Item -Path $path -Recurse -Force | Out-Null + } + # create the pkg dir + New-Item -Path $path -ItemType Directory -Force | Out-Null + Compress-Archive -Path './pkg/*' -DestinationPath "$path/$Version-Binaries.zip" +}, PrintChecksum + +# Synopsis: Creates a Chocolately package of the Module +Add-BuildTask ChocoPack -If (Test-PodeBuildIsWindows) PackDeps, PackageFolder, StampVersion, DeliverableFolder, { + exec { choco pack ./packers/choco/pode.nuspec } + Move-Item -Path "pode.$Version.nupkg" -Destination './deliverable' +} - Invoke-PodeBuildDockerBuild -Tag $Version -File './Dockerfile' - Invoke-PodeBuildDockerBuild -Tag 'latest' -File './Dockerfile' - Invoke-PodeBuildDockerBuild -Tag "$Version-alpine" -File './alpine.dockerfile' - Invoke-PodeBuildDockerBuild -Tag 'latest-alpine' -File './alpine.dockerfile' +# Synopsis: Create docker tags +Add-BuildTask DockerPack PackageFolder, StampVersion, { + # check if github and windows, and output warning + if ((Test-PodeBuildIsGitHub) -and (Test-PodeBuildIsWindows)) { + Write-Warning 'Docker images are not built on GitHub Windows runners, and Docker is in Windows container only mode. Exiting task.' + return + } - if (!(Test-PodeBuildIsGitHub)) { - Invoke-PodeBuildDockerBuild -Tag "$Version-arm32" -File './arm32.dockerfile' - Invoke-PodeBuildDockerBuild -Tag 'latest-arm32' -File './arm32.dockerfile' - } - else { - Write-Warning 'Docker images for ARM32 are not built on GitHub runners due to having the wrong OS architecture. Skipping.' - } + try { + # Try to get the Docker version to check if Docker is installed + docker --version + } + catch { + # If Docker is not available, exit the task + Write-Warning 'Docker is not installed or not available in the PATH. Exiting task.' + return } - # Synopsis: Package up the Module - Add-BuildTask Pack Compress, ChocoPack, DockerPack + Invoke-PodeBuildDockerBuild -Tag $Version -File './Dockerfile' + Invoke-PodeBuildDockerBuild -Tag 'latest' -File './Dockerfile' + Invoke-PodeBuildDockerBuild -Tag "$Version-alpine" -File './alpine.dockerfile' + Invoke-PodeBuildDockerBuild -Tag 'latest-alpine' -File './alpine.dockerfile' - # Synopsis: Package up the Module into a /pkg folder - Add-BuildTask PackageFolder Build, { - $path = './pkg' - if (Test-Path $path) { - Remove-Item -Path $path -Recurse -Force | Out-Null - } + if (!(Test-PodeBuildIsGitHub)) { + Invoke-PodeBuildDockerBuild -Tag "$Version-arm32" -File './arm32.dockerfile' + Invoke-PodeBuildDockerBuild -Tag 'latest-arm32' -File './arm32.dockerfile' + } + else { + Write-Warning 'Docker images for ARM32 are not built on GitHub runners due to having the wrong OS architecture. Skipping.' + } +} - # create the pkg dir - New-Item -Path $path -ItemType Directory -Force | Out-Null +# Synopsis: Package up the Module +Add-BuildTask Pack Compress, ChocoPack, DockerPack - # which source folders do we need? create them and copy their contents - $folders = @('Private', 'Public', 'Misc', 'Libs', 'Locales') - $folders | ForEach-Object { - New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null - Copy-Item -Path "./src/$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null - } +# Synopsis: Package up the Module into a /pkg folder +Add-BuildTask PackageFolder Build, { + $path = './pkg' + if (Test-Path $path) { + Remove-Item -Path $path -Recurse -Force | Out-Null + } - # which route folders to we need? create them and copy their contents - $folders = @('licenses') - $folders | ForEach-Object { - New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null - Copy-Item -Path "./$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null - } + # create the pkg dir + New-Item -Path $path -ItemType Directory -Force | Out-Null - # copy general files - $files = @('src/Pode.psm1', 'src/Pode.psd1', 'src/Pode.Internal.psm1', 'src/Pode.Internal.psd1', 'LICENSE.txt') - $files | ForEach-Object { - Copy-Item -Path "./$($_)" -Destination $path -Force | Out-Null - } + # which source folders do we need? create them and copy their contents + $folders = @('Private', 'Public', 'Misc', 'Libs', 'Locales') + $folders | ForEach-Object { + New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null + Copy-Item -Path "./src/$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null + } + + # which route folders to we need? create them and copy their contents + $folders = @('licenses') + $folders | ForEach-Object { + New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null + Copy-Item -Path "./$($_)/*" -Destination (Join-Path $path $_) -Force -Recurse | Out-Null + } + + # copy general files + $files = @('src/Pode.psm1', 'src/Pode.psd1', 'src/Pode.Internal.psm1', 'src/Pode.Internal.psd1', 'LICENSE.txt') + $files | ForEach-Object { + Copy-Item -Path "./$($_)" -Destination $path -Force | Out-Null } +} - <# +<# # Testing #> - # Synopsis: Run the tests - Add-BuildTask TestNoBuild TestDeps, { - $p = (Get-Command Invoke-Pester) - if ($null -eq $p -or $p.Version -ine $Versions.Pester) { - Remove-Module Pester -Force -ErrorAction Ignore - Import-Module Pester -Force -RequiredVersion $Versions.Pester - } +# Synopsis: Run the tests +Add-BuildTask TestNoBuild TestDeps, { + $p = (Get-Command Invoke-Pester) + if ($null -eq $p -or $p.Version -ine $Versions.Pester) { + Remove-Module Pester -Force -ErrorAction Ignore + Import-Module Pester -Force -RequiredVersion $Versions.Pester + } - # for windows, output current netsh excluded ports - if (Test-PodeBuildIsWindows) { - netsh int ipv4 show excludedportrange protocol=tcp | Out-Default - } - if ($UICulture -ne ([System.Threading.Thread]::CurrentThread.CurrentUICulture) ) { - $originalUICulture = [System.Threading.Thread]::CurrentThread.CurrentUICulture - Write-Output "Original UICulture is $originalUICulture" - Write-Output "Set UICulture to $UICulture" - # set new UICulture - [System.Threading.Thread]::CurrentThread.CurrentUICulture = $UICulture - } - $Script:TestResultFile = "$($pwd)/TestResults.xml" - - # get default from static property - $configuration = [PesterConfiguration]::Default - $configuration.run.path = @('./tests/unit', './tests/integration') - $configuration.run.PassThru = $true - $configuration.TestResult.OutputFormat = 'NUnitXml' - $configuration.Output.Verbosity = $PesterVerbosity - $configuration.TestResult.OutputPath = $Script:TestResultFile - - # if run code coverage if enabled - if (Test-PodeBuildCanCodeCoverage) { - $srcFiles = (Get-ChildItem "$($pwd)/src/*.ps1" -Recurse -Force).FullName - $configuration.CodeCoverage.Enabled = $true - $configuration.CodeCoverage.Path = $srcFiles - $Script:TestStatus = Invoke-Pester -Configuration $configuration - } - else { - $Script:TestStatus = Invoke-Pester -Configuration $configuration - } - if ($originalUICulture) { - Write-Output "Restore UICulture to $originalUICulture" - # restore original UICulture - [System.Threading.Thread]::CurrentThread.CurrentUICulture = $originalUICulture - } - }, PushCodeCoverage, CheckFailedTests + # for windows, output current netsh excluded ports + if (Test-PodeBuildIsWindows) { + netsh int ipv4 show excludedportrange protocol=tcp | Out-Default + } + if ($UICulture -ne ([System.Threading.Thread]::CurrentThread.CurrentUICulture) ) { + $originalUICulture = [System.Threading.Thread]::CurrentThread.CurrentUICulture + Write-Output "Original UICulture is $originalUICulture" + Write-Output "Set UICulture to $UICulture" + # set new UICulture + [System.Threading.Thread]::CurrentThread.CurrentUICulture = $UICulture + } + $Script:TestResultFile = "$($pwd)/TestResults.xml" + + # get default from static property + $configuration = [PesterConfiguration]::Default + $configuration.run.path = @('./tests/unit', './tests/integration') + $configuration.run.PassThru = $true + $configuration.TestResult.OutputFormat = 'NUnitXml' + $configuration.Output.Verbosity = $PesterVerbosity + $configuration.TestResult.OutputPath = $Script:TestResultFile + + # if run code coverage if enabled + if (Test-PodeBuildCanCodeCoverage) { + $srcFiles = (Get-ChildItem "$($pwd)/src/*.ps1" -Recurse -Force).FullName + $configuration.CodeCoverage.Enabled = $true + $configuration.CodeCoverage.Path = $srcFiles + $Script:TestStatus = Invoke-Pester -Configuration $configuration + } + else { + $Script:TestStatus = Invoke-Pester -Configuration $configuration + } + if ($originalUICulture) { + Write-Output "Restore UICulture to $originalUICulture" + # restore original UICulture + [System.Threading.Thread]::CurrentThread.CurrentUICulture = $originalUICulture + } +}, PushCodeCoverage, CheckFailedTests - # Synopsis: Run tests after a build - Add-BuildTask Test Build, TestNoBuild +# Synopsis: Run tests after a build +Add-BuildTask Test Build, TestNoBuild - # Synopsis: Check if any of the tests failed - Add-BuildTask CheckFailedTests { - if ($TestStatus.FailedCount -gt 0) { - throw "$($TestStatus.FailedCount) tests failed" - } +# Synopsis: Check if any of the tests failed +Add-BuildTask CheckFailedTests { + if ($TestStatus.FailedCount -gt 0) { + throw "$($TestStatus.FailedCount) tests failed" } +} - # Synopsis: If AppyVeyor or GitHub, push code coverage stats - Add-BuildTask PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { - try { - $service = Get-PodeBuildService - $branch = Get-PodeBuildBranch +# Synopsis: If AppyVeyor or GitHub, push code coverage stats +Add-BuildTask PushCodeCoverage -If (Test-PodeBuildCanCodeCoverage) { + try { + $service = Get-PodeBuildService + $branch = Get-PodeBuildBranch - Write-Host "Pushing coverage for $($branch) from $($service)" - $coverage = New-CoverallsReport -Coverage $Script:TestStatus.CodeCoverage -ServiceName $service -BranchName $branch - Publish-CoverallsReport -Report $coverage -ApiToken $env:PODE_COVERALLS_TOKEN - } - catch { - $_.Exception | Out-Default - } + Write-Host "Pushing coverage for $($branch) from $($service)" + $coverage = New-CoverallsReport -Coverage $Script:TestStatus.CodeCoverage -ServiceName $service -BranchName $branch + Publish-CoverallsReport -Report $coverage -ApiToken $env:PODE_COVERALLS_TOKEN + } + catch { + $_.Exception | Out-Default } +} - <# +<# # Docs #> - # Synopsis: Run the documentation locally - Add-BuildTask Docs DocsDeps, DocsHelpBuild, { - mkdocs serve --open - } +# Synopsis: Run the documentation locally +Add-BuildTask Docs DocsDeps, DocsHelpBuild, { + mkdocs serve --open +} - # Synopsis: Build the function help documentation - Add-BuildTask DocsHelpBuild IndexSamples, DocsDeps, Build, { - # import the local module - Remove-Module Pode -Force -ErrorAction Ignore | Out-Null - Import-Module ./src/Pode.psm1 -Force | Out-Null +# Synopsis: Build the function help documentation +Add-BuildTask DocsHelpBuild IndexSamples, DocsDeps, Build, { + # import the local module + Remove-Module Pode -Force -ErrorAction Ignore | Out-Null + Import-Module ./src/Pode.psm1 -Force | Out-Null - # build the function docs - $path = './docs/Functions' - $map = @{} + # build the function docs + $path = './docs/Functions' + $map = @{} (Get-Module Pode).ExportedFunctions.Keys | ForEach-Object { - $type = [System.IO.Path]::GetFileNameWithoutExtension((Split-Path -Leaf -Path (Get-Command $_ -Module Pode).ScriptBlock.File)) - New-MarkdownHelp -Command $_ -OutputFolder (Join-Path $path $type) -Force -Metadata @{ PodeType = $type } -AlphabeticParamsOrder | Out-Null - $map[$_] = $type - } + $type = [System.IO.Path]::GetFileNameWithoutExtension((Split-Path -Leaf -Path (Get-Command $_ -Module Pode).ScriptBlock.File)) + New-MarkdownHelp -Command $_ -OutputFolder (Join-Path $path $type) -Force -Metadata @{ PodeType = $type } -AlphabeticParamsOrder | Out-Null + $map[$_] = $type + } - # update docs to bind links to unlinked functions - $path = Join-Path $pwd 'docs' - Get-ChildItem -Path $path -Recurse -Filter '*.md' | ForEach-Object { - $depth = ($_.FullName.Replace($path, [string]::Empty).trim('\/') -split '[\\/]').Length - $updated = $false + # update docs to bind links to unlinked functions + $path = Join-Path $pwd 'docs' + Get-ChildItem -Path $path -Recurse -Filter '*.md' | ForEach-Object { + $depth = ($_.FullName.Replace($path, [string]::Empty).trim('\/') -split '[\\/]').Length + $updated = $false - $content = (Get-Content -Path $_.FullName | ForEach-Object { - $line = $_ + $content = (Get-Content -Path $_.FullName | ForEach-Object { + $line = $_ - while ($line -imatch '\[`(?[a-z]+\-pode[a-z]+)`\](?([^(]|$))') { - $updated = $true - $name = $Matches['name'] - $char = $Matches['char'] - $line = ($line -ireplace "\[``$($name)``\]([^(]|$)", "[``$($name)``]($('../' * $depth)Functions/$($map[$name])/$($name))$($char)") - } + while ($line -imatch '\[`(?[a-z]+\-pode[a-z]+)`\](?([^(]|$))') { + $updated = $true + $name = $Matches['name'] + $char = $Matches['char'] + $line = ($line -ireplace "\[``$($name)``\]([^(]|$)", "[``$($name)``]($('../' * $depth)Functions/$($map[$name])/$($name))$($char)") + } - $line - }) + $line + }) - if ($updated) { - $content | Out-File -FilePath $_.FullName -Force -Encoding ascii - } + if ($updated) { + $content | Out-File -FilePath $_.FullName -Force -Encoding ascii } - - # remove the module - Remove-Module Pode -Force -ErrorAction Ignore | Out-Null } - # Synopsis: Build the documentation - Add-BuildTask DocsBuild DocsDeps, DocsHelpBuild, { - mkdocs build --quiet - } + # remove the module + Remove-Module Pode -Force -ErrorAction Ignore | Out-Null +} + +# Synopsis: Build the documentation +Add-BuildTask DocsBuild DocsDeps, DocsHelpBuild, { + mkdocs build --quiet +} - <# +<# # Clean-up #> - # Synopsis: Clean the build enviroment - Add-BuildTask Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs +# Synopsis: Clean the build enviroment +Add-BuildTask Clean CleanPkg, CleanDeliverable, CleanLibs, CleanListener, CleanDocs - # Synopsis: Clean the Deliverable folder - Add-BuildTask CleanDeliverable { - $path = './deliverable' - if (Test-Path -Path $path -PathType Container) { - Write-Host 'Removing ./deliverable folder' - Remove-Item -Path $path -Recurse -Force | Out-Null - } - Write-Host "Cleanup $path done" +# Synopsis: Clean the Deliverable folder +Add-BuildTask CleanDeliverable { + $path = './deliverable' + if (Test-Path -Path $path -PathType Container) { + Write-Host 'Removing ./deliverable folder' + Remove-Item -Path $path -Recurse -Force | Out-Null } + Write-Host "Cleanup $path done" +} - # Synopsis: Clean the pkg directory - Add-BuildTask CleanPkg { - $path = './pkg' - if ((Test-Path -Path $path -PathType Container )) { - Write-Host 'Removing ./pkg folder' - Remove-Item -Path $path -Recurse -Force | Out-Null - } - - if ((Test-Path -Path .\packers\choco\tools\ChocolateyInstall.ps1 -PathType Leaf )) { - Write-Host 'Removing .\packers\choco\tools\ChocolateyInstall.ps1' - Remove-Item -Path .\packers\choco\tools\ChocolateyInstall.ps1 - } +# Synopsis: Clean the pkg directory +Add-BuildTask CleanPkg { + $path = './pkg' + if ((Test-Path -Path $path -PathType Container )) { + Write-Host 'Removing ./pkg folder' + Remove-Item -Path $path -Recurse -Force | Out-Null + } - if ((Test-Path -Path .\packers\choco\pode.nuspec -PathType Leaf )) { - Write-Host 'Removing .\packers\choco\pode.nuspec' - Remove-Item -Path .\packers\choco\pode.nuspec - } + if ((Test-Path -Path .\packers\choco\tools\ChocolateyInstall.ps1 -PathType Leaf )) { + Write-Host 'Removing .\packers\choco\tools\ChocolateyInstall.ps1' + Remove-Item -Path .\packers\choco\tools\ChocolateyInstall.ps1 + } - Write-Host "Cleanup $path done" + if ((Test-Path -Path .\packers\choco\pode.nuspec -PathType Leaf )) { + Write-Host 'Removing .\packers\choco\pode.nuspec' + Remove-Item -Path .\packers\choco\pode.nuspec } - # Synopsis: Clean the libs folder - Add-BuildTask CleanLibs { - $path = './src/Libs' - if (Test-Path -Path $path -PathType Container) { - Write-Host "Removing $path contents" - Remove-Item -Path $path -Recurse -Force | Out-Null - } + Write-Host "Cleanup $path done" +} - Write-Host "Cleanup $path done" +# Synopsis: Clean the libs folder +Add-BuildTask CleanLibs { + $path = './src/Libs' + if (Test-Path -Path $path -PathType Container) { + Write-Host "Removing $path contents" + Remove-Item -Path $path -Recurse -Force | Out-Null } - # Synopsis: Clean the Listener folder - Add-BuildTask CleanListener { - $path = './src/Listener/bin' - if (Test-Path -Path $path -PathType Container) { - Write-Host "Removing $path contents" - Remove-Item -Path $path -Recurse -Force | Out-Null - } + Write-Host "Cleanup $path done" +} - Write-Host "Cleanup $path done" +# Synopsis: Clean the Listener folder +Add-BuildTask CleanListener { + $path = './src/Listener/bin' + if (Test-Path -Path $path -PathType Container) { + Write-Host "Removing $path contents" + Remove-Item -Path $path -Recurse -Force | Out-Null } - Add-BuildTask CleanDocs { - $path = './docs/Getting-Started/Samples.md' - if (Test-Path -Path $path -PathType Leaf) { - Write-Host "Removing $path" - Remove-Item -Path $path -Force | Out-Null - } + Write-Host "Cleanup $path done" +} + +Add-BuildTask CleanDocs { + $path = './docs/Getting-Started/Samples.md' + if (Test-Path -Path $path -PathType Leaf) { + Write-Host "Removing $path" + Remove-Item -Path $path -Force | Out-Null } - <# +} +<# # Local module management #> - # Synopsis: Install Pode Module locally - Add-BuildTask Install-Module -If ($Version) Pack, { - $PSPaths = Split-PodeBuildPwshPath +# Synopsis: Install Pode Module locally +Add-BuildTask Install-Module -If ($Version) Pack, { + $PSPaths = Split-PodeBuildPwshPath - $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" - if (Test-Path $dest) { - Remove-Item -Path $dest -Recurse -Force | Out-Null - } - - # create the dest dir - New-Item -Path $dest -ItemType Directory -Force | Out-Null - $path = './pkg' + $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" + if (Test-Path $dest) { + Remove-Item -Path $dest -Recurse -Force | Out-Null + } - # copy over folders - $folders = @('Private', 'Public', 'Misc', 'Libs', 'licenses', 'Locales') - $folders | ForEach-Object { - Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force -Recurse | Out-Null - } + # create the dest dir + New-Item -Path $dest -ItemType Directory -Force | Out-Null + $path = './pkg' - # copy over general files - $files = @('Pode.psm1', 'Pode.psd1', 'Pode.Internal.psm1', 'Pode.Internal.psd1', 'LICENSE.txt') - $files | ForEach-Object { - Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force | Out-Null - } + # copy over folders + $folders = @('Private', 'Public', 'Misc', 'Libs', 'licenses', 'Locales') + $folders | ForEach-Object { + Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force -Recurse | Out-Null + } - Write-Host "Deployed to $dest" + # copy over general files + $files = @('Pode.psm1', 'Pode.psd1', 'Pode.Internal.psm1', 'Pode.Internal.psd1', 'LICENSE.txt') + $files | ForEach-Object { + Copy-Item -Path (Join-Path -Path $path -ChildPath $_) -Destination $dest -Force | Out-Null } - # Synopsis: Remove the Pode Module from the local registry - Add-BuildTask Remove-Module { - if (!$Version) { - throw 'Parameter -Version is required' - } + Write-Host "Deployed to $dest" +} - $PSPaths = Split-PodeBuildPwshPath +# Synopsis: Remove the Pode Module from the local registry +Add-BuildTask Remove-Module { + if (!$Version) { + throw 'Parameter -Version is required' + } - $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" - if (!(Test-Path $dest)) { - Write-Warning "Directory $dest doesn't exist" - } + $PSPaths = Split-PodeBuildPwshPath - Write-Host "Deleting module from $dest" - Remove-Item -Path $dest -Recurse -Force | Out-Null + $dest = Join-Path -Path $PSPaths[0] -ChildPath 'Pode' -AdditionalChildPath "$Version" + if (!(Test-Path $dest)) { + Write-Warning "Directory $dest doesn't exist" } + Write-Host "Deleting module from $dest" + Remove-Item -Path $dest -Recurse -Force | Out-Null +} + - <# +<# # PowerShell setup #> - # Synopsis: Setup the PowerShell environment - Add-BuildTask SetupPowerShell { - # code for this step is altered versions of the code found here: - # - https://github.com/bjompen/UpdatePWSHAction/blob/main/UpgradePwsh.ps1 - # - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 - - # fail if no version supplied - if ([string]::IsNullOrWhiteSpace($PowerShellVersion)) { - throw 'No PowerShell version supplied to set up' - } +# Synopsis: Setup the PowerShell environment +Add-BuildTask SetupPowerShell { + # code for this step is altered versions of the code found here: + # - https://github.com/bjompen/UpdatePWSHAction/blob/main/UpgradePwsh.ps1 + # - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 - # is the version valid? - $tags = @('preview', 'lts', 'daily', 'stable') - if (($PowerShellVersion -inotin $tags) -and ($PowerShellVersion -inotmatch '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$')) { - throw "Invalid PowerShell version supplied: $($PowerShellVersion)" - } + # fail if no version supplied + if ([string]::IsNullOrWhiteSpace($PowerShellVersion)) { + throw 'No PowerShell version supplied to set up' + } - # tag version or literal version? - $isTagVersion = $PowerShellVersion -iin $tags - if ($isTagVersion) { - Write-Host "Release tag: $($PowerShellVersion)" - $PowerShellVersion = Convert-PodeBuildOSPwshTagToVersion - } - Write-Host "Release version: $($PowerShellVersion)" + # is the version valid? + $tags = @('preview', 'lts', 'daily', 'stable') + if (($PowerShellVersion -inotin $tags) -and ($PowerShellVersion -inotmatch '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$')) { + throw "Invalid PowerShell version supplied: $($PowerShellVersion)" + } - # base/prefix versions - $atoms = $PowerShellVersion -split '\-' - $baseVersion = $atoms[0] + # tag version or literal version? + $isTagVersion = $PowerShellVersion -iin $tags + if ($isTagVersion) { + Write-Host "Release tag: $($PowerShellVersion)" + $PowerShellVersion = Convert-PodeBuildOSPwshTagToVersion + } + Write-Host "Release version: $($PowerShellVersion)" - # do nothing if the current version is the version we're trying to set up - $currentVersion = Get-PodeBuildCurrentPwshVersion - Write-Host "Current PowerShell version: $($currentVersion)" + # base/prefix versions + $atoms = $PowerShellVersion -split '\-' + $baseVersion = $atoms[0] - if ($baseVersion -ieq $currentVersion) { - Write-Host "PowerShell version $($PowerShellVersion) is already installed" - return - } + # do nothing if the current version is the version we're trying to set up + $currentVersion = Get-PodeBuildCurrentPwshVersion + Write-Host "Current PowerShell version: $($currentVersion)" - # build the package name - $arch = Get-PodeBuildOSPwshArchitecture - $os = Get-PodeBuildOSPwshName + if ($baseVersion -ieq $currentVersion) { + Write-Host "PowerShell version $($PowerShellVersion) is already installed" + return + } - $packageName = (@{ - win = "PowerShell-$($PowerShellVersion)-$($os)-$($arch).zip" - linux = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" - osx = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" - })[$os] + # build the package name + $arch = Get-PodeBuildOSPwshArchitecture + $os = Get-PodeBuildOSPwshName - # build the URL - $urls = @{ - Old = "https://pscoretestdata.blob.core.windows.net/v$($PowerShellVersion -replace '\.', '-')/$($packageName)" - New = "https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install/v$($PowerShellVersion)/$($packageName)" - } + $packageName = (@{ + win = "PowerShell-$($PowerShellVersion)-$($os)-$($arch).zip" + linux = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" + osx = "powershell-$($PowerShellVersion)-$($os)-$($arch).tar.gz" + })[$os] - # download the package to a temp location - $outputFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $packageName - $downloadParams = @{ - Uri = $urls.New - OutFile = $outputFile - ErrorAction = 'Stop' - } + # build the URL + $urls = @{ + Old = "https://pscoretestdata.blob.core.windows.net/v$($PowerShellVersion -replace '\.', '-')/$($packageName)" + New = "https://powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net/install/v$($PowerShellVersion)/$($packageName)" + } - Write-Host "Output file: $($outputFile)" + # download the package to a temp location + $outputFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $packageName + $downloadParams = @{ + Uri = $urls.New + OutFile = $outputFile + ErrorAction = 'Stop' + } - # retry the download 6 times, with a sleep of 10s between each attempt, and altering between old and new URLs - $counter = 0 - $success = $false + Write-Host "Output file: $($outputFile)" - do { - try { - $counter++ - Write-Host "Attempt $($counter) of 6" + # retry the download 6 times, with a sleep of 10s between each attempt, and altering between old and new URLs + $counter = 0 + $success = $false - # use new URL for odd attempts, and old URL for even attempts - if ($counter % 2 -eq 0) { - $downloadParams.Uri = $urls.Old - } - else { - $downloadParams.Uri = $urls.New - } - - # download the package - Write-Host "Attempting download of $($packageName) from $($downloadParams.Uri)" - Invoke-WebRequest @downloadParams + do { + try { + $counter++ + Write-Host "Attempt $($counter) of 6" - $success = $true - Write-Host "Downloaded $($packageName) successfully" + # use new URL for odd attempts, and old URL for even attempts + if ($counter % 2 -eq 0) { + $downloadParams.Uri = $urls.Old } - catch { - $success = $false - if ($counter -ge 6) { - throw "Failed to download PowerShell package after 6 attempts. Error: $($_.Exception.Message)" - } - - Start-Sleep -Seconds 5 + else { + $downloadParams.Uri = $urls.New } - } while (!$success) - # create target folder for package - $targetFolder = Join-Path -Path (Resolve-Path ~).Path -ChildPath ($packageName -ireplace '\.tar$') - if (!(Test-Path $targetFolder)) { - $null = New-Item -Path $targetFolder -ItemType Directory -Force - } + # download the package + Write-Host "Attempting download of $($packageName) from $($downloadParams.Uri)" + Invoke-WebRequest @downloadParams - # extract the package - switch ($os) { - 'win' { - Expand-Archive -Path $outputFile -DestinationPath $targetFolder -Force + $success = $true + Write-Host "Downloaded $($packageName) successfully" + } + catch { + $success = $false + if ($counter -ge 6) { + throw "Failed to download PowerShell package after 6 attempts. Error: $($_.Exception.Message)" } - { $_ -iin 'linux', 'osx' } { - $null = tar -xzf $outputFile -C $targetFolder - } + Start-Sleep -Seconds 5 } + } while (!$success) + + # create target folder for package + $targetFolder = Join-Path -Path (Resolve-Path ~).Path -ChildPath ($packageName -ireplace '\.tar$') + if (!(Test-Path $targetFolder)) { + $null = New-Item -Path $targetFolder -ItemType Directory -Force + } - # install the package - Write-Host "Installing PowerShell $($PowerShellVersion) to $($targetFolder)" - if (Test-PodeBuildOSWindows) { - Install-PodeBuildPwshWindows -Target $targetFolder + # extract the package + switch ($os) { + 'win' { + Expand-Archive -Path $outputFile -DestinationPath $targetFolder -Force } - else { - Install-PodeBuildPwshUnix -Target $targetFolder + + { $_ -iin 'linux', 'osx' } { + $null = tar -xzf $outputFile -C $targetFolder } } + # install the package + Write-Host "Installing PowerShell $($PowerShellVersion) to $($targetFolder)" + if (Test-PodeBuildOSWindows) { + Install-PodeBuildPwshWindows -Target $targetFolder + } + else { + Install-PodeBuildPwshUnix -Target $targetFolder + } +} + - <# +<# # Release Notes #> - # Synopsis: Build the Release Notes - task ReleaseNotes { - if ([string]::IsNullOrWhiteSpace($ReleaseNoteVersion)) { - Write-Host 'Please provide a ReleaseNoteVersion' -ForegroundColor Red - return - } +# Synopsis: Build the Release Notes +task ReleaseNotes { + if ([string]::IsNullOrWhiteSpace($ReleaseNoteVersion)) { + Write-Host 'Please provide a ReleaseNoteVersion' -ForegroundColor Red + return + } - # get the PRs for the ReleaseNoteVersion - $prs = gh search prs --milestone $ReleaseNoteVersion --repo badgerati/pode --merged --limit 200 --json 'number,title,labels,author' | ConvertFrom-Json + # get the PRs for the ReleaseNoteVersion + $prs = gh search prs --milestone $ReleaseNoteVersion --repo badgerati/pode --merged --limit 200 --json 'number,title,labels,author' | ConvertFrom-Json - # group PRs into categories, filtering out some internal PRs - $categories = [ordered]@{ - Features = @() - Enhancements = @() - Bugs = @() - Documentation = @() - } + # group PRs into categories, filtering out some internal PRs + $categories = [ordered]@{ + Features = @() + Enhancements = @() + Bugs = @() + Documentation = @() + } - $dependabot = @{} + $dependabot = @{} - foreach ($pr in $prs) { - if ($pr.labels.name -icontains 'superseded') { - continue - } + foreach ($pr in $prs) { + if ($pr.labels.name -icontains 'superseded') { + continue + } - $label = ($pr.labels[0].name -split ' ')[0] - if ($label -iin @('new-release', 'internal-code')) { - continue - } + $label = ($pr.labels[0].name -split ' ')[0] + if ($label -iin @('new-release', 'internal-code')) { + continue + } - if ([string]::IsNullOrWhiteSpace($label)) { - $label = 'misc' - } + if ([string]::IsNullOrWhiteSpace($label)) { + $label = 'misc' + } - switch ($label.ToLowerInvariant()) { - 'feature' { $label = 'Features' } - 'enhancement' { $label = 'Enhancements' } - 'bug' { $label = 'Bugs' } - } + switch ($label.ToLowerInvariant()) { + 'feature' { $label = 'Features' } + 'enhancement' { $label = 'Enhancements' } + 'bug' { $label = 'Bugs' } + } - if (!$categories.Contains($label)) { - $categories[$label] = @() - } + if (!$categories.Contains($label)) { + $categories[$label] = @() + } - if ($pr.author.login -ilike '*dependabot*') { - if ($pr.title -imatch 'Bump (?\S+) from (?[0-9\.]+) to (?[0-9\.]+)') { - if (!$dependabot.ContainsKey($Matches['name'])) { - $dependabot[$Matches['name']] = @{ - Name = $Matches['name'] - Number = $pr.number - From = [version]$Matches['from'] - To = [version]$Matches['to'] - } + if ($pr.author.login -ilike '*dependabot*') { + if ($pr.title -imatch 'Bump (?\S+) from (?[0-9\.]+) to (?[0-9\.]+)') { + if (!$dependabot.ContainsKey($Matches['name'])) { + $dependabot[$Matches['name']] = @{ + Name = $Matches['name'] + Number = $pr.number + From = [version]$Matches['from'] + To = [version]$Matches['to'] + } + } + else { + $item = $dependabot[$Matches['name']] + if ([int]$pr.number -gt [int]$item.Number) { + $item.Number = $pr.number } - else { - $item = $dependabot[$Matches['name']] - if ([int]$pr.number -gt [int]$item.Number) { - $item.Number = $pr.number - } - if ([version]$Matches['from'] -lt $item.From) { - $item.From = [version]$Matches['from'] - } - if ([version]$Matches['to'] -gt $item.To) { - $item.To = [version]$Matches['to'] - } + if ([version]$Matches['from'] -lt $item.From) { + $item.From = [version]$Matches['from'] + } + if ([version]$Matches['to'] -gt $item.To) { + $item.To = [version]$Matches['to'] } - - continue } - } - $titles = @($pr.title).Trim() - if ($pr.title.Contains(';')) { - $titles = ($pr.title -split ';').Trim() - } - - $author = $null - if (($pr.author.login -ine 'badgerati') -and ($pr.author.login -inotlike '*dependabot*')) { - $author = $pr.author.login + continue } + } - foreach ($title in $titles) { - $str = "* #$($pr.number): $($title -replace '`', "'")" - if (![string]::IsNullOrWhiteSpace($author)) { - $str += " (thanks @$($author)!)" - } + $titles = @($pr.title).Trim() + if ($pr.title.Contains(';')) { + $titles = ($pr.title -split ';').Trim() + } - if ($str -imatch '\s+(docs|documentation)\s+') { - $categories['Documentation'] += $str - } - else { - $categories[$label] += $str - } - } + $author = $null + if (($pr.author.login -ine 'badgerati') -and ($pr.author.login -inotlike '*dependabot*')) { + $author = $pr.author.login } - # add dependabot aggregated PRs - if ($dependabot.Count -gt 0) { - $label = 'dependencies' - if (!$categories.Contains($label)) { - $categories[$label] = @() + foreach ($title in $titles) { + $str = "* #$($pr.number): $($title -replace '`', "'")" + if (![string]::IsNullOrWhiteSpace($author)) { + $str += " (thanks @$($author)!)" } - foreach ($dep in $dependabot.Values) { - $categories[$label] += "* #$($dep.Number): Bump $($dep.Name) from $($dep.From) to $($dep.To)" + if ($str -imatch '\s+(docs|documentation)\s+') { + $categories['Documentation'] += $str } + else { + $categories[$label] += $str + } + } + } + + # add dependabot aggregated PRs + if ($dependabot.Count -gt 0) { + $label = 'dependencies' + if (!$categories.Contains($label)) { + $categories[$label] = @() } - # output the release notes - Write-Host "# v$($ReleaseNoteVersion)`n" + foreach ($dep in $dependabot.Values) { + $categories[$label] += "* #$($dep.Number): Bump $($dep.Name) from $($dep.From) to $($dep.To)" + } + } - $culture = (Get-Culture).TextInfo - foreach ($category in $categories.Keys) { - if ($categories[$category].Length -eq 0) { - continue - } + # output the release notes + Write-Host "# v$($ReleaseNoteVersion)`n" - Write-Host "### $($culture.ToTitleCase($category))" - $categories[$category] | Sort-Object | ForEach-Object { Write-Host $_ } - Write-Host '' + $culture = (Get-Culture).TextInfo + foreach ($category in $categories.Keys) { + if ($categories[$category].Length -eq 0) { + continue } + + Write-Host "### $($culture.ToTitleCase($category))" + $categories[$category] | Sort-Object | ForEach-Object { Write-Host $_ } + Write-Host '' } } -else { - Write-Host 'This script is intended to be run with Invoke-Build. Please use Invoke-Build to execute the tasks defined in this script.' -ForegroundColor Yellow -} \ No newline at end of file From cb683fe6f5512b524772acf87ba16fc4acc5ae2c Mon Sep 17 00:00:00 2001 From: mdaneri Date: Fri, 22 Nov 2024 14:25:30 -0800 Subject: [PATCH 22/23] fix workflow --- .github/workflows/ci-pwsh7_2.yml | 2 +- .github/workflows/ci-pwsh7_5.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-pwsh7_2.yml b/.github/workflows/ci-pwsh7_2.yml index 67602bb8b..2c8a2b3af 100644 --- a/.github/workflows/ci-pwsh7_2.yml +++ b/.github/workflows/ci-pwsh7_2.yml @@ -25,7 +25,7 @@ on: env: INVOKE_BUILD_VERSION: '5.12.0' - POWERSHELL_VERSION: '7.5.0' + POWERSHELL_VERSION: '7.2.24' jobs: build: diff --git a/.github/workflows/ci-pwsh7_5.yml b/.github/workflows/ci-pwsh7_5.yml index b5faba8cd..8af886f21 100644 --- a/.github/workflows/ci-pwsh7_5.yml +++ b/.github/workflows/ci-pwsh7_5.yml @@ -25,7 +25,8 @@ on: env: INVOKE_BUILD_VERSION: '5.12.1' - POWERSHELL_VERSION: '7.2.24' + POWERSHELL_VERSION: '7.5.0-rc.1' + jobs: build: From 64536e3e95158ac32aed3fee6226cc94069ad025 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Fri, 22 Nov 2024 14:29:15 -0800 Subject: [PATCH 23/23] fix invoke-build version --- .github/workflows/ci-pwsh7_5.yml | 2 +- .github/workflows/ci-pwsh_preview.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-pwsh7_5.yml b/.github/workflows/ci-pwsh7_5.yml index 8af886f21..1b0c51cce 100644 --- a/.github/workflows/ci-pwsh7_5.yml +++ b/.github/workflows/ci-pwsh7_5.yml @@ -24,7 +24,7 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.12.1' + INVOKE_BUILD_VERSION: '5.12.0' POWERSHELL_VERSION: '7.5.0-rc.1' diff --git a/.github/workflows/ci-pwsh_preview.yml b/.github/workflows/ci-pwsh_preview.yml index d9dcee85c..43198540f 100644 --- a/.github/workflows/ci-pwsh_preview.yml +++ b/.github/workflows/ci-pwsh_preview.yml @@ -24,7 +24,7 @@ on: - '*.dockerfile' env: - INVOKE_BUILD_VERSION: '5.12.1' + INVOKE_BUILD_VERSION: '5.12.0' POWERSHELL_VERSION: 'Preview' jobs: