diff --git a/.vsts-ci/linux.yml b/.vsts-ci/linux.yml index 04451cba405..be7de6d8fc5 100644 --- a/.vsts-ci/linux.yml +++ b/.vsts-ci/linux.yml @@ -30,6 +30,8 @@ pr: - .vsts-ci/misc-analysis.yml - .github/ISSUE_TEMPLATE/* - .dependabot/config.yml + - .vsts-ci/windows.yml + - .vsts-ci/windows/* variables: DOTNET_CLI_TELEMETRY_OPTOUT: 1 diff --git a/.vsts-ci/mac.yml b/.vsts-ci/mac.yml index 55666e05d03..55d29959336 100644 --- a/.vsts-ci/mac.yml +++ b/.vsts-ci/mac.yml @@ -31,6 +31,8 @@ pr: - .dependabot/config.yml - tools/releaseBuild/* - tools/releaseBuild/azureDevOps/templates/* + - /.vsts-ci/windows.yml + - /.vsts-ci/windows/* variables: DOTNET_CLI_TELEMETRY_OPTOUT: 1 diff --git a/.vsts-ci/windows.yml b/.vsts-ci/windows.yml index 6554e3f38e5..bdaa015832e 100644 --- a/.vsts-ci/windows.yml +++ b/.vsts-ci/windows.yml @@ -73,11 +73,3 @@ stages: tagSet: Others - template: templates/verify-xunit.yml - -- stage: PackagingWin - displayName: Packaging for Windows - dependsOn: [] # by specifying an empty array, this stage doesn't depend on the stage before it - jobs: - # Unlike daily builds, we do not upload nuget package to MyGet so we do not wait on tests to finish. - - template: templates/windows-packaging.yml - diff --git a/.vsts-ci/templates/windows-packaging.yml b/.vsts-ci/windows/templates/windows-packaging.yml similarity index 70% rename from .vsts-ci/templates/windows-packaging.yml rename to .vsts-ci/windows/templates/windows-packaging.yml index 2c691809885..c3c6bfcfe3e 100644 --- a/.vsts-ci/templates/windows-packaging.yml +++ b/.vsts-ci/windows/templates/windows-packaging.yml @@ -1,16 +1,18 @@ parameters: pool: 'Hosted VS2017' jobName: 'win_packaging' + architecture: 'x64' + channel: 'preview' parentJobs: [] jobs: -- job: ${{ parameters.jobName }} +- job: ${{ parameters.jobName }}_${{ parameters.channel }}_${{ parameters.architecture }} dependsOn: ${{ parameters.parentJobs }} pool: name: ${{ parameters.pool }} - displayName: Windows Packaging + displayName: Windows Packaging - ${{ parameters.architecture }} - ${{ parameters.channel }} steps: - powershell: | @@ -30,5 +32,5 @@ jobs: - pwsh: | Import-Module .\tools\ci.psm1 New-CodeCoverageAndTestPackage - Invoke-CIFinish + Invoke-CIFinish -Runtime win7-${{ parameters.architecture }} -channel ${{ parameters.channel }} displayName: Build and Test Package diff --git a/.vsts-ci/windows/windows-packaging.yml b/.vsts-ci/windows/windows-packaging.yml new file mode 100644 index 00000000000..e3edb42d4c4 --- /dev/null +++ b/.vsts-ci/windows/windows-packaging.yml @@ -0,0 +1,85 @@ +name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr) +trigger: + # Batch merge builds together while a merge build is running + batch: true + branches: + include: + - master + - release* + - feature* + paths: + include: + - /.vsts-ci/templates/windows-packaging.yml + - /.vsts-ci/windows-packaging.yml + - /global.json + - /src/* + - /tools/ci.psm1 + - /tools/packaging/* + - /assets/* + +pr: + branches: + include: + - master + - release* + - feature* + paths: + # file extension filters are not supported when this was written. + # This really should be /src/**/*.csproj + include: + - /.vsts-ci/templates/windows-packaging.yml + - /.vsts-ci/windows-packaging.yml + - /global.json + - /src/Microsoft.Management.Infrastructure.CimCmdlets/Microsoft.Management.Infrastructure.CimCmdlets.csproj + - /src/Microsoft.Management.UI.Internal/Microsoft.PowerShell.GraphicalHost.csproj + - /src/Microsoft.PowerShell.Commands.Diagnostics/Microsoft.PowerShell.Commands.Diagnostics.csproj + - /src/Microsoft.PowerShell.Commands.Management/Microsoft.PowerShell.Commands.Management.csproj + - /src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj + - /src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj + - /src/Microsoft.PowerShell.CoreCLR.Eventing/Microsoft.PowerShell.CoreCLR.Eventing.csproj + - /src/Microsoft.PowerShell.GlobalTool.Shim/Microsoft.PowerShell.GlobalTool.Shim.csproj + - /src/Microsoft.PowerShell.LocalAccounts/Microsoft.PowerShell.LocalAccounts.csproj + - /src/Microsoft.PowerShell.MarkdownRender/Microsoft.PowerShell.MarkdownRender.csproj + - /src/Microsoft.PowerShell.SDK/Microsoft.PowerShell.SDK.csproj + - /src/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.csproj + - /src/Microsoft.WSMan.Management/Microsoft.WSMan.Management.csproj + - /src/Microsoft.WSMan.Runtime/Microsoft.WSMan.Runtime.csproj + - /src/Modules/PSGalleryModules.csproj + - /src/powershell-win-core/powershell-win-core.csproj + - /tools/ci.psm1 + - /tools/packaging/* + - /assets/files.wxs + - /assets/Product.wxs + +variables: + - name: GIT_CONFIG_PARAMETERS + value: "'core.autocrlf=false'" + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: 1 + - name: POWERSHELL_TELEMETRY_OPTOUT + value: 1 + # Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds + - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE + value: 1 + - name: __SuppressAnsiEscapeSequences + value: 1 + - group: fakeNugetKey + +resources: +- repo: self + clean: true +stages: +- stage: PackagingWin + displayName: Packaging for Windows + dependsOn: [] # by specifying an empty array, this stage doesn't depend on the stage before it + jobs: + # Unlike daily builds, we do not upload nuget package to MyGet so we do not wait on tests to finish. + - template: templates/windows-packaging.yml + - template: templates/windows-packaging.yml + parameters: + channel: stable + architecture: x86 + - template: templates/windows-packaging.yml + parameters: + channel: preview + architecture: x86 diff --git a/test/packaging/windows/msi.tests.ps1 b/test/packaging/windows/msi.tests.ps1 index d9541b74f06..ce9e3334557 100644 --- a/test/packaging/windows/msi.tests.ps1 +++ b/test/packaging/windows/msi.tests.ps1 @@ -53,6 +53,8 @@ Describe -Name "Windows MSI" -Fixture { } $msiX64Path = $env:PsMsiX64Path + $channel = $env:PSMsiChannel + $runtime = $env:PSMsiRuntime # Get any existing powershell in the path $beforePath = @(([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' | @@ -82,12 +84,29 @@ Describe -Name "Windows MSI" -Fixture { Context "Upgrade code" { BeforeAll { - $previewUpgladeCode = '39243d76-adaf-42b1-94fb-16ecf83237c8' + Write-Verbose "cr-$channel-$runtime" -Verbose + switch ("$channel-$runtime") { + "preview-win7-x64" { + $msiUpgradeCode = '39243d76-adaf-42b1-94fb-16ecf83237c8' + } + "stable-win7-x64" { + $msiUpgradeCode = '31ab5147-9a97-4452-8443-d9709f0516e1' + } + "preview-win7-x86" { + $msiUpgradeCode = '86abcfbd-1ccc-4a88-b8b2-0facfde29094' + } + "stable-win7-x86" { + $msiUpgradeCode = '1d00683b-0f84-4db8-a64f-2f98ad42fe06' + } + default { + throw "'$_' not a valid channel runtime combination" + } + } } - It "Preview MSI should not be installed before test" -Skip:(!(Test-Elevated)) { - $result = @(Get-CimInstance -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' and Value = '{$previewUpgladeCode}'") - $result.Count | Should -Be 0 -Because 'Query should return nothing if preview x64 is not installed' + It "$Channel MSI should not be installed before test" -Skip:(!(Test-Elevated)) { + $result = @(Get-CimInstance -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' and Value = '{$msiUpgradeCode}'") + $result.Count | Should -Be 0 -Because "Query should return nothing if $channel x64 is not installed" } It "MSI should install without error" -Skip:(!(Test-Elevated)) { @@ -97,8 +116,8 @@ Describe -Name "Windows MSI" -Fixture { } It "Upgrade code should be correct" -Skip:(!(Test-Elevated)) { - $result = @(Get-CimInstance -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' and Value = '{$previewUpgladeCode}'") - $result.Count | Should -Be 1 -Because 'Query should return 1 result if Upgrade code is for x64 preview' + $result = @(Get-CimInstance -Query "SELECT Value FROM Win32_Property WHERE Property='UpgradeCode' and Value = '{$msiUpgradeCode}'") + $result.Count | Should -Be 1 -Because "Query should return 1 result if Upgrade code is for x64 $channel" } It "MSI should uninstall without error" -Skip:(!(Test-Elevated)) { @@ -117,7 +136,7 @@ Describe -Name "Windows MSI" -Fixture { It "MSI should have not be updated path" -Skip:(!(Test-Elevated)) { $psPath = ([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' | - Where-Object {$_ -like '*files\powershell*' -and $_ -notin $beforePath} + Where-Object { $_ -like '*files\powershell*' -and $_ -notin $beforePath } $psPath | Should -BeNullOrEmpty } @@ -137,8 +156,20 @@ Describe -Name "Windows MSI" -Fixture { } It "MSI should have updated path" -Skip:(!(Test-Elevated)) { + if ($channel -eq 'preview') { + $pattern = '*files*\powershell*\preview*' + } else { + $pattern = '*files*\powershell*' + } + $psPath = ([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' | - Where-Object {$_ -like '*files\powershell*\preview*' -and $_ -notin $beforePath} + Where-Object { $_ -like $pattern -and $_ -notin $beforePath } + + if (!$psPath) { + ([System.Environment]::GetEnvironmentVariable('PATH', 'MACHINE')) -split ';' | + Where-Object { $_ -notin $beforePath } | + ForEach-Object { Write-Verbose -Verbose $_ } + } $psPath | Should -Not -BeNullOrEmpty } diff --git a/tools/ci.psm1 b/tools/ci.psm1 index 2042349445f..f978decf64a 100644 --- a/tools/ci.psm1 +++ b/tools/ci.psm1 @@ -437,30 +437,45 @@ function Get-ReleaseTag # Implements CI 'on_finish' step function Invoke-CIFinish { + param( + [string] $Runtime = 'win7-x64', + [string] $Channel = 'preview' + ) + if($PSEdition -eq 'Core' -and ($IsLinux -or $IsMacOS)) { return New-LinuxPackage } try { - $releaseTag = Get-ReleaseTag - $previewVersion = $releaseTag.Split('-') - $previewPrefix = $previewVersion[0] - $previewLabel = $previewVersion[1].replace('.','') - - if(Test-DailyBuild) + if($Channel -eq 'preview') { - $previewLabel= "daily{0}" -f $previewLabel - } + $releaseTag = Get-ReleaseTag - $preReleaseVersion = "$previewPrefix-$previewLabel.$env:BUILD_BUILDID" + $previewVersion = $releaseTag.Split('-') + $previewPrefix = $previewVersion[0] + $previewLabel = $previewVersion[1].replace('.','') - # Build clean before backing to remove files from testing - Start-PSBuild -CrossGen -PSModuleRestore -Configuration 'Release' -ReleaseTag $preReleaseVersion -Clean + if(Test-DailyBuild) + { + $previewLabel= "daily{0}" -f $previewLabel + } + + $preReleaseVersion = "$previewPrefix-$previewLabel.$env:BUILD_BUILDID" + # Build clean before backing to remove files from testing + Start-PSBuild -CrossGen -PSModuleRestore -Configuration 'Release' -ReleaseTag $preReleaseVersion -Clean -Runtime $Runtime + } + else { + $releaseTag = Get-ReleaseTag + $releaseTagParts = $releaseTag.split('.') + $preReleaseVersion = $releaseTagParts[0]+ ".9.9" + Write-Verbose "newPSReleaseTag: $preReleaseVersion" -Verbose + Start-PSBuild -CrossGen -PSModuleRestore -Configuration 'Release' -ReleaseTag $preReleaseVersion -Clean -Runtime $Runtime + } - # Build packages - $packages = Start-PSPackage -Type msi,nupkg,zip,zip-pdb -ReleaseTag $preReleaseVersion -SkipReleaseChecks + # Build packages $preReleaseVersion = "$previewPrefix-$previewLabel.$env:BUILD_BUILDID" + $packages = Start-PSPackage -Type msi,nupkg,zip,zip-pdb -ReleaseTag $preReleaseVersion -SkipReleaseChecks -WindowsRuntime $Runtime $artifacts = New-Object System.Collections.ArrayList foreach ($package in $packages) { @@ -486,6 +501,8 @@ function Invoke-CIFinish # the packaging tests find the MSI package using env:PSMsiX64Path $env:PSMsiX64Path = $artifacts | Where-Object { $_.EndsWith(".msi")} + $env:PSMsiChannel = $Channel + $env:PSMsiRuntime = $Runtime # Install the latest Pester and import it $maximumPesterVersion = '4.99' diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 03bcb63461b..93e713f21c2 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -336,6 +336,7 @@ function Start-PSPackage { if ($Runtime -match "-x86") { $TargetArchitecture = "x86" } + Write-Verbose "TargetArchitecture = $TargetArchitecture" -Verbose $Arguments = @{ ProductNameSuffix = $NameSuffix