From 6b994dbb2d9100fa790fc2ef88b8ac21387f39d8 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Mon, 29 Aug 2016 13:12:01 -0700 Subject: [PATCH 1/5] Move the PowerShell code in appVeyor.yml to a module --- appveyor.yml | 116 ++----------------------------- tools/appveyor.psm1 | 161 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 111 deletions(-) create mode 100644 tools/appveyor.psm1 diff --git a/appveyor.yml b/appveyor.yml index 4738e844d..38a0403ce 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,120 +9,14 @@ nuget: install: - git submodule update --init - ps: $buildConfiguration = 'Release' - - ps: Import-Module .\build.psm1; Start-PSBootstrap -Force + - ps: Import-Module .\tools\Appveyor.psm1 + - ps: Invoke-AppveyorInstall build_script: - - ps: | - $ErrorActionPreference = 'Stop' - # check to be sure our test tags are correct - $result = Get-PesterTag - if ( $result.Result -ne "Pass" ) { - $result.Warnings - throw "Tags must be CI, Feature, Scenario, or Slow" - } - Start-PSBuild -CrossGen -Configuration $buildConfiguration - Start-PSBuild -FullCLR + - ps: Invoke-AppveyorBuild test_script: - - ps: | - # fail tests execution, if any PS error detected - $ErrorActionPreference = 'Stop' - # - # CoreCLR - $env:CoreOutput = Split-Path -Parent (Get-PSOutput -Options (New-PSOptions -Publish -Configuration $buildConfiguration)) - Write-Host -Foreground Green 'Run CoreCLR tests' - $testResultsFile = "$pwd\TestsResults.xml" - if(!(Test-Path "$env:CoreOutput\powershell.exe")) - { - throw "CoreCL PowerShell.exe was not built" - } - & ("$env:CoreOutput\powershell.exe") -noprofile -noninteractive -c "Set-ExecutionPolicy -Scope Process Unrestricted; Invoke-Pester test/powershell -Tag 'CI' -ExcludeTag 'Slow' -OutputFormat NUnitXml -OutputFile $testResultsFile" - - (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) - # - # FullCLR - $env:FullOutput = Split-Path -Parent (Get-PSOutput -Options (New-PSOptions -FullCLR)) - Write-Host -Foreground Green 'Run FullCLR tests' - $testResultsFileFullCLR = "$pwd\TestsResults.FullCLR.xml" - Start-DevPowerShell -FullCLR -NoNewWindow -ArgumentList '-noprofile', '-noninteractive' -Command "Set-ExecutionPolicy -Scope Process Unrestricted; Invoke-Pester test/fullCLR -ExcludeTag 'Slow' -OutputFormat NUnitXml -OutputFile $testResultsFileFullCLR" - (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFileFullCLR)) - # - # Fail the build, if tests failed - Write-Host -Foreground Green 'Upload CoreCLR test results' - $x = [xml](cat -raw $testResultsFile) - if ([int]$x.'test-results'.failures -gt 0) - { - throw "$($x.'test-results'.failures) tests in test/powershell failed" - } - Write-Host -Foreground Green 'Upload FullCLR test results' - $x = [xml](cat -raw $testResultsFileFullCLR) - if ([int]$x.'test-results'.failures -gt 0) - { - throw "$($x.'test-results'.failures) tests in test/fullCLR failed" - } + - ps: Invoke-AppveyorTest on_finish: - - ps: | - $ErrorActionPreference = 'Stop' - try { - # Build packages - $packages = Start-PSPackage - - # Creating project artifact - $name = git describe - - # Remove 'v' from version, append 'PowerShell' - to be consistent with other package names - $name = $name -replace 'v','' - $name = 'PowerShell_' + $name - - $zipFilePath = Join-Path $pwd "$name.zip" - $zipFileFullPath = Join-Path $pwd "$name.FullCLR.zip" - Add-Type -assemblyname System.IO.Compression.FileSystem - Write-Verbose "Zipping ${env:CoreOutput} into $zipFilePath" -verbose - [System.IO.Compression.ZipFile]::CreateFromDirectory($env:CoreOutput, $zipFilePath) - Write-Verbose "Zipping ${env:FullOutput} into $zipFileFullPath" -verbose - [System.IO.Compression.ZipFile]::CreateFromDirectory($env:FullOutput, $zipFileFullPath) - - $artifacts = New-Object System.Collections.ArrayList - foreach ($package in $packages) { - $artifacts.Add($package) - } - - $artifacts.Add($zipFilePath) - $artifacts.Add($zipFileFullPath) - - if ($env:APPVEYOR_REPO_TAG_NAME) - { - # ignore the first part of semver, use the preview part - $preReleaseVersion = ($env:APPVEYOR_REPO_TAG_NAME).Split('-')[1] - } - else - { - $previewLabel = (git describe --abbrev=0).Split('-')[1] - $preReleaseVersion = "$previewLabel.$($env:APPVEYOR_BUILD_NUMBER)" - } - - Publish-NuGetFeed -OutputPath .\nuget-artifacts -VersionSuffix $preReleaseVersion - - $artifacts += (ls .\nuget-artifacts | % {$_.FullName}) - - $pushedAllArtifacts = $true - $artifacts | % { - Write-Host "Pushing $_ as Appveyor artifact" - if(Test-Path $_) - { - Push-AppveyorArtifact $_ - } - else - { - $pushedAllArtifacts = $false - Write-Warning "Artifact $_ does not exist." - } - } - if(!$pushedAllArtifacts) - { - throw "Some artifacts did not exist!" - } - } catch { - Write-Host -Foreground Red $_ - } + - ps: Invoke-AppveyorFinish diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 new file mode 100644 index 000000000..02d6c219e --- /dev/null +++ b/tools/appveyor.psm1 @@ -0,0 +1,161 @@ +$ErrorActionPreference = 'Stop' +$repoRoot = Join-Path $PSScriptRoot '..' + +Import-Module (Join-Path $repoRoot 'build.psm1') + +function Invoke-AppVeyorFull +{ + Invoke-AppVeyorInstall + Invoke-AppVeyorBuild + Invoke-AppVeyorTest + Invoke-AppveyorFinish +} + +function Invoke-AppVeyorBuild +{ + # check to be sure our test tags are correct + $result = Get-PesterTag + if ( $result.Result -ne "Pass" ) { + $result.Warnings + throw "Tags must be CI, Feature, Scenario, or Slow" + } + Start-PSBuild -CrossGen -Configuration $buildConfiguration + Start-PSBuild -FullCLR +} + +function Invoke-AppVeyorInstall +{ + Start-PSBootstrap -Force +} + +function Update-AppVeyorTestResults +{ + param( + [string] $resultsFile + ) + + if($env:Appveyor) + { + $resolvedResultsPath = (Resolve-Path $resultsFile) + (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $resolvedResultsPath) + } + else + { + Write-Warning "Not running in appveyor, skipping upload of test results: $resultsFile" + } +} + +function Invoke-AppVeyorTest +{ + # + # CoreCLR + $env:CoreOutput = Split-Path -Parent (Get-PSOutput -Options (New-PSOptions -Publish -Configuration $buildConfiguration)) + Write-Host -Foreground Green 'Run CoreCLR tests' + $testResultsFile = "$pwd\TestsResults.xml" + if(!(Test-Path "$env:CoreOutput\powershell.exe")) + { + throw "CoreCL PowerShell.exe was not built" + } + + & ("$env:CoreOutput\powershell.exe") -noprofile -noninteractive -c "Set-ExecutionPolicy -Scope Process Unrestricted; Invoke-Pester test/powershell -Tag 'CI' -ExcludeTag 'Slow' -OutputFormat NUnitXml -OutputFile $testResultsFile" + Update-AppVeyorTestResults -resultsFile $testResultsFile + + # + # FullCLR + $env:FullOutput = Split-Path -Parent (Get-PSOutput -Options (New-PSOptions -FullCLR)) + Write-Host -Foreground Green 'Run FullCLR tests' + $testResultsFileFullCLR = "$pwd\TestsResults.FullCLR.xml" + Start-DevPowerShell -FullCLR -NoNewWindow -ArgumentList '-noprofile', '-noninteractive' -Command "Set-ExecutionPolicy -Scope Process Unrestricted; Invoke-Pester test/fullCLR -ExcludeTag 'Slow' -OutputFormat NUnitXml -OutputFile $testResultsFileFullCLR" + Update-AppVeyorTestResults -resultsFile $testResultsFileFullCLR + + + # + # Fail the build, if tests failed + Write-Host -Foreground Green 'Upload CoreCLR test results' + $x = [xml](cat -raw $testResultsFile) + if ([int]$x.'test-results'.failures -gt 0) + { + throw "$($x.'test-results'.failures) tests in test/powershell failed" + } + + Write-Host -Foreground Green 'Upload FullCLR test results' + $x = [xml](cat -raw $testResultsFileFullCLR) + + if ([int]$x.'test-results'.failures -gt 0) + { + throw "$($x.'test-results'.failures) tests in test/fullCLR failed" + } +} + +function Invoke-AppveyorFinish +{ + try { + # Build packages + $packages = Start-PSPackage + + # Creating project artifact + $name = git describe + + # Remove 'v' from version, append 'PowerShell' - to be consistent with other package names + $name = $name -replace 'v','' + $name = 'PowerShell_' + $name + + $zipFilePath = Join-Path $pwd "$name.zip" + $zipFileFullPath = Join-Path $pwd "$name.FullCLR.zip" + Add-Type -assemblyname System.IO.Compression.FileSystem + Write-Verbose "Zipping ${env:CoreOutput} into $zipFilePath" -verbose + [System.IO.Compression.ZipFile]::CreateFromDirectory($env:CoreOutput, $zipFilePath) + Write-Verbose "Zipping ${env:FullOutput} into $zipFileFullPath" -verbose + [System.IO.Compression.ZipFile]::CreateFromDirectory($env:FullOutput, $zipFileFullPath) + + $artifacts = New-Object System.Collections.ArrayList + foreach ($package in $packages) { + $artifacts.Add($package) + } + + $artifacts.Add($zipFilePath) + $artifacts.Add($zipFileFullPath) + + if ($env:APPVEYOR_REPO_TAG_NAME) + { + # ignore the first part of semver, use the preview part + $preReleaseVersion = ($env:APPVEYOR_REPO_TAG_NAME).Split('-')[1] + } + else + { + $previewLabel = (git describe --abbrev=0).Split('-')[1] + $preReleaseVersion = "$previewLabel.$($env:APPVEYOR_BUILD_NUMBER)" + } + + # only publish to nuget feed if it is not a pull request + if(!$env:APPVEYOR_PULL_REQUEST_NUMBER) + { + Publish-NuGetFeed -OutputPath .\nuget-artifacts -VersionSuffix $preReleaseVersion + } + + $artifacts += (ls .\nuget-artifacts | % {$_.FullName}) + + $pushedAllArtifacts = $true + $artifacts | % { + Write-Host "Pushing $_ as Appveyor artifact" + if(Test-Path $_) + { + if($env:Appveyor) + { + Push-AppveyorArtifact $_ + } + } + else + { + $pushedAllArtifacts = $false + Write-Warning "Artifact $_ does not exist." + } + } + if(!$pushedAllArtifacts) + { + throw "Some artifacts did not exist!" + } + } catch { + Write-Host -Foreground Red $_ + } +} \ No newline at end of file From 89b3970cfa0d306416e63899e11a5d2aa66ad35a Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Mon, 29 Aug 2016 13:36:45 -0700 Subject: [PATCH 2/5] Added image requirement to appveyor.yml to make it easier to run on your own appveyor instance --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 38a0403ce..35a696758 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,7 @@ version: 6.0.0-alpha.9-{build} +image: Visual Studio 2015 + cache: - '%LocalAppData%\Microsoft\dotnet' From f8520e06b3ccc9e58f18a9645d992cf0685413c5 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Mon, 29 Aug 2016 13:57:20 -0700 Subject: [PATCH 3/5] Handle error and retry test results push. --- tools/appveyor.psm1 | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index 02d6c219e..a2593c164 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -36,8 +36,39 @@ function Update-AppVeyorTestResults if($env:Appveyor) { - $resolvedResultsPath = (Resolve-Path $resultsFile) - (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $resolvedResultsPath) + $retryCount = 0 + $pushedResults = $false + $pushedArtifacts = $false + while( (!$pushedResults -or !$pushedResults) -and $retryCount -lt 3) + { + if($retryCount -gt 0) + { + Write-Verbose "Retrying updating test artifacts..." + } + + $retryCount++ + $resolvedResultsPath = (Resolve-Path $resultsFile) + try { + (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $resolvedResultsPath) + $pushedResults = $true + } + catch { + Write-Warning "Pushing test result failed..." + } + + try { + Push-AppveyorArtifact $resolvedResultsPath + $pushedArtifacts = $true + } + catch { + Write-Warning "Pushing test Artifact failed..." + } + } + + if(!$pushedResults -or !$pushedResults) + { + Write-Warning "Failed to push all artifacts for $resultsFile" + } } else { From 67ef752efb5f12097d16b096f10b934f72f6f7da Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Mon, 29 Aug 2016 14:21:48 -0700 Subject: [PATCH 4/5] Add description of the functions in appveyor.psm1 --- tools/appveyor.psm1 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index a2593c164..20d22d74e 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -3,6 +3,8 @@ $repoRoot = Join-Path $PSScriptRoot '..' Import-Module (Join-Path $repoRoot 'build.psm1') +# Emulates running all of AppVeyor but locally +# should not be used on AppVeyor function Invoke-AppVeyorFull { Invoke-AppVeyorInstall @@ -11,6 +13,7 @@ function Invoke-AppVeyorFull Invoke-AppveyorFinish } +# Implements the AppVeyor 'build_script' step function Invoke-AppVeyorBuild { # check to be sure our test tags are correct @@ -23,11 +26,15 @@ function Invoke-AppVeyorBuild Start-PSBuild -FullCLR } +# Implements the AppVeyor 'install' step function Invoke-AppVeyorInstall { Start-PSBootstrap -Force } +# A wrapper to ensure that we upload test results +# and that if we are not able to that it does not fail +# the CI build function Update-AppVeyorTestResults { param( @@ -64,7 +71,7 @@ function Update-AppVeyorTestResults Write-Warning "Pushing test Artifact failed..." } } - + if(!$pushedResults -or !$pushedResults) { Write-Warning "Failed to push all artifacts for $resultsFile" @@ -76,6 +83,7 @@ function Update-AppVeyorTestResults } } +# Implement AppVeyor 'Test_script' function Invoke-AppVeyorTest { # @@ -118,6 +126,7 @@ function Invoke-AppVeyorTest } } +# Implements AppVeyor 'on_finish' step function Invoke-AppveyorFinish { try { From b7c373280cd4f5f1555514d4080c090bcb042450 Mon Sep 17 00:00:00 2001 From: Travis Plunk Date: Mon, 29 Aug 2016 14:52:50 -0700 Subject: [PATCH 5/5] Fix issues identified in Pull Request comments --- tools/appveyor.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 index 20d22d74e..aab7fa561 100644 --- a/tools/appveyor.psm1 +++ b/tools/appveyor.psm1 @@ -93,7 +93,7 @@ function Invoke-AppVeyorTest $testResultsFile = "$pwd\TestsResults.xml" if(!(Test-Path "$env:CoreOutput\powershell.exe")) { - throw "CoreCL PowerShell.exe was not built" + throw "CoreCLR PowerShell.exe was not built" } & ("$env:CoreOutput\powershell.exe") -noprofile -noninteractive -c "Set-ExecutionPolicy -Scope Process Unrestricted; Invoke-Pester test/powershell -Tag 'CI' -ExcludeTag 'Slow' -OutputFormat NUnitXml -OutputFile $testResultsFile" @@ -114,7 +114,7 @@ function Invoke-AppVeyorTest $x = [xml](cat -raw $testResultsFile) if ([int]$x.'test-results'.failures -gt 0) { - throw "$($x.'test-results'.failures) tests in test/powershell failed" + throw "$($x.'test-results'.failures) tests in test/powershell failed" } Write-Host -Foreground Green 'Upload FullCLR test results'