diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index bb587e9a12b..60bac0125e1 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -30,8 +30,6 @@ function Start-PSPackage { [Switch] $Force, - [Switch] $IncludeSymbols, - [Switch] $SkipReleaseChecks ) @@ -39,217 +37,255 @@ function Start-PSPackage { # creating package for 'deb-arm'. It should be added back to the ValidateSet of '-Type' once the implementation # of creating 'deb-arm' package is done. - # Runtime and Configuration settings required by the package - ($Runtime, $Configuration) = if ($WindowsRuntime) { - $WindowsRuntime, "Release" - } elseif ($Type -eq "deb-arm") { - New-PSOptions -Configuration "Release" -Runtime "Linux-ARM" -WarningAction SilentlyContinue | ForEach-Object { $_.Runtime, $_.Configuration } - } else { - New-PSOptions -Configuration "Release" -WarningAction SilentlyContinue | ForEach-Object { $_.Runtime, $_.Configuration } - } + DynamicParam { + if ($Type -eq "zip") { + # Add a dynamic parameter '-IncludeSymbols' when the specified package type is 'zip'. + # The '-IncludeSymbols' parameter can be used to indicate that the package should only contain powershell binaries and symbols. + $ParameterAttr = New-Object "System.Management.Automation.ParameterAttribute" + $Attributes = New-Object "System.Collections.ObjectModel.Collection``1[System.Attribute]" + $Attributes.Add($ParameterAttr) > $null - if($Environment.IsWindows) { - # Runtime will always be win7-x64 or win7-x86 on Windows. - # Build the name suffix for universal win-plat packages. - $NameSuffix = $Runtime -replace 'win\d+', 'win' + $Parameter = New-Object "System.Management.Automation.RuntimeDefinedParameter" -ArgumentList ("IncludeSymbols", [switch], $Attributes) + $Dict = New-Object "System.Management.Automation.RuntimeDefinedParameterDictionary" + $Dict.Add("IncludeSymbols", $Parameter) > $null + return $Dict + } } - log "Packaging RID: '$Runtime'; Packaging Configuration: '$Configuration'" - - $Script:Options = Get-PSOptions + End { + $IncludeSymbols = $null + if ($PSBoundParameters.ContainsKey('IncludeSymbols')) { + log 'setting IncludeSymbols' + $IncludeSymbols = $PSBoundParameters['IncludeSymbols'] + } - $crossGenCorrect = $false - if ($Type -eq "deb-arm") { - # crossgen doesn't support arm32 yet - $crossGenCorrect = $true - } - elseif(-not $IncludeSymbols.IsPresent -and $Script:Options.CrossGen) { - $crossGenCorrect = $true - } - elseif ($IncludeSymbols.IsPresent -and -not $Script:Options.CrossGen) { - $crossGenCorrect = $true - } + # Runtime and Configuration settings required by the package + ($Runtime, $Configuration) = if ($WindowsRuntime) { + $WindowsRuntime, "Release" + } elseif ($Type -eq "deb-arm") { + New-PSOptions -Configuration "Release" -Runtime "Linux-ARM" -WarningAction SilentlyContinue | ForEach-Object { $_.Runtime, $_.Configuration } + } else { + New-PSOptions -Configuration "Release" -WarningAction SilentlyContinue | ForEach-Object { $_.Runtime, $_.Configuration } + } - # Make sure the most recent build satisfies the package requirement - if (-not $Script:Options -or ## Start-PSBuild hasn't been executed yet - -not $crossGenCorrect -or ## Last build didn't specify '-CrossGen' correctly - $Script:Options.Runtime -ne $Runtime -or ## Last build wasn't for the required RID - $Script:Options.Configuration -ne $Configuration -or ## Last build was with configuration other than 'Release' - $Script:Options.Framework -ne "netcoreapp2.0") ## Last build wasn't for CoreCLR - { - # It's possible that the most recent build doesn't satisfy the package requirement but - # an earlier build does. - # It's also possible that the last build actually satisfies the package requirement but - # then `Start-PSPackage` runs from a new PS session or `build.psm1` was reloaded. - # - # In these cases, the user will be asked to build again even though it's technically not - # necessary. However, we want it that way -- being very explict when generating packages. - # This check serves as a simple gate to ensure that the user knows what he is doing, and - # also ensure `Start-PSPackage` does what the user asks/expects, because once packages - # are generated, it'll be hard to verify if they were built from the correct content. - $params = @('-Clean') - if(-not $IncludeSymbols.IsPresent) - { - $params += '-CrossGen' + if($Environment.IsWindows) { + # Runtime will always be win7-x64 or win7-x86 on Windows. + # Build the name suffix for universal win-plat packages. + $NameSuffix = $Runtime -replace 'win\d+', 'win' } - $params += '-Runtime', $Runtime - $params += '-Configuration', $Configuration - throw "Please ensure you have run 'Start-PSBuild $params'!" - } + log "Packaging RID: '$Runtime'; Packaging Configuration: '$Configuration'" - if($SkipReleaseChecks.IsPresent) { - Write-Warning "Skipping release checks." - } - elseif(!$Script:Options.RootInfo.IsValid){ - throw $Script:Options.RootInfo.Warning - } + $Script:Options = Get-PSOptions - # If ReleaseTag is specified, use the given tag to calculate Vesrion - if ($PSCmdlet.ParameterSetName -eq "ReleaseTag") { - $Version = $ReleaseTag -Replace '^v' - } + $crossGenCorrect = $false + if ($Type -eq "deb-arm") { + # crossgen doesn't support arm32 yet + $crossGenCorrect = $true + } + elseif(-not $IncludeSymbols.IsPresent -and $Script:Options.CrossGen) { + $crossGenCorrect = $true + } + elseif ($IncludeSymbols.IsPresent) { + $crossGenCorrect = $true + } - # Use Git tag if not given a version - if (-not $Version) { - $Version = (git --git-dir="$PSScriptRoot/../../.git" describe) -Replace '^v' - } + # Make sure the most recent build satisfies the package requirement + if (-not $Script:Options -or ## Start-PSBuild hasn't been executed yet + -not $crossGenCorrect -or ## Last build didn't specify '-CrossGen' correctly + $Script:Options.Runtime -ne $Runtime -or ## Last build wasn't for the required RID + $Script:Options.Configuration -ne $Configuration -or ## Last build was with configuration other than 'Release' + $Script:Options.Framework -ne "netcoreapp2.0") ## Last build wasn't for CoreCLR + { + # It's possible that the most recent build doesn't satisfy the package requirement but + # an earlier build does. + # It's also possible that the last build actually satisfies the package requirement but + # then `Start-PSPackage` runs from a new PS session or `build.psm1` was reloaded. + # + # In these cases, the user will be asked to build again even though it's technically not + # necessary. However, we want it that way -- being very explict when generating packages. + # This check serves as a simple gate to ensure that the user knows what he is doing, and + # also ensure `Start-PSPackage` does what the user asks/expects, because once packages + # are generated, it'll be hard to verify if they were built from the correct content. + $params = @('-Clean') + if(-not $IncludeSymbols.IsPresent) + { + $params += '-CrossGen' + } + $params += '-Runtime', $Runtime + $params += '-Configuration', $Configuration - $Source = Split-Path -Path $Script:Options.Output -Parent - log "Packaging Source: '$Source'" + throw "Please ensure you have run 'Start-PSBuild $params'!" + } - # Decide package output type - if (-not $Type) { - $Type = if ($Environment.IsLinux) { - if ($Environment.LinuxInfo.ID -match "ubuntu") { - "deb", "nupkg" - } elseif ($Environment.IsRedHatFamily) { - "rpm", "nupkg" - } else { - throw "Building packages for $($Environment.LinuxInfo.PRETTY_NAME) is unsupported!" - } - } elseif ($Environment.IsMacOS) { - "osxpkg", "nupkg" - } elseif ($Environment.IsWindows) { - "msi", "nupkg" + if($SkipReleaseChecks.IsPresent) { + Write-Warning "Skipping release checks." + } + elseif(!$Script:Options.RootInfo.IsValid){ + throw $Script:Options.RootInfo.Warning } - Write-Warning "-Type was not specified, continuing with $Type!" - } - log "Packaging Type: $Type" - # Add the symbols to the suffix - # if symbols are specified to be included - if($IncludeSymbols.IsPresent -and $NameSuffix) { - $NameSuffix = "symbols-$NameSuffix" - } - elseif ($IncludeSymbols.IsPresent) { - $NameSuffix = "symbols" - } + # If ReleaseTag is specified, use the given tag to calculate Vesrion + if ($PSCmdlet.ParameterSetName -eq "ReleaseTag") { + $Version = $ReleaseTag -Replace '^v' + } - switch ($Type) { - "zip" { - $Arguments = @{ - PackageNameSuffix = $NameSuffix - PackageSourcePath = $Source - PackageVersion = $Version - Force = $Force - } + # Use Git tag if not given a version + if (-not $Version) { + $Version = (git --git-dir="$PSScriptRoot/../../.git" describe) -Replace '^v' + } - if ($PSCmdlet.ShouldProcess("Create Zip Package")) { - New-ZipPackage @Arguments - } + $Source = Split-Path -Path $Script:Options.Output -Parent + + # If building a symbols package, don't include the publish build. + if ($IncludeSymbols.IsPresent) + { + $buildSource = Split-Path -Path $Source -Parent + $Source = New-TempFolder + Get-ChildItem -Path $buildSource | Where-Object {$_.Name -ine 'Publish'} | Copy-Item -Destination $Source -Recurse } - "msi" { - $TargetArchitecture = "x64" - if ($Runtime -match "-x86") { - $TargetArchitecture = "x86" - } - $Arguments = @{ - ProductNameSuffix = $NameSuffix - ProductSourcePath = $Source - ProductVersion = $Version - AssetsPath = "$PSScriptRoot\..\..\assets" - LicenseFilePath = "$PSScriptRoot\..\..\assets\license.rtf" - # Product Guid needs to be unique for every PowerShell version to allow SxS install - ProductGuid = New-Guid - ProductTargetArchitecture = $TargetArchitecture - Force = $Force - } + log "Packaging Source: '$Source'" - if ($PSCmdlet.ShouldProcess("Create MSI Package")) { - New-MSIPackage @Arguments + # Decide package output type + if (-not $Type) { + $Type = if ($Environment.IsLinux) { + if ($Environment.LinuxInfo.ID -match "ubuntu") { + "deb", "nupkg" + } elseif ($Environment.IsRedHatFamily) { + "rpm", "nupkg" + } else { + throw "Building packages for $($Environment.LinuxInfo.PRETTY_NAME) is unsupported!" + } + } elseif ($Environment.IsMacOS) { + "osxpkg", "nupkg" + } elseif ($Environment.IsWindows) { + "msi", "nupkg" } + Write-Warning "-Type was not specified, continuing with $Type!" } - "AppImage" { - if ($IncludeSymbols.IsPresent) { - throw "AppImage does not support packaging '-IncludeSymbols'" - } + log "Packaging Type: $Type" - if ($Environment.IsUbuntu14) { - $null = Start-NativeExecution { bash -iex "$PSScriptRoot/../appimage.sh" } - $appImage = Get-Item PowerShell-*.AppImage - if ($appImage.Count -gt 1) { - throw "Found more than one AppImage package, remove all *.AppImage files and try to create the package again" + # Add the symbols to the suffix + # if symbols are specified to be included + if($IncludeSymbols.IsPresent -and $NameSuffix) { + $NameSuffix = "symbols-$NameSuffix" + } + elseif ($IncludeSymbols.IsPresent) { + $NameSuffix = "symbols" + } + + switch ($Type) { + "zip" { + $Arguments = @{ + PackageNameSuffix = $NameSuffix + PackageSourcePath = $Source + PackageVersion = $Version + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create Zip Package")) { + New-ZipPackage @Arguments } - Rename-Item $appImage.Name $appImage.Name.Replace("-","-$Version-") - } else { - Write-Warning "Ignoring AppImage type for non Ubuntu Trusty platform" } - } - 'nupkg' { - $Arguments = @{ - PackageNameSuffix = $NameSuffix - PackageSourcePath = $Source - PackageVersion = $Version - PackageRuntime = $Runtime - PackageConfiguration = $Configuration - Force = $Force + "msi" { + $TargetArchitecture = "x64" + if ($Runtime -match "-x86") { + $TargetArchitecture = "x86" + } + + $Arguments = @{ + ProductNameSuffix = $NameSuffix + ProductSourcePath = $Source + ProductVersion = $Version + AssetsPath = "$PSScriptRoot\..\..\assets" + LicenseFilePath = "$PSScriptRoot\..\..\assets\license.rtf" + # Product Guid needs to be unique for every PowerShell version to allow SxS install + ProductGuid = New-Guid + ProductTargetArchitecture = $TargetArchitecture + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create MSI Package")) { + New-MSIPackage @Arguments + } } + "AppImage" { + if ($IncludeSymbols.IsPresent) { + throw "AppImage does not support packaging '-IncludeSymbols'" + } - if ($PSCmdlet.ShouldProcess("Create NuPkg Package")) { - New-NugetPackage @Arguments + if ($Environment.IsUbuntu14) { + $null = Start-NativeExecution { bash -iex "$PSScriptRoot/../appimage.sh" } + $appImage = Get-Item PowerShell-*.AppImage + if ($appImage.Count -gt 1) { + throw "Found more than one AppImage package, remove all *.AppImage files and try to create the package again" + } + Rename-Item $appImage.Name $appImage.Name.Replace("-","-$Version-") + } else { + Write-Warning "Ignoring AppImage type for non Ubuntu Trusty platform" + } } - } - 'tar' { - $Arguments = @{ - PackageSourcePath = $Source - Name = $Name - Version = $Version - Force = $Force + 'nupkg' { + $Arguments = @{ + PackageNameSuffix = $NameSuffix + PackageSourcePath = $Source + PackageVersion = $Version + PackageRuntime = $Runtime + PackageConfiguration = $Configuration + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create NuPkg Package")) { + New-NugetPackage @Arguments + } } + 'tar' { + $Arguments = @{ + PackageSourcePath = $Source + Name = $Name + Version = $Version + Force = $Force + } - if ($PSCmdlet.ShouldProcess("Create tar.gz Package")) { - New-TarballPackage @Arguments + if ($PSCmdlet.ShouldProcess("Create tar.gz Package")) { + New-TarballPackage @Arguments + } } - } - 'deb' { - $Arguments = @{ - Type = 'deb' - PackageSourcePath = $Source - Name = $Name - Version = $Version - Force = $Force + 'deb' { + $Arguments = @{ + Type = 'deb' + PackageSourcePath = $Source + Name = $Name + Version = $Version + Force = $Force + } + foreach ($Distro in $Script:DebianDistributions) { + $Arguments["Distribution"] = $Distro + if ($PSCmdlet.ShouldProcess("Create DEB Package for $Distro")) { + New-UnixPackage @Arguments + } + } } - foreach ($Distro in $Script:DebianDistributions) { - $Arguments["Distribution"] = $Distro - if ($PSCmdlet.ShouldProcess("Create DEB Package for $Distro")) { + default { + $Arguments = @{ + Type = $_ + PackageSourcePath = $Source + Name = $Name + Version = $Version + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create $_ Package")) { New-UnixPackage @Arguments } } } - default { - $Arguments = @{ - Type = $_ - PackageSourcePath = $Source - Name = $Name - Version = $Version - Force = $Force - } - if ($PSCmdlet.ShouldProcess("Create $_ Package")) { - New-UnixPackage @Arguments - } + if($IncludeSymbols.IsPresent) + { + # Source is a temporary folder when -IncludeSymbols is present. So, we should remove it. + Remove-Item -Path $Source -Recurse -Force -ErrorAction SilentlyContinue } } } @@ -318,6 +354,19 @@ function New-TarballPackage { } } +function New-TempFolder +{ + $tempPath = [System.IO.Path]::GetTempPath() + + $tempFolder = Join-Path -Path $tempPath -ChildPath ([System.IO.Path]::GetRandomFileName()) + if(!(Test-Path -Path $tempFolder)) + { + $null = New-Item -Path $tempFolder -ItemType Directory + } + + return $tempFolder +} + function New-UnixPackage { [CmdletBinding(SupportsShouldProcess=$true)] param(