diff --git a/build.psm1 b/build.psm1 index 41e3d94676..73adb32849 100644 --- a/build.psm1 +++ b/build.psm1 @@ -428,7 +428,8 @@ function Start-PSBuild { # These runtimes must match those in project.json # We do not use ValidateScript since we want tab completion # If this parameter is not provided it will get determined automatically. - [ValidateSet("linux-arm", + [ValidateSet("fxdependent", + "linux-arm", "linux-musl-x64", "linux-x64", "osx-x64", @@ -455,7 +456,6 @@ function Start-PSBuild { if ("win-arm","win-arm64" -contains $Runtime -and -not $Environment.IsWindows) { throw "Cross compiling for win-arm or win-arm64 is only supported on Windows environment" } - function Stop-DevPowerShell { Get-Process pwsh* | Where-Object { @@ -536,7 +536,7 @@ Fix steps: $Arguments += "--configuration", $Options.Configuration $Arguments += "--framework", $Options.Framework - if (-not $SMAOnly) { + if (-not $SMAOnly -and $Options.Runtime -ne 'fxdependent') { # libraries should not have runtime $Arguments += "--runtime", $Options.Runtime } @@ -572,7 +572,8 @@ Fix steps: Write-Log "Run dotnet $Arguments from $pwd" Start-NativeExecution { dotnet $Arguments } - if ($CrossGen) { + if ($CrossGen -and $Options.Runtime -ne 'fxdependent') { + ## fxdependent package cannot be CrossGen'ed Start-CrossGen -PublishPath $publishPath -Runtime $script:Options.Runtime Write-Log "pwsh.exe with ngen binaries is available at: $($Options.Output)" } else { @@ -657,10 +658,13 @@ Fix steps: $iconPath = "$PSScriptRoot\assets\Powershell_black.ico" } - Start-NativeExecution { & $rcedit $pwshPath --set-icon $iconPath ` - --set-file-version $fileVersion --set-product-version $ReleaseVersion --set-version-string "ProductName" "PowerShell Core 6" ` - --set-version-string "LegalCopyright" "(C) Microsoft Corporation. All Rights Reserved." ` - --application-manifest "$PSScriptRoot\assets\pwsh.manifest" } | Write-Verbose + # fxdependent package does not have an executable to set iconPath etc. + if ($Options.Runtime -ne 'fxdependent') { + Start-NativeExecution { & $rcedit $pwshPath --set-icon $iconPath ` + --set-file-version $fileVersion --set-product-version $ReleaseVersion --set-version-string "ProductName" "PowerShell Core 6" ` + --set-version-string "LegalCopyright" "(C) Microsoft Corporation. All Rights Reserved." ` + --application-manifest "$PSScriptRoot\assets\pwsh.manifest" } | Write-Verbose + } } # download modules from powershell gallery. @@ -696,7 +700,12 @@ function Restore-PSPackage if ($Force -or (-not (Test-Path "$($Options.Top)/obj/project.assets.json"))) { - $RestoreArguments = @("--runtime",$Options.Runtime,"--verbosity") + if($Options.Runtime -ne 'fxdependent') { + $RestoreArguments = @("--runtime",$Options.Runtime, "--verbosity") + } else { + $RestoreArguments = @("--verbosity") + } + if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { $RestoreArguments += "detailed" } else { @@ -780,6 +789,7 @@ function New-PSOptions { # These are duplicated from Start-PSBuild # We do not use ValidateScript since we want tab completion [ValidateSet("", + "fxdependent", "linux-arm", "linux-musl-x64", "linux-x64", @@ -855,7 +865,9 @@ function New-PSOptions { } } - $Executable = if ($Environment.IsLinux -or $Environment.IsMacOS) { + $Executable = if ($Runtime -eq 'fxdependent') { + "pwsh.dll" + } elseif ($Environment.IsLinux -or $Environment.IsMacOS) { "pwsh" } elseif ($Environment.IsWindows) { "pwsh.exe" @@ -863,7 +875,11 @@ function New-PSOptions { # Build the Output path if (!$Output) { - $Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework, $Runtime, "publish", $Executable) + if ($Runtime -eq 'fxdependent') { + $Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework, "publish", $Executable) + } else { + $Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework, $Runtime, "publish", $Executable) + } } if ($SMAOnly) diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 63fd068aec..4553e5744c 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -23,7 +23,7 @@ function Start-PSPackage { [string]$Name = "powershell", # Ubuntu, CentOS, Fedora, macOS, and Windows packages are supported - [ValidateSet("deb", "osxpkg", "rpm", "msi", "zip", "AppImage", "nupkg", "tar", "tar-arm", 'tar-musl')] + [ValidateSet("deb", "osxpkg", "rpm", "msi", "zip", "AppImage", "nupkg", "tar", "tar-arm", 'tar-musl', 'fxdependent')] [string[]]$Type, # Generate windows downlevel package @@ -39,7 +39,7 @@ function Start-PSPackage { ) DynamicParam { - if ("zip" -eq $Type) { + if ("zip" -eq $Type -or "fxdependent" -eq $Type) { # Add a dynamic parameter '-IncludeSymbols' when the specified package type is 'zip' only. # 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" @@ -71,7 +71,7 @@ function Start-PSPackage { New-PSOptions -Configuration "Release" -WarningAction SilentlyContinue | ForEach-Object { $_.Runtime, $_.Configuration } } - if($Environment.IsWindows) { + if ($Environment.IsWindows) { # Runtime will be one of win7-x64, win7-x86, "win-arm" and "win-arm64" on Windows. # Build the name suffix for universal win-plat packages. switch ($Runtime) { @@ -81,7 +81,12 @@ function Start-PSPackage { } } - Write-Log "Packaging RID: '$Runtime'; Packaging Configuration: '$Configuration'" + if ($Type -eq 'fxdependent') { + $NameSuffix = "win-fxdependent" + Write-Log "Packaging : '$Type'; Packaging Configuration: '$Configuration'" + } else { + Write-Log "Packaging RID: '$Runtime'; Packaging Configuration: '$Configuration'" + } $Script:Options = Get-PSOptions @@ -105,14 +110,23 @@ function Start-PSPackage { $PSModuleRestoreCorrect = $true } - # Make sure the most recent build satisfies the package requirement - if (-not $Script:Options -or ## Start-PSBuild hasn't been executed yet + $precheckFailed = if ($Type -eq 'fxdependent') { + ## We do not check for runtime and crossgen for framework dependent package. + -not $Script:Options -or ## Start-PSBuild hasn't been executed yet + -not $PSModuleRestoreCorrect -or ## Last build didn't specify '-PSModuleRestore' correctly + $Script:Options.Configuration -ne $Configuration -or ## Last build was with configuration other than 'Release' + $Script:Options.Framework -ne "netcoreapp2.1" ## Last build wasn't for CoreCLR + } else { + -not $Script:Options -or ## Start-PSBuild hasn't been executed yet -not $crossGenCorrect -or ## Last build didn't specify '-CrossGen' correctly -not $PSModuleRestoreCorrect -or ## Last build didn't specify '-PSModuleRestore' 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.1") ## Last build wasn't for CoreCLR - { + $Script:Options.Framework -ne "netcoreapp2.1" ## Last build wasn't for CoreCLR + } + + # Make sure the most recent build satisfies the package requirement + if ($precheckFailed) { # 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 @@ -124,21 +138,31 @@ function Start-PSPackage { # 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') - $params += '-CrossGen' + + # CrossGen cannot be done for framework dependent package as it is runtime agnostic. + if ($Type -ne 'fxdependent') { + $params += '-CrossGen' + } + if (!$IncludeSymbols.IsPresent) { $params += '-PSModuleRestore' } - $params += '-Runtime', $Runtime + if ($Type -eq 'fxdependent') { + $params += '-Runtime', 'fxdependent' + } else { + $params += '-Runtime', $Runtime + } + $params += '-Configuration', $Configuration throw "Please ensure you have run 'Start-PSBuild $params'!" } - if($SkipReleaseChecks.IsPresent) { + if ($SkipReleaseChecks.IsPresent) { Write-Warning "Skipping release checks." } - elseif(!$Script:Options.RootInfo.IsValid){ + elseif (!$Script:Options.RootInfo.IsValid){ throw $Script:Options.RootInfo.Warning } @@ -222,7 +246,7 @@ function Start-PSPackage { # Add the symbols to the suffix # if symbols are specified to be included - if($IncludeSymbols.IsPresent -and $NameSuffix) { + if ($IncludeSymbols.IsPresent -and $NameSuffix) { $NameSuffix = "symbols-$NameSuffix" } elseif ($IncludeSymbols.IsPresent) { @@ -242,6 +266,32 @@ function Start-PSPackage { New-ZipPackage @Arguments } } + "fxdependent" { + if ($IsWindows) { + $Arguments = @{ + PackageNameSuffix = $NameSuffix + PackageSourcePath = $Source + PackageVersion = $Version + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create Zip Package")) { + New-ZipPackage @Arguments + } + } elseif ($IsLinux) { + $Arguments = @{ + PackageSourcePath = $Source + Name = $Name + PackageNameSuffix = 'fxdependent' + Version = $Version + Force = $Force + } + + if ($PSCmdlet.ShouldProcess("Create tar.gz Package")) { + New-TarballPackage @Arguments + } + } + } "msi" { $TargetArchitecture = "x64" if ($Runtime -match "-x86") { @@ -364,7 +414,7 @@ function Start-PSPackage { } } - if($IncludeSymbols.IsPresent) + 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 @@ -383,6 +433,9 @@ function New-TarballPackage { [ValidatePattern("^powershell")] [string] $Name, + # Suffix of the Name + [string] $PackageNameSuffix, + [Parameter(Mandatory)] [string] $Version, @@ -392,7 +445,12 @@ function New-TarballPackage { [switch] $Force ) - $packageName = "$Name-$Version-{0}-$Architecture.tar.gz" + if ($PackageNameSuffix) { + $packageName = "$Name-$Version-{0}-$Architecture-$PackageNameSuffix.tar.gz" + } else { + $packageName = "$Name-$Version-{0}-$Architecture.tar.gz" + } + if ($Environment.IsWindows) { throw "Must be on Linux or macOS to build 'tar.gz' packages!" } elseif ($Environment.IsLinux) { @@ -444,7 +502,7 @@ function New-TempFolder $tempPath = [System.IO.Path]::GetTempPath() $tempFolder = Join-Path -Path $tempPath -ChildPath ([System.IO.Path]::GetRandomFileName()) - if(!(Test-Path -Path $tempFolder)) + if (!(Test-Path -Path $tempFolder)) { $null = New-Item -Path $tempFolder -ItemType Directory } @@ -499,7 +557,9 @@ function Expand-PSSignedBuild { param( [Parameter(Mandatory)] - [string]$BuildZip + [string]$BuildZip, + + [Switch]$SkipPwshExeCheck ) $psModulePath = Split-Path -path $PSScriptRoot @@ -511,7 +571,14 @@ function Expand-PSSignedBuild # That zip file is used for compliance scan. Remove-Item -Path (Join-Path -Path $buildPath -ChildPath '*.zip') -Recurse - $windowsExecutablePath = (Join-Path $buildPath -ChildPath 'pwsh.exe') + if ($SkipPwshExeCheck) + { + $windowsExecutablePath = (Join-Path $buildPath -ChildPath 'pwsh.dll') + } + else + { + $windowsExecutablePath = (Join-Path $buildPath -ChildPath 'pwsh.exe') + } Restore-PSModuleToBuild -PublishPath $buildPath @@ -522,7 +589,7 @@ function Expand-PSSignedBuild $options.PSModuleRestore = $true - if(Test-Path -Path $windowsExecutablePath) + if (Test-Path -Path $windowsExecutablePath) { $options.Output = $windowsExecutablePath } @@ -669,7 +736,7 @@ function New-UnixPackage { } $linkSource = "/tmp/pwsh" - if($pscmdlet.ShouldProcess("Create package file system")) + if ($pscmdlet.ShouldProcess("Create package file system")) { # refers to executable, does not vary by channel New-Item -Force -ItemType SymbolicLink -Path $linkSource -Target "$Destination/pwsh" >$null @@ -705,9 +772,9 @@ function New-UnixPackage { } # Add macOS powershell launcher - if($Type -eq "osxpkg") + if ($Type -eq "osxpkg") { - if($pscmdlet.ShouldProcess("Add macOS launch application")) + if ($pscmdlet.ShouldProcess("Add macOS launch application")) { # Generate launcher app folder $AppsFolder = New-MacOSLauncher -Version $Version @@ -715,7 +782,7 @@ function New-UnixPackage { } $packageDependenciesParams = @{} - if($DebDistro) + if ($DebDistro) { $packageDependenciesParams['Distribution']=$DebDistro } @@ -743,12 +810,12 @@ function New-UnixPackage { # Build package try { - if($pscmdlet.ShouldProcess("Create $type package")) { + if ($pscmdlet.ShouldProcess("Create $type package")) { $Output = Start-NativeExecution { fpm $Arguments } } } finally { if ($Environment.IsMacOS) { - if($pscmdlet.ShouldProcess("Cleanup macOS launcher")) + if ($pscmdlet.ShouldProcess("Cleanup macOS launcher")) { Clear-MacOSLauncher } @@ -798,7 +865,7 @@ function New-MacOsDistributionPackage [Switch] $IsPreview ) - if(!$Environment.IsMacOS) + if (!$Environment.IsMacOS) { throw 'New-MacOsDistributionPackage is only supported on macOS!' } @@ -984,7 +1051,7 @@ function Get-FpmArguments "$LinkSource=$LinkDestination" ) - if($AppsFolder) + if ($AppsFolder) { $Arguments += "$AppsFolder=/" } @@ -1004,7 +1071,7 @@ function Test-Distribution throw "$Distribution is required for a Debian based distribution." } - if($Script:DebianDistributions -notcontains $Distribution) + if ($Script:DebianDistributions -notcontains $Distribution) { throw "$Distribution should be one of the following: $Script:DebianDistributions" } @@ -1060,11 +1127,11 @@ function Test-Dependencies [string] $gemsPath = $null [string] $depenencyPath = $null $gemsPath = Get-ChildItem -Path /usr/lib64/ruby/gems | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName - if($gemsPath) { + if ($gemsPath) { $depenencyPath = Get-ChildItem -Path (Join-Path -Path $gemsPath -ChildPath "gems" -AdditionalChildPath $Dependency) -Recurse | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty DirectoryName $originalPath = $env:PATH $env:PATH = $ENV:PATH +":" + $depenencyPath - if((precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Package")) { + if ((precheck $Dependency "Package dependency '$Dependency' not found. Run Start-PSBootstrap -Package")) { continue } else { @@ -1128,7 +1195,7 @@ function New-ManGzip # run ronn to convert man page to roff $RonnFile = Join-Path $PSScriptRoot "/../../assets/pwsh.1.ronn" - if($IsPreview.IsPresent) + if ($IsPreview.IsPresent) { $newRonnFile = $RonnFile -replace 'pwsh', 'pwsh-preview' Copy-Item -Path $RonnFile -Destination $newRonnFile -force @@ -1140,7 +1207,7 @@ function New-ManGzip # Run ronn on assets file Start-NativeExecution { ronn --roff $RonnFile } -VerboseOutputOnError - if($IsPreview.IsPresent) + if ($IsPreview.IsPresent) { Remove-item $RonnFile } @@ -1164,7 +1231,7 @@ function Get-MacOSPackageId [switch] $IsPreview ) - if($IsPreview.IsPresent) + if ($IsPreview.IsPresent) { return 'com.microsoft.powershell-preview' } @@ -1291,17 +1358,17 @@ function New-ZipPackage $zipLocationPath = Join-Path $PWD "$zipPackageName.zip" - if($Force.IsPresent) + if ($Force.IsPresent) { - if(Test-Path $zipLocationPath) + if (Test-Path $zipLocationPath) { Remove-Item $zipLocationPath } } - If(Get-Command Compress-Archive -ErrorAction Ignore) + if (Get-Command Compress-Archive -ErrorAction Ignore) { - if($pscmdlet.ShouldProcess("Create zip package")) + if ($pscmdlet.ShouldProcess("Create zip package")) { Compress-Archive -Path $PackageSourcePath\* -DestinationPath $zipLocationPath } @@ -1427,7 +1494,7 @@ function New-UnifiedNugetPackage [string] $GenAPIToolPath ) - if(-not $Environment.IsWindows) + if (-not $Environment.IsWindows) { throw "New-UnifiedNugetPackage can be only executed on Windows platform." } @@ -1484,7 +1551,7 @@ function New-UnifiedNugetPackage { CreateNugetPlatformFolder -Platform 'linux-arm' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $linuxArm32BinPath - if($linuxMuslBinPath) + if ($linuxMuslBinPath) { CreateNugetPlatformFolder -Platform 'linux-musl-x64' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $linuxMuslBinPath } @@ -1587,12 +1654,12 @@ function New-UnifiedNugetPackage New-NugetPackage -NuSpecPath $filePackageFolder.FullName -PackageDestinationPath $PackagePath } - if(Test-Path $refBinPath) + if (Test-Path $refBinPath) { Remove-Item $refBinPath -Recurse -Force -ErrorAction SilentlyContinue } - if(Test-Path $tmpPackageRoot) + if (Test-Path $tmpPackageRoot) { Remove-Item $tmpPackageRoot -Recurse -Force -ErrorAction SilentlyContinue } @@ -1623,7 +1690,7 @@ function Get-ProjectPackageInformation # check to see if there is a newer package for each refernce foreach($package in $packages) { - if($package.Version -notmatch '\*' -and $package.Include) + if ($package.Version -notmatch '\*' -and $package.Include) { # Get the name of the package [PSCustomObject] @{ @@ -1670,7 +1737,7 @@ function New-NuSpec { [string] $FilePath ) - if(-not $Environment.IsWindows) + if (-not $Environment.IsWindows) { throw "New-NuSpec can be only executed on Windows platform." } @@ -1739,7 +1806,7 @@ function New-ReferenceAssembly [string] $SnkFilePath ) - if(-not $Environment.IsWindows) + if (-not $Environment.IsWindows) { throw "New-ReferenceAssembly can be only executed on Windows platform." } @@ -1755,7 +1822,7 @@ function New-ReferenceAssembly $genAPIExe = Get-ChildItem -Path "$GenAPIToolPath/*GenAPI.exe" -Recurse - if(-not (Test-Path $genAPIExe)) + if (-not (Test-Path $genAPIExe)) { throw "GenAPI.exe was not found at: $GenAPIToolPath" } @@ -1764,7 +1831,7 @@ function New-ReferenceAssembly $linuxSMAPath = Join-Path $Linux64BinPath "System.Management.Automation.dll" - if(-not (Test-Path $linuxSMAPath)) + if (-not (Test-Path $linuxSMAPath)) { throw "System.Management.Automation.dll was not found at: $Linux64BinPath" } @@ -1800,7 +1867,7 @@ function New-ReferenceAssembly { $match = $line | Select-String -Pattern $patternsToRemove -SimpleMatch - if($match -ne $null) + if ($match -ne $null) { $writer.WriteLine("//$line") } @@ -1809,11 +1876,11 @@ function New-ReferenceAssembly $writer.WriteLine($line) } } - if($reader -ne $null) + if ($reader -ne $null) { $reader.Close() } - if($writer -ne $null) + if ($writer -ne $null) { $writer.Close() } @@ -1840,7 +1907,7 @@ function New-ReferenceAssembly $refBinPath = Join-Path $smaProjectFolder 'bin/Release/netstandard2.0/System.Management.Automation.dll' - if($refBinPath -eq $null) + if ($refBinPath -eq $null) { throw "Reference assembly was not built." } @@ -1854,7 +1921,7 @@ function New-ReferenceAssembly Pop-Location } - if(Test-Path $genAPIFolder) + if (Test-Path $genAPIFolder) { Remove-Item $genAPIFolder -Recurse -Force -ErrorAction SilentlyContinue } @@ -1891,7 +1958,7 @@ function New-NugetPackage $nuget = Get-Command -Type Application nuget -ErrorAction SilentlyContinue - if($nuget -eq $null) + if ($nuget -eq $null) { throw 'nuget application is not available in PATH' } @@ -1900,7 +1967,7 @@ function New-NugetPackage Start-NativeExecution { nuget pack . } > $null - if(-not (Test-Path $PackageDestinationPath)) + if (-not (Test-Path $PackageDestinationPath)) { New-Item $PackageDestinationPath -ItemType Directory -Force > $null } @@ -1934,7 +2001,7 @@ function Publish-NugetToMyGet $nuget = Get-Command -Type Application nuget -ErrorAction SilentlyContinue - if($nuget -eq $null) + if ($nuget -eq $null) { throw 'nuget application is not available in PATH' } @@ -1996,7 +2063,7 @@ function New-NugetContentPackage $nugetFolder = New-SubFolder -Path $PSScriptRoot -ChildPath 'nugetOutput' -Clean $nuspecPackageName = $PackageName - if($PackageNameSuffix) + if ($PackageNameSuffix) { $nuspecPackageName += '-' + $PackageNameSuffix } @@ -2050,12 +2117,12 @@ function New-SubFolder ) $subFolderPath = Join-Path -Path $Path -ChildPath $ChildPath - if($Clean.IsPresent -and (Test-Path $subFolderPath)) + if ($Clean.IsPresent -and (Test-Path $subFolderPath)) { Remove-Item -Path $subFolderPath -Recurse -Force -ErrorAction SilentlyContinue } - if(!(Test-Path $subFolderPath)) + if (!(Test-Path $subFolderPath)) { $null = New-Item -Path $subFolderPath -ItemType Directory } @@ -2084,7 +2151,7 @@ function Get-PackageSemanticVersion } elseif ($packageVersionTokens.Count -eq 4) { # We have all the four fields $packageRevisionTokens = ($packageVersionTokens[3].Split('-'))[0] - if($NuGet.IsPresent) + if ($NuGet.IsPresent) { $packageRevisionTokens = $packageRevisionTokens.Replace('.','-') } @@ -2143,22 +2210,22 @@ function Get-NugetSemanticVersion $inIdentifier = $false foreach($token in $packageVersionTokens) { $tokenParts = $null - if($token -match '-') { + if ($token -match '-') { $tokenParts = $token.Split('-') } - elseif($inIdentifier) { + elseif ($inIdentifier) { $tokenParts = @($token) } # If we don't have token parts, then it's a versionPart - if(!$tokenParts) { + if (!$tokenParts) { $versionPartTokens += $token } else { foreach($idToken in $tokenParts) { # The first token after we detect the id Part is still # a version part - if(!$inIdentifier) { + if (!$inIdentifier) { $versionPartTokens += $idToken $inIdentifier = $true } @@ -2169,12 +2236,12 @@ function Get-NugetSemanticVersion } } - if($versionPartTokens.Count -gt 3) { + if ($versionPartTokens.Count -gt 3) { throw "Cannot create Semantic Version from the string $Version containing 4 or more version tokens" } $packageSemanticVersion = ($versionPartTokens -join '.') - if($identifierPortionTokens.Count -gt 0) { + if ($identifierPortionTokens.Count -gt 0) { $packageSemanticVersion += '-' + ($identifierPortionTokens -join '-') } @@ -2337,7 +2404,7 @@ function New-MSIPatch Write-Log "Linking patch..." Start-NativeExecution -VerboseOutputOnError {& $wixPaths.wixLightExePath -nologo $wixPatchObjPath -out $wixPatchWixMspPath} - if($Delta.IsPresent) + if ($Delta.IsPresent) { Write-Log "Generating delta msp..." Start-NativeExecution -VerboseOutputOnError {& $wixPaths.wixPyroExePath -nologo $wixPatchWixMspPath -out $mspDeltaName -t RTM $wixPatchMstPath } @@ -2424,7 +2491,7 @@ function New-MSIPackage $ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion $simpleProductVersion = '6' $isPreview = Test-IsPreview -Version $ProductSemanticVersion - if($isPreview) + if ($isPreview) { $simpleProductVersion += '-preview' } @@ -2452,7 +2519,7 @@ function New-MSIPackage [Environment]::SetEnvironmentVariable("SimpleProductVersion", $simpleProductVersion, "Process") [Environment]::SetEnvironmentVariable("ProductSemanticVersion", $ProductSemanticVersion, "Process") [Environment]::SetEnvironmentVariable("ProductVersionWithName", $productVersionWithName, "Process") - if(!$isPreview) + if (!$isPreview) { [Environment]::SetEnvironmentVariable("PwshPath", '', "Process") [Environment]::SetEnvironmentVariable("UpgradeCodeX64", '31ab5147-9a97-4452-8443-d9709f0516e1', "Process") @@ -2492,7 +2559,7 @@ function New-MSIPackage $msiLocationPath = Join-Path $pwd "$packageName.msi" $msiPdbLocationPath = Join-Path $pwd "$packageName.wixpdb" - if(!$Force.IsPresent -and (Test-Path -Path $msiLocationPath)) + if (!$Force.IsPresent -and (Test-Path -Path $msiLocationPath)) { Write-Error -Message "Package already exists, use -Force to overwrite, path: $msiLocationPath" -ErrorAction Stop } @@ -2577,14 +2644,14 @@ function Test-FileWxs foreach($file in $assetFiles) { $name = $file.Source - if($heatNodesByFile.Keys -inotcontains $name) + if ($heatNodesByFile.Keys -inotcontains $name) { $passed = $false Write-Warning "{$name} is no longer in product and should be removed from {$FilesWxsPath}" $componentId = $file.ParentNode.Id $componentXPath = '//Wix:Component[@Id="{0}"]' -f $componentId $componentNode = Get-XmlNodeByXPath -XmlDoc $newFilesAssetXml -XmlNsManager $xmlns -XPath $componentXPath - if($componentNode) + if ($componentNode) { # Remove the Component Remove-XmlElement -Element $componentNode -RemoveEmptyParents @@ -2602,7 +2669,7 @@ function Test-FileWxs # verify that no files have been added. foreach($file in $heatNodesByFile.Keys) { - if($indexedAssetFiles -inotcontains $file) + if ($indexedAssetFiles -inotcontains $file) { $passed = $false $folder = Split-Path -Path $file @@ -2628,7 +2695,7 @@ function Test-FileWxs } } - if(!$passed) + if (!$passed) { $newXmlFileName = Join-Path -Path $env:TEMP -ChildPath ([System.io.path]::GetRandomFileName() + '.xml') $newFilesAssetXml.Save($newXmlFileName) @@ -2637,7 +2704,7 @@ function Test-FileWxs $newXml = $newXml -replace 'x86', '$(var.FileArchitecture)' $newXml | Out-File -FilePath $newXmlFileName -Encoding ascii Write-Log -message "Update xml saved to $newXmlFileName" - if($env:appveyor) + if ($env:appveyor) { try { @@ -2648,7 +2715,7 @@ function Test-FileWxs Write-Warning -Message "Pushing MSI File fragment failed." } } - elseif($env:TF_BUILD -and $env:BUILD_REASON -ne 'PullRequest') + elseif ($env:TF_BUILD -and $env:BUILD_REASON -ne 'PullRequest') { Write-Host "##vso[artifact.upload containerfolder=wix;artifactname=wix]$newXmlFileName" } @@ -2674,7 +2741,7 @@ function Remove-ComponentRefNode $compRefXPath = '//Wix:ComponentRef[@Id="{0}"]' -f $Id $node = Get-XmlNodeByXPath -XmlDoc $XmlDoc -XmlNsManager $XmlNsManager -XPath $compRefXPath - if($node) + if ($node) { Remove-XmlElement -element $node } @@ -2696,7 +2763,7 @@ function Get-ComponentGroupNode $XmlNsManager ) - if(!$XmlNsManager.HasNamespace('Wix')) + if (!$XmlNsManager.HasNamespace('Wix')) { throw 'Namespace manager must have "wix" defined.' } @@ -2722,7 +2789,7 @@ function Get-DirectoryNode $XmlNsManager ) - if(!$XmlNsManager.HasNamespace('Wix')) + if (!$XmlNsManager.HasNamespace('Wix')) { throw 'Namespace manager must have "wix" defined.' } @@ -2731,11 +2798,11 @@ function Get-DirectoryNode [System.Xml.XmlElement] $dirNode = $Node.ParentNode.ParentNode $dirNodeType = $dirNode.LocalName - if($dirNodeType -eq 'DirectoryRef') + if ($dirNodeType -eq 'DirectoryRef') { return Get-XmlNodeByXPath -XmlDoc $XmlDoc -XmlNsManager $XmlNsManager -XPath "//Wix:DirectoryRef" } - if($dirNodeType -eq 'Directory') + if ($dirNodeType -eq 'Directory') { while($dirNode.LocalName -eq 'Directory') { $pathStack.Push($dirNode.Name) @@ -2748,9 +2815,9 @@ function Get-DirectoryNode $path += 'Wix:Directory[@Name="{0}"]' -f $dirName $node = Get-XmlNodeByXPath -XmlDoc $XmlDoc -XmlNsManager $XmlNsManager -XPath $path - if(!$node) + if (!$node) { - if(!$lastNode) + if (!$lastNode) { # Inserting at the root $lastNode = Get-XmlNodeByXPath -XmlDoc $XmlDoc -XmlNsManager $XmlNsManager -XPath "//Wix:DirectoryRef" diff --git a/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 b/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 index d797e567e1..67a6992a25 100644 --- a/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 +++ b/tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1 @@ -17,7 +17,8 @@ param ( [switch]$AppImage, [switch]$TarX64, - [switch]$TarArm + [switch]$TarArm, + [switch]$FxDependent ) $releaseTagParam = @{} @@ -33,9 +34,23 @@ try { Import-Module "$location/tools/packaging" Start-PSBootstrap -Package -NoSudo - Start-PSBuild -Configuration Release -Crossgen -PSModuleRestore @releaseTagParam - Start-PSPackage @releaseTagParam + $buildParams = @{ Configuration = 'Release'; PSModuleRestore = $true} + + if($FxDependent.IsPresent) { + $buildParams.Add("Runtime", "fxdependent") + } else { + $buildParams.Add("Crossgen", $true) + } + + Start-PSBuild @buildParams @releaseTagParam + + if($FxDependent) { + Start-PSPackage -Type 'fxdependent' @releaseTagParam + } else { + Start-PSPackage @releaseTagParam + } + if ($AppImage) { Start-PSPackage -Type AppImage @releaseTagParam } if ($TarX64) { Start-PSPackage -Type tar @releaseTagParam } @@ -52,6 +67,7 @@ finally } $linuxPackages = Get-ChildItem "$location/powershell*" -Include *.deb,*.rpm,*.AppImage,*.tar.gz + foreach ($linuxPackage in $linuxPackages) { $filePath = $linuxPackage.FullName diff --git a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 index fd5669657e..8af08a9ada 100644 --- a/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 +++ b/tools/releaseBuild/Images/microsoft_powershell_windowsservercore/PowerShellPackage.ps1 @@ -11,7 +11,7 @@ param ( [string] $destination = "$env:WORKSPACE", - [ValidateSet("win7-x64", "win7-x86", "win-arm", "win-arm64")] + [ValidateSet("win7-x64", "win7-x86", "win-arm", "win-arm64", "fxdependent")] [string]$Runtime = 'win7-x64', [switch] $Wait, @@ -32,12 +32,12 @@ param ( ) $releaseTagParam = @{} -if($ReleaseTag) +if ($ReleaseTag) { $releaseTagParam = @{ 'ReleaseTag' = $ReleaseTag } } -if(-not $env:homedrive) +if (-not $env:homedrive) { Write-Verbose "fixing empty home paths..." -Verbose $profileParts = $env:userprofile -split ':' @@ -45,7 +45,7 @@ if(-not $env:homedrive) $env:homepath = $profileParts[1] } -if(! (Test-Path $destination)) +if (! (Test-Path $destination)) { Write-Verbose "Creating destination $destination" -Verbose $null = New-Item -Path $destination -ItemType Directory @@ -57,7 +57,7 @@ Write-Verbose "homepath : ${env:homepath}" # Don't use CIM_PhysicalMemory, docker containers may cache old values $memoryMB = (Get-CimInstance win32_computersystem).TotalPhysicalMemory /1MB $requiredMemoryMB = 2048 -if($memoryMB -lt $requiredMemoryMB) +if ($memoryMB -lt $requiredMemoryMB) { throw "Building powershell requires at least $requiredMemoryMB MiB of memory and only $memoryMB MiB is present." } @@ -76,16 +76,24 @@ try{ Write-Verbose "Bootstrapping powershell build..." -verbose Start-PSBootstrap -Force -Package - if($PSCmdlet.ParameterSetName -eq 'packageSigned') + if ($PSCmdlet.ParameterSetName -eq 'packageSigned') { Write-Verbose "Expanding signed build..." -verbose - Expand-PSSignedBuild -BuildZip $BuildZip + if($Runtime -eq 'fxdependent') + { + Expand-PSSignedBuild -BuildZip $BuildZip -SkipPwshExeCheck + } + else + { + Expand-PSSignedBuild -BuildZip $BuildZip + } + Remove-Item -Path $BuildZip } else { Write-Verbose "Starting powershell build for RID: $Runtime and ReleaseTag: $ReleaseTag ..." -verbose - $buildParams = @{'CrossGen'= $Runtime -notmatch "arm"} + $buildParams = @{'CrossGen'= $Runtime -notmatch "arm" -and $Runtime -ne "fxdependent"} if(!$Symbols.IsPresent) { $buildParams['PSModuleRestore'] = $true @@ -94,14 +102,22 @@ try{ Start-PSBuild -Clean -Runtime $Runtime -Configuration Release @releaseTagParam @buildParams } - $pspackageParams = @{'Type'='msi'; 'WindowsRuntime'=$Runtime} - if(!$ComponentRegistration.IsPresent -and !$Symbols.IsPresent -and $Runtime -notmatch "arm") + if ($Runtime -eq 'fxdependent') + { + $pspackageParams = @{'Type'='fxdependent'} + } + else + { + $pspackageParams = @{'Type'='msi'; 'WindowsRuntime'=$Runtime} + } + + if (!$ComponentRegistration.IsPresent -and !$Symbols.IsPresent -and $Runtime -notmatch "arm" -and $Runtime -ne 'fxdependent') { Write-Verbose "Starting powershell packaging(msi)..." -verbose Start-PSPackage @pspackageParams @releaseTagParam } - if(!$ComponentRegistration.IsPresent) + if (!$ComponentRegistration.IsPresent -and $Runtime -ne 'fxdependent') { $pspackageParams['Type']='zip' $pspackageParams['IncludeSymbols']=$Symbols.IsPresent @@ -116,7 +132,21 @@ try{ Copy-Item -Path $file -Destination "$destination\" -Force } } - else { + elseif (!$ComponentRegistration.IsPresent -and $Runtime -eq 'fxdependent') + { + ## Add symbols for just like zip package. + $pspackageParams['IncludeSymbols']=$Symbols.IsPresent + Start-PSPackage @pspackageParams @releaseTagParam + + ## Copy the fxdependent Zip package to destination. + Get-ChildItem $location\PowerShell-*.zip | ForEach-Object { + $file = $_.FullName + Write-Verbose "Copying $file to $destination" -verbose + Copy-Item -Path $file -Destination "$destination\" -Force + } + } + else + { Write-Verbose "Exporting project.assets files ..." -verbose $projectAssetsCounter = 1 @@ -139,7 +169,7 @@ try{ finally { Write-Verbose "Beginning build clean-up..." -verbose - if($Wait.IsPresent) + if ($Wait.IsPresent) { $path = Join-Path $PSScriptRoot -ChildPath 'delete-to-continue.txt' $null = New-Item -Path $path -ItemType File diff --git a/tools/releaseBuild/build.json b/tools/releaseBuild/build.json index d14322c670..214ee44c41 100644 --- a/tools/releaseBuild/build.json +++ b/tools/releaseBuild/build.json @@ -200,6 +200,43 @@ "DockerImageName": "ps-winsrvcore", "BinaryBucket": "signed", "ArtifactsExpected": 1 + }, + { + "Name": "win-fxdependent-symbols", + "RepoDestinationPath": "C:\\PowerShell", + "BuildCommand": "C:\\PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent -ReleaseTag _ReleaseTag_ -Symbols", + "BuildDockerOptions": [ + "-m", + "3968m" + ], + "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\DockerFile", + "AdditionalContextFiles" :[ + ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", + ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", + ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" + ], + "DockerImageName": "ps-winsrvcore", + "BinaryBucket": "results", + "ArtifactsExpected": 1, + "VariableForExtractedBinariesPath": "Symbols_fxdependent" + }, + { + "Name": "win-fxdependent-package", + "RepoDestinationPath": "C:\\PowerShell", + "BuildCommand": "C:\\PowerShellPackage.ps1 -BuildZip _RepoDestinationPath_\\_BuildPackageName_ -location _RepoDestinationPath_ -destination _DockerVolume_ -Runtime fxdependent -ReleaseTag _ReleaseTag_", + "BuildDockerOptions": [ + "-m", + "3968m" + ], + "DockerFile": ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\DockerFile", + "AdditionalContextFiles" :[ + ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\PowerShellPackage.ps1", + ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\wix.psm1", + ".\\tools\\releaseBuild\\Images\\microsoft_powershell_windowsservercore\\dockerInstall.psm1" + ], + "DockerImageName": "ps-winsrvcore", + "BinaryBucket": "signed", + "ArtifactsExpected": 1 } ], "Linux": [ @@ -256,6 +293,15 @@ "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_alpine3/Dockerfile", "DockerImageName": "ps-alpine-3", "BinaryBucket": "release" + }, + { + "Name": "fxdependent", + "RepoDestinationPath": "/PowerShell", + "BuildCommand": "/PowerShellPackage.ps1 -location _RepoDestinationPath_ -destination _DockerVolume_ -ReleaseTag _ReleaseTag_ -FxDependent", + "AdditionalContextFiles" :[ "./tools/releaseBuild/Images/GenericLinuxFiles/PowerShellPackage.ps1"], + "DockerFile": "./tools/releaseBuild/Images/microsoft_powershell_centos7/Dockerfile", + "DockerImageName": "ps-centos-7", + "BinaryBucket": "release" } ] } diff --git a/tools/releaseBuild/createComplianceFolder.ps1 b/tools/releaseBuild/createComplianceFolder.ps1 index 28716f0390..d036f65dce 100644 --- a/tools/releaseBuild/createComplianceFolder.ps1 +++ b/tools/releaseBuild/createComplianceFolder.ps1 @@ -15,9 +15,9 @@ foreach($folder in $ArtifactFolder) # Find Symbols zip which contains compliance files Write-Host "ArtifactFolder: $folder" $filename = Join-Path -Path $folder -ChildPath 'symbols.zip' - + $parentName = Split-Path -Path $folder -Leaf - + # Use simplified names because some of the compliance tools didn't like the full names # decided not to use hashes because the names need to be consistent otherwise the tool also has issues # which is another problem with the full name, it includes version. @@ -28,7 +28,10 @@ foreach($folder in $ArtifactFolder) elseif ($parentName -match 'x86') { $name = 'x86' } - else + elseif ($parentName -match 'fxdependent') { + $name = 'fxd' + } + else { throw "$parentName could not be classified as x86 or x64" } @@ -53,4 +56,4 @@ foreach($folder in $ArtifactFolder) } # set VSTS variable with path to compliance files -Write-Host "##vso[task.setvariable variable=$VSTSVariableName]$unzipPath" \ No newline at end of file +Write-Host "##vso[task.setvariable variable=$VSTSVariableName]$unzipPath" diff --git a/tools/releaseBuild/updateSigning.ps1 b/tools/releaseBuild/updateSigning.ps1 index 32419153f6..bd017976f9 100644 --- a/tools/releaseBuild/updateSigning.ps1 +++ b/tools/releaseBuild/updateSigning.ps1 @@ -1,16 +1,24 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. param( - [string] $SigningXmlPath = (Join-Path -Path $PSScriptRoot -ChildPath 'signing.xml') + [string] $SigningXmlPath = (Join-Path -Path $PSScriptRoot -ChildPath 'signing.xml'), + [switch] $SkipPwshExe ) # Script for use in VSTS to update signing.xml +if ($SkipPwshExe) { + ## This is required for fxdependent package as no .exe is generated. + $xmlContent = Get-Content $SigningXmlPath | Where-Object { $_ -notmatch '__INPATHROOT__\\pwsh.exe'} +} else { + $xmlContent = Get-Content $signingXmlPath +} + # Parse the signing xml -$signingXml = [xml](Get-Content $signingXmlPath) +$signingXml = [xml] $xmlContent # Get any variables to updating 'signType' in the XML # Define a varabile named `SignType' in VSTS to updating that signing type -# Example: $env:AuthenticodeSignType='newvalue' +# Example: $env:AuthenticodeSignType='newvalue' # will cause all files with the 'Authenticode' signtype to be updated with the 'newvalue' signtype $signTypes = @{} Get-ChildItem -Path env:/*SignType | ForEach-Object -Process { @@ -20,7 +28,7 @@ Get-ChildItem -Path env:/*SignType | ForEach-Object -Process { } # examine each job in the xml -$signingXml.SignConfigXML.job | ForEach-Object -Process { +$signingXml.SignConfigXML.job | ForEach-Object -Process { # examine each file in the job $_.file | ForEach-Object -Process { # if the sign type is one of the variables we found, update it to the new value