diff --git a/test/powershell/Host/HostUtilities.Tests.ps1 b/test/powershell/Host/HostUtilities.Tests.ps1 index 96145b41ca..937e167c60 100644 --- a/test/powershell/Host/HostUtilities.Tests.ps1 +++ b/test/powershell/Host/HostUtilities.Tests.ps1 @@ -32,7 +32,7 @@ Describe "InvokeOnRunspace method as nested command" -tags "Feature" { } } -Describe "InvokeOnRunspace method on remote runspace" -tags "Feature" { +Describe "InvokeOnRunspace method on remote runspace" -tags "Feature","RequireAdminOnWindows" { BeforeAll { diff --git a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 index b93891632b..c87ce887d7 100644 --- a/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 +++ b/test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1 @@ -491,7 +491,7 @@ Describe "TabCompletion" -Tags CI { ## if $PSHOME contains a space tabcompletion adds ' around the path @{ inputStr = 'cd $pshome\Modu'; expected = if($PSHOME.Contains(' ')) { "'$(Join-Path $PSHOME 'Modules')'" } else { Join-Path $PSHOME 'Modules' }; setup = $null } @{ inputStr = 'cd "$pshome\Modu"'; expected = "`"$(Join-Path $PSHOME 'Modules')`""; setup = $null } - @{ inputStr = '$PSHOME\System.Management.Au'; expected = Join-Path $PSHOME 'System.Management.Automation.dll'; setup = $null } + @{ inputStr = '$PSHOME\System.Management.Au'; expected = if($PSHOME.Contains(' ')) { "`& '$(Join-Path $PSHOME 'System.Management.Automation.dll')'" } else { Join-Path $PSHOME 'System.Management.Automation.dll'; setup = $null }} @{ inputStr = '"$PSHOME\System.Management.Au"'; expected = "`"$(Join-Path $PSHOME 'System.Management.Automation.dll')`""; setup = $null } @{ inputStr = '& "$PSHOME\System.Management.Au"'; expected = "`"$(Join-Path $PSHOME 'System.Management.Automation.dll')`""; setup = $null } ## tab completion AST-based tests @@ -1045,7 +1045,7 @@ dir -Recurse ` } } -Describe "Tab completion tests with remote Runspace" -Tags Feature { +Describe "Tab completion tests with remote Runspace" -Tags Feature,RequireAdminOnWindows { BeforeAll { if ($IsWindows) { $session = New-RemoteSession @@ -1116,9 +1116,7 @@ Describe "WSMan Config Provider tab complete tests" -Tags Feature,RequireAdminOn $res = TabExpansion2 -inputScript $path -cursorColumn $path.Length $listener = Get-ChildItem WSMan:\localhost\Listener $res.CompletionMatches.Count | Should -Be $listener.Count - for ($i = 0; $i -lt $res.CompletionMatches.Count; $i++) { - $res.CompletionMatches[$i].ListItemText | Should -Be $listener[$i].Name - } + $res.CompletionMatches.ListItemText | Should -BeIn $listener.Name } It "Tab completion gets dynamic parameters for '' using ''" -TestCases @( diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/RemoteGetModule.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/RemoteGetModule.Tests.ps1 index 985b20291e..27bab77bd7 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/RemoteGetModule.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/RemoteGetModule.Tests.ps1 @@ -3,18 +3,28 @@ Describe "Remote module tests" -Tags 'Feature','RequireAdminOnWindows' { BeforeAll { - $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() - if (!$IsWindows) { + + if (!$IsWindows) + { + $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() $PSDefaultParameterValues["it:skip"] = $true - } else { - $pssession = New-RemoteSession - # pending https://github.com/PowerShell/PowerShell/issues/4819 - # $cimsession = New-RemoteSession -CimSession + return } + + $pssession = New-RemoteSession + # pending https://github.com/PowerShell/PowerShell/issues/4819 + # $cimsession = New-RemoteSession -CimSession } AfterAll { - $global:PSDefaultParameterValues = $originalDefaultParameterValues + + if (!$IsWindows) + { + $global:PSDefaultParameterValues = $originalDefaultParameterValues + return + } + + if ($pssession -ne $null) { Remove-PSSession $pssession -ErrorAction SilentlyContinue } } It "Get-Module fails if not using -ListAvailable with ''" -TestCases @( diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Rename-Computer.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Rename-Computer.Tests.ps1 index 8cb63a0583..a2ed536220 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Rename-Computer.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Rename-Computer.Tests.ps1 @@ -13,7 +13,7 @@ try Enable-Testhook -testhookName TestStopComputer # TEST START HERE - Describe "Rename-Computer" -Tag Feature { + Describe "Rename-Computer" -Tag Feature,RequireAdminOnWindows { # if we throw in BeforeEach, the test will fail and the stop will not be called BeforeEach { if ( ! (Test-TesthookIsSet -testhookName $RenameTesthook) ) { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1 index feb4c07e09..6bb32d48e3 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1 @@ -12,7 +12,7 @@ try $PSDefaultParameterValues["it:skip"] = ! $IsWindows Enable-Testhook -testhookName $restartTesthookName - Describe "Restart-Computer" -Tag Feature { + Describe "Restart-Computer" -Tag Feature,RequireAdminOnWindows { # if we throw in BeforeEach, the test will fail and the restart will not be called BeforeEach { if ( ! (Test-TesthookIsSet -testhookName $restartTesthookName) ) { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 index fa9789c7f5..60a1cc2bba 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 @@ -1,6 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -Describe "Start-Process" -Tags @("Feature") { +Describe "Start-Process" -Tag "Feature","RequireAdminOnWindows" { BeforeAll { $isNanoServer = [System.Management.Automation.Platform]::IsNanoServer @@ -113,7 +113,7 @@ Describe "Start-Process" -Tags @("Feature") { } It "Should start notepad.exe with ShellExecute" -Skip:(!$isFullWin) { - $process = Start-Process notepad -PassThru -WindowStyle Normal + $process = Start-Process notepad.exe -PassThru -WindowStyle Normal $process.Name | Should -Be "notepad" $process | Stop-Process } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Implicit.Remoting.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Implicit.Remoting.Tests.ps1 index abe47d5dae..6fca0330ff 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Implicit.Remoting.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Implicit.Remoting.Tests.ps1 @@ -11,25 +11,6 @@ $PSDefaultParameterValues["it:skip"] = $skipTest try { - # - # Ensure WinRM remoting is enabled - # - if (! $skipTest) - { - # Check to see if a default endpoint has been created - $endpointName = "PowerShell.$($psversiontable.GitCommitId)" - $matchedEndpoint = Get-PSSessionConfiguration $endpointName -ErrorAction SilentlyContinue - - if ($matchedEndpoint -eq $null) - { - # An endpoint for this instance of PowerShell does not exist. - # - # -SkipNetworkProfileCheck is used in case Docker or another application - # has created a publich virtual network profile on the system - Enable-PSRemoting -SkipNetworkProfileCheck - } - } - Describe "Implicit remoting and CIM cmdlets with AllSigned and Restricted policy" -tags "Feature","RequireAdminOnWindows" { BeforeAll { diff --git a/test/powershell/Modules/Microsoft.WSMan.Management/TestWSMan.Tests.ps1 b/test/powershell/Modules/Microsoft.WSMan.Management/TestWSMan.Tests.ps1 index 9db02182b4..ec824ec0b0 100644 --- a/test/powershell/Modules/Microsoft.WSMan.Management/TestWSMan.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.WSMan.Management/TestWSMan.Tests.ps1 @@ -1,6 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -Describe "TestWSMan tests" -Tags 'Feature' { +Describe "TestWSMan tests" -Tags 'Feature','RequireAdminOnWindows' { BeforeAll { $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() @@ -46,13 +46,14 @@ Describe "TestWSMan tests" -Tags 'Feature' { { Test-WSMan -Authentication foo -ErrorAction Stop } | Should -Throw -ErrorId "CannotConvertArgumentNoMessage,Microsoft.WSMan.Management.TestWSManCommand" } - It "Test-WSMan works for ''" -TestCases @( - @{ computername = $null }, - @{ computername = "localhost" }, - @{ computername = $env:COMPUTERNAME } + It "Test-WSMan works for " -TestCases @( + @{ testName = "Null"; computername = $null }, + @{ testName = "localhost"; computername = "localhost" }, + @{ testName = "computername"; computername = $env:COMPUTERNAME } ) { param($computername) $response = Test-WSMan -ComputerName $computername + $response | Should -Not -BeNullOrEmpty $response.PSObject.TypeNames[0] | Should -Be "System.Xml.XmlElement#http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd#IdentifyResponse" $response.wsmid | Should -Be "http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd" $response.ProtocolVersion | Should -Be "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" diff --git a/test/powershell/engine/Remoting/ImplicitRemotingBatching.Tests.ps1 b/test/powershell/engine/Remoting/ImplicitRemotingBatching.Tests.ps1 index c694e52a56..b305bed3d2 100644 --- a/test/powershell/engine/Remoting/ImplicitRemotingBatching.Tests.ps1 +++ b/test/powershell/engine/Remoting/ImplicitRemotingBatching.Tests.ps1 @@ -1,22 +1,55 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -Describe "TestImplicitRemotingBatching hook should correctly batch simple remote command pipelines" -Tags 'Feature','RequireAdminOnWindows' { +Describe "TestImplicitRemotingBatching hook should correctly batch simple remote command pipelines" -Tag 'Feature','RequireAdminOnWindows' { BeforeAll { if (! $isWindows) { return } + function ThrowSetupError + { + param ( + [string] $errorMessage, + [System.Management.Automation.ErrorRecord[]] $eRecords + ) + + $msg = @() + foreach ($err in $powerShell.Streams.Error) + { + $msg += $err.ToString() + "`n" + } + + throw "$errorMessage : '$msg'" + } + + # Make sure we can create a remote session + $remotePSSession = New-RemoteSession + if ($remotePSSession -eq $null) + { + Write-Verbose "Unable to create a remote session in test." + } + else + { + Remove-PSSession $remotePSSession + } + [powershell] $powerShell = [powershell]::Create([System.Management.Automation.RunspaceMode]::NewRunspace) # Create remote session in new PowerShell session $powerShell.AddScript('Import-Module -Name HelpersRemoting; $remoteSession = New-RemoteSession').Invoke() - if ($powerShell.Streams.Error.Count -gt 0) { throw "Unable to create remote session for test" } + if ($powerShell.Streams.Error.Count -gt 0) + { + ThrowSetupError -errorMessage "Unable to create remote session for test with error" -eRecords $powerShell.Streams.Error + } # Import implicit commands from remote session $powerShell.Commands.Clear() $powerShell.AddScript('Import-PSSession -Session $remoteSession -CommandName Get-Process,Write-Output -AllowClobber').Invoke() - if ($powerShell.Streams.Error.Count -gt 0) { throw "Unable to import pssession for test" } + if ($powerShell.Streams.Error.Count -gt 0) + { + ThrowSetupError -errorMessage "Unable to import pssession for test" -eRecords $powerShell.Streams.Error + } # Define $filter variable in local session $powerShell.Commands.Clear() diff --git a/test/powershell/engine/Remoting/InvokeCommandRemoteDebug.Tests.ps1 b/test/powershell/engine/Remoting/InvokeCommandRemoteDebug.Tests.ps1 index 1b81b1d3fd..8053cf6838 100644 --- a/test/powershell/engine/Remoting/InvokeCommandRemoteDebug.Tests.ps1 +++ b/test/powershell/engine/Remoting/InvokeCommandRemoteDebug.Tests.ps1 @@ -116,39 +116,36 @@ if ($IsWindows) '@ } -Describe "Invoke-Command remote debugging tests" -Tags 'Feature' { +Describe "Invoke-Command remote debugging tests" -Tags 'Feature','RequireAdminOnWindows' { BeforeAll { if (!$IsWindows) { $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() - $PSDefaultParameterValues["it:Pending"] = $true + $PSDefaultParameterValues["it:skip"] = $true + return } - else - { - $sb = [scriptblock]::Create(@' - "Hello!" -'@) - Add-Type -TypeDefinition $typeDef + $sb = [scriptblock]::Create('"Hello!"') - $dummyHost = [TestRunner.DummyHost]::new() - [runspace] $rs = [runspacefactory]::CreateRunspace($dummyHost) - $rs.Open() - $dummyHost._runspace = $rs + Add-Type -TypeDefinition $typeDef - $testDebugger = [TestRunner.TestDebugger]::new($rs) + $dummyHost = [TestRunner.DummyHost]::new() + [runspace] $rs = [runspacefactory]::CreateRunspace($dummyHost) + $rs.Open() + $dummyHost._runspace = $rs - [runspace] $rs2 = [runspacefactory]::CreateRunspace() - $rs2.Open() + $testDebugger = [TestRunner.TestDebugger]::new($rs) - [powershell] $ps = [powershell]::Create() - $ps.Runspace = $rs + [runspace] $rs2 = [runspacefactory]::CreateRunspace() + $rs2.Open() - [powershell] $ps2 = [powershell]::Create() - $ps2.Runspace = $rs2 - } + [powershell] $ps = [powershell]::Create() + $ps.Runspace = $rs + + [powershell] $ps2 = [powershell]::Create() + $ps2.Runspace = $rs2 } AfterAll { @@ -156,16 +153,15 @@ Describe "Invoke-Command remote debugging tests" -Tags 'Feature' { if (!$IsWindows) { $global:PSDefaultParameterValues = $originalDefaultParameterValues + return } - else - { - if ($null -ne $testDebugger) { $testDebugger.Release() } - if ($null -ne $ps) { $ps.Dispose() } - if ($null -ne $ps2) { $ps2.Dispose() } - if ($null -ne $rs) { $rs.Dispose() } - if ($null -ne $rs2) { $rs2.Dispose() } - if ($null -ne $remoteSession) { Remove-PSSession $remoteSession -ErrorAction SilentlyContinue } - } + + if ($null -ne $testDebugger) { $testDebugger.Release() } + if ($null -ne $ps) { $ps.Dispose() } + if ($null -ne $ps2) { $ps2.Dispose() } + if ($null -ne $rs) { $rs.Dispose() } + if ($null -ne $rs2) { $rs2.Dispose() } + if ($null -ne $remoteSession) { Remove-PSSession $remoteSession -ErrorAction SilentlyContinue } } BeforeEach { diff --git a/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 b/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 index 33b63571e6..631c5e1b8c 100644 --- a/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 +++ b/test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 @@ -277,7 +277,7 @@ Describe "Remoting loopback tests" -Tags @('CI', 'RequireAdminOnWindows') { } It 'Can invoke-command as job' { - $result = Invoke-Command -ScriptBlock { 1 + 1 } -Session $openSession -AsJob | Receive-Job -AutoRemoveJob -Wait + $result = Invoke-Command -ScriptBlock { 1 + 1 } -Session $openSession -AsJob | Receive-Job -AutoRemoveJob -Wait -ErrorAction SilentlyContinue $result | Should -Be 2 } diff --git a/test/powershell/engine/ResourceValidation/TestRunner.ps1 b/test/powershell/engine/ResourceValidation/TestRunner.ps1 index 01e3db38dc..05bbf6107c 100644 --- a/test/powershell/engine/ResourceValidation/TestRunner.ps1 +++ b/test/powershell/engine/ResourceValidation/TestRunner.ps1 @@ -36,6 +36,16 @@ function Test-ResourceStrings # This is the reason why this is not a general module for use. There is # no other way to run these tests Describe "Resources strings in $AssemblyName (was -ResGen used with Start-PSBuild)" -tag Feature { + + function NormalizeLineEnd + { + param ( + [string] $string + ) + + $string -replace "`r`n", "`n" + } + foreach ( $resourceFile in $resourceFiles ) { # in the event that the id has a space in it, it is replaced with a '_' @@ -50,7 +60,8 @@ function Test-ResourceStrings # check all the resource strings $xmlData = [xml](Get-Content $resourceFile.Fullname) foreach ( $inResource in $xmlData.root.data ) { - $resourceType.GetProperty($inResource.name,$bindingFlags).GetValue(0) | Should -Be $inresource.value + $resourceStringToCheck = $resourceType.GetProperty($inResource.name,$bindingFlags).GetValue(0) + NormalizeLineEnd($resourceStringToCheck) | Should -Be (NormalizeLineEnd($inresource.value)) } } } diff --git a/test/tools/Modules/HelpersRemoting/HelpersRemoting.psm1 b/test/tools/Modules/HelpersRemoting/HelpersRemoting.psm1 index 8fb67f63bb..23d2178307 100644 --- a/test/tools/Modules/HelpersRemoting/HelpersRemoting.psm1 +++ b/test/tools/Modules/HelpersRemoting/HelpersRemoting.psm1 @@ -10,10 +10,53 @@ if ($IsWindows) { try { $Script:AppVeyorRemoteCred = Import-Clixml -Path "$env:TEMP\AppVeyorRemoteCred.xml" } catch { } } +function Get-DefaultEndPointName +{ + $endPointName = "PowerShell.$(${PSVersionTable}.GitCommitId)" + $endPoint = Get-PSSessionConfiguration -Name $endPointName -ErrorAction SilentlyContinue + + if ($endPoint -eq $null) + { + Enable-PSRemoting -SkipNetworkProfileCheck + $endPoint = Get-PSSessionConfiguration -Name $endPointName -ErrorAction SilentlyContinue + + if ($endPoint -eq $null) + { + Write-Warning "Unable to create the remoting configuration endpoint for this PowerShell version: $(${PSVersionTable}.PSVersion)" + return $endPointName + } + } + + if ($endPoint.Permission -like "*NT AUTHORITY\NETWORK AccessDenied*") + { + Enable-PSRemoting -SkipNetworkProfileCheck + $endPoint = Get-PSSessionConfiguration -Name $endPointName -ErrorAction SilentlyContinue + + if ($endPoint.Permission -like "*NT AUTHORITY\NETWORK AccessDenied*") + { + Write-Warning "Unable to enable the remoting configuration endpoint: $(${PSVersionTable}.PSVersion)" + } + } + + return $endPointName +} + function New-RemoteRunspace { + param ( + [string] $ConfigurationName + ) + + # For PSCore6, we want to always test against a remoting endpoint running PSCore6 (not Windows PowerShell) + if ([string]::IsNullOrEmpty($ConfigurationName)) + { + $ConfigurationName = Get-DefaultEndPointName + } + $wsmanConInfo = [System.Management.Automation.Runspaces.WSManConnectionInfo]::new() + $wsmanConInfo.ShellUri = 'http://schemas.microsoft.com/powershell/' + $ConfigurationName + if ($Script:AppVeyorRemoteCred) { Write-Verbose "Using Global AppVeyor Credential" -Verbose @@ -27,6 +70,8 @@ function New-RemoteRunspace $remoteRunspace = [runspacefactory]::CreateRunspace($Host, $wsmanConInfo) $remoteRunspace.Open() + Write-Verbose "Successfully created remote runspace on endpoint: $ConfigurationName" + return $remoteRunspace } @@ -95,7 +140,14 @@ function New-RemoteSession [string] $Name, [string] $ConfigurationName, [switch] $CimSession, - [System.Management.Automation.Remoting.PSSessionOption] $SessionOption) + [System.Management.Automation.Remoting.PSSessionOption] $SessionOption + ) + + # For PSCore6, we want to always test against a remoting endpoint running PSCore6 (not Windows PowerShell) + if ([string]::IsNullOrEmpty($ConfigurationName)) + { + $ConfigurationName = Get-DefaultEndPointName + } $parameters = CreateParameters -Name $Name -ConfigurationName $ConfigurationName -SessionOption $SessionOption -CimSession:$CimSession.IsPresent @@ -105,6 +157,8 @@ function New-RemoteSession $session = New-PSSession @parameters } + Write-Verbose "Successfully created remote PSSession on endpoint: $ConfigurationName" + return $session } @@ -114,7 +168,14 @@ function Invoke-RemoteCommand [string] $ComputerName, [scriptblock] $ScriptBlock, [string] $ConfigurationName, - [switch] $InDisconnectedSession) + [switch] $InDisconnectedSession + ) + + # For PSCore6, we want to always test against a remoting endpoint running PSCore6 (not Windows PowerShell) + if ([string]::IsNullOrEmpty($ConfigurationName)) + { + $ConfigurationName = Get-DefaultEndPointName + } $parameters = CreateParameters -ComputerName $ComputerName -ConfigurationName $ConfigurationName diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index 07685c4f0e..270e21d73f 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -91,22 +91,48 @@ function Add-UserToGroup Function Test-DailyBuild { $trueString = 'True' - if(($env:PS_DAILY_BUILD -eq $trueString) -or ($env:APPVEYOR_SCHEDULED_BUILD -eq $trueString) -or ($env:APPVEYOR_REPO_TAG_NAME)) + # PS_DAILY_BUILD says that we have previously determined that this is a daily build + # APPVEYOR_SCHEDULED_BUILD is True means that we are in an AppVeyor Scheduled build + # APPVEYOR_REPO_TAG_NAME means we are building a tag in AppVeyor + # BUILD_REASON is Schedule means we are in a VSTS Scheduled build + if(($env:PS_DAILY_BUILD -eq $trueString) -or ($env:APPVEYOR_SCHEDULED_BUILD -eq $trueString) -or ($env:APPVEYOR_REPO_TAG_NAME) -or $env:BUILD_REASON -eq 'Schedule') { return $true } # if [Feature] is in the commit message, # Run Daily tests - if($env:APPVEYOR_REPO_COMMIT_MESSAGE -match '\[feature\]') + $commitMessage = Get-CommitMessage + Write-Verbose "commitMessage: $commitMessage" -verbose + + if($commitMessage -match '\[feature\]' -or $env:FORCE_FEATURE -eq 'True') { - Set-AppveyorBuildVariable -Name PS_DAILY_BUILD -Value $trueString + Set-BuildVariable -Name PS_DAILY_BUILD -Value $trueString return $true } return $false } +# Returns the commit message for the current build +function Get-CommitMessage +{ + if ($env:APPVEYOR_REPO_COMMIT_MESSAGE) + { + return $env:APPVEYOR_REPO_COMMIT_MESSAGE + } + elseif ($env:BUILD_SOURCEVERSIONMESSAGE -match 'Merge\s*([0-9A-F]*)') + { + # We are in VSTS and have a commit ID in the Source Version Message + $commitId = $Matches[1] + return &git log --format=%B -n 1 $commitId + } + else + { + Write-Log "Unknown BUILD_SOURCEVERSIONMESSAGE format '$env:BUILD_SOURCEVERSIONMESSAGE'" -Verbose + } +} + # Sets a build variable Function Set-BuildVariable { @@ -205,28 +231,34 @@ function Invoke-AppVeyorInstall } if(Test-DailyBuild){ - $buildName = "[Daily]" + if($env:APPVEYOR) + { + $buildName = "[Daily]" - # Add daily to title if it's not already there - # It can be there already for rerun requests - if($env:APPVEYOR_PULL_REQUEST_TITLE -and $env:APPVEYOR_PULL_REQUEST_TITLE -notmatch '^\[Daily\]') - { - $buildName += $env:APPVEYOR_PULL_REQUEST_TITLE - } - elseif($env:APPVEYOR_PULL_REQUEST_TITLE) - { - $buildName = $env:APPVEYOR_PULL_REQUEST_TITLE - } - elseif($env:APPVEYOR_REPO_COMMIT_MESSAGE -notmatch '^\[Daily\].*$') - { - $buildName += $env:APPVEYOR_REPO_COMMIT_MESSAGE - } - else - { - $buildName = $env:APPVEYOR_REPO_COMMIT_MESSAGE - } + # Add daily to title if it's not already there + # It can be there already for rerun requests + if($env:APPVEYOR_PULL_REQUEST_TITLE -and $env:APPVEYOR_PULL_REQUEST_TITLE -notmatch '^\[Daily\]') + { + $buildName += $env:APPVEYOR_PULL_REQUEST_TITLE + } + elseif($env:APPVEYOR_PULL_REQUEST_TITLE) + { + $buildName = $env:APPVEYOR_PULL_REQUEST_TITLE + } + elseif($env:APPVEYOR_REPO_COMMIT_MESSAGE -notmatch '^\[Daily\].*$') + { + $buildName += $env:APPVEYOR_REPO_COMMIT_MESSAGE + } + else + { + $buildName = $env:APPVEYOR_REPO_COMMIT_MESSAGE + } - Update-AppveyorBuild -message $buildName + Update-AppveyorBuild -message $buildName + } + elseif ($env:BUILD_REASON -eq 'Schedule') { + Write-Host "##vso[build.updatebuildnumber]Daily-$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhss"))" + } } if ($env:APPVEYOR -or $env:TF_BUILD) @@ -467,13 +499,28 @@ function Invoke-AppVeyorAfterTest $codeCoverageArtifacts = Compress-CoverageArtifacts -CodeCoverageOutput $codeCoverageOutput Write-Host -ForegroundColor Green 'Upload CodeCoverage artifacts' - $codeCoverageArtifacts | ForEach-Object { Push-AppveyorArtifact $_ } + $codeCoverageArtifacts | ForEach-Object { + Push-Artifact -Path $_ + } + } +} - New-TestPackage -Destination $pwd - $testPackageFullName = Join-Path $pwd 'TestPackage.zip' - Write-Verbose "Created TestPackage.zip" -Verbose - Write-Host -ForegroundColor Green -'Upload test package' - Push-AppveyorArtifact $testPackageFullName +# Wrapper to push artifact +function Push-Artifact +{ + param( + [Parameter(Mandatory)] + [ValidateScript({Test-Path -Path $_})] + $Path + ) + + if($env:Appveyor) + { + Push-AppveyorArtifact $Path + } + elseif ($env:TF_BUILD -and $env:BUILD_REASON -ne 'PullRequest') { + # In VSTS + Write-Host "##vso[artifact.upload containerfolder=artifacts;artifactname=artifacts;]$Path" } } @@ -511,7 +558,13 @@ function Get-ReleaseTag if($env:APPVEYOR_BUILD_NUMBER) { $releaseTag = $releaseTag.split('.')[0..2] -join '.' - $releaseTag = $releaseTag+'.'+$env:APPVEYOR_BUILD_NUMBER + $releaseTag = $releaseTag + '.' + $env:APPVEYOR_BUILD_NUMBER + } + elseif($env:BUILD_BUILID) + { + #In VSTS + $releaseTag = $releaseTag.split('.')[0..2] -join '.' + $releaseTag = $releaseTag + '.' + $env:BUILD_BUILID } return $releaseTag @@ -557,7 +610,14 @@ function Invoke-AppveyorFinish $previewLabel= "daily{0}" -f $previewLabel } - $preReleaseVersion = "$previewPrefix-$previewLabel.$env:APPVEYOR_BUILD_NUMBER" + if ($env:TF_BUILD) + { + $preReleaseVersion = "$previewPrefix-$previewLabel.$env:BUILD_BUILDID" + } + else + { + $preReleaseVersion = "$previewPrefix-$previewLabel.$env:APPVEYOR_BUILD_NUMBER" + } } # the packaging tests find the MSI package using env:PSMsiX64Path @@ -604,14 +664,7 @@ function Invoke-AppveyorFinish Write-Host "Pushing $_ as Appveyor artifact" if(Test-Path $_) { - if($env:Appveyor) - { - Push-AppveyorArtifact $_ - } - elseif ($env:TF_BUILD -and $env:BUILD_REASON -ne 'PullRequest') { - # In VSTS - Write-Host "##vso[artifact.upload containerfolder=artifacts;artifactname=artifacts;]$_" - } + Push-Artifact -Path $_ } else {