Skip to content

Add PowerShell Core Build+Test to Appveyor CI #939

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Mar 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7fd4fb9
test using pwsh
bergmeister Mar 17, 2018
4a32c11
fix yaml syntax
bergmeister Mar 17, 2018
f56bb83
install platyps on pwsh
bergmeister Mar 17, 2018
bd484a6
appveyor still uses pwsh 6.0.0
bergmeister Mar 17, 2018
a8cea13
fix 1 test for pwsh. 1 remaining
bergmeister Mar 17, 2018
8c6dafa
make test pending that is failing on pwsh on Windows as well.
bergmeister Mar 17, 2018
d5af4a1
re-fix test for pwsh
bergmeister Mar 17, 2018
4d43669
really fix test and simplify
bergmeister Mar 17, 2018
49617f4
tweak and optimize appveyor.yml
bergmeister Mar 17, 2018
71b898d
extract appveyor steps into ps module to eliminate code duplication
bergmeister Mar 17, 2018
7fd574b
fix and simplify test script
bergmeister Mar 17, 2018
92de2ca
fix path problem and put appveyor finish into module as well
bergmeister Mar 17, 2018
796189d
pwsh sessions are not being persisted on appveyor. Fix module deploym…
bergmeister Mar 17, 2018
d14edfe
remove wmf4 image temporarily to run it on the fork again
bergmeister Mar 17, 2018
20025cb
revert test script to non-module version because some tests failed
bergmeister Mar 17, 2018
5f62577
try fix yaml syntax
bergmeister Mar 17, 2018
f880cf9
use consistent space and try $ErrorActionPreference = 'Stop' in appve…
bergmeister Mar 17, 2018
db72dcb
fix appveyorfinish for pwsh and give test-appveyor function a last try
bergmeister Mar 17, 2018
d285e45
take out invoke-appveyortest method since it does not work in the app…
bergmeister Mar 17, 2018
557091f
add wmf4 image as it is ready for PW now.
bergmeister Mar 17, 2018
ef57ef3
install platyps in a wmf4 friendly way
bergmeister Mar 17, 2018
d5c2104
let's try if we can remove the hard coded checkout path (fingers cros…
bergmeister Mar 17, 2018
71facf8
let's try if we can rename the PowerShellEdition to something more me…
bergmeister Mar 17, 2018
34553e0
Set DOTNET_SKIP_FIRST_TIME_EXPERIENCE to 1 to speed-up WMF4 builds, w…
bergmeister Mar 17, 2018
53493c9
make indentation consistent after rename
bergmeister Mar 17, 2018
b535971
remove setting PATH for psmodulepath in yaml (not needed for VS 2017 …
bergmeister Mar 18, 2018
ae18e5d
use OS agnostic file separator and fix case sensitivity as a preparat…
bergmeister Mar 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions Tests/Engine/InvokeScriptAnalyzer.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -523,18 +523,35 @@ Describe "Test -Fix Switch" {

Describe "Test -EnableExit Switch" {
It "Returns exit code equivalent to number of warnings" {
powershell -Command 'Import-Module PSScriptAnalyzer; Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit'
if ($IsCoreCLR) {
pwsh -command 'Import-Module PSScriptAnalyzer; Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit'
}
else {
powershell -command 'Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit'
}
$LASTEXITCODE | Should -Be 1
}

Describe "-ReportSummary switch" {
$reportSummaryFor1Warning = '*1 rule violation found. Severity distribution: Error = 0, Warning = 1, Information = 0*'
It "prints the correct report summary using the -NoReportSummary switch" {
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci -ReportSummary'
if ($IsCoreCLR) {
$result = pwsh -command 'Import-Module PSScriptAnalyzer; Invoke-Scriptanalyzer -ScriptDefinition gci -ReportSummary'
}
else {
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci -ReportSummary'
}

"$result" | Should -BeLike $reportSummaryFor1Warning
}
It "does not print the report summary when not using -NoReportSummary switch" {
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci'
if ($IsCoreCLR) {
$result = pwsh -command 'Import-Module PSScriptAnalyzer; Invoke-Scriptanalyzer -ScriptDefinition gci'
}
else {
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci'
}

"$result" | Should -Not -BeLike $reportSummaryFor1Warning
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/Rules/UseToExportFieldsInManifest.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Describe "UseManifestExportFields" {
$results[0].Extent.Text | Should -Be "'*'"
}

It "suggests corrections for AliasesToExport with wildcard" -pending:($IsLinux -or $IsMacOS) {
It "suggests corrections for AliasesToExport with wildcard" -pending:($IsCoreClr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this tracked by an issue?

Copy link
Collaborator Author

@bergmeister bergmeister Mar 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No but Pester shows the number of pending tests. We should maybe create an issue specific for the non-Windows builds and fix/investigate it as part of making the non-Windows builds?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created an issue here

$violations = Run-PSScriptAnalyzerRule $testManifestBadAliasesWildcardPath
$violationFilepath = Join-path $testManifestPath $testManifestBadAliasesWildcardPath
Test-CorrectionExtent $violationFilepath $violations[0] 1 "'*'" "@('gbar', 'gfoo')"
Expand Down
116 changes: 44 additions & 72 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,91 +1,63 @@
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
PowerShellEdition: Desktop
PowerShellEdition: PowerShellCore
BuildConfiguration: Release
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
PowerShellEdition: WindowsPowerShell
BuildConfiguration: Release
- APPVEYOR_BUILD_WORKER_IMAGE: WMF 4
PowerShellEdition: Desktop
PowerShellEdition: WindowsPowerShell
BuildConfiguration: PSv3Release

# clone directory
clone_folder: c:\projects\psscriptanalyzer

# cache Nuget packages and dotnet CLI cache
cache:
- '%USERPROFILE%\.nuget\packages -> appveyor.yml'
- '%LocalAppData%\Microsoft\dotnet -> appveyor.yml'

# Install Pester
install:
- ps: nuget install platyPS -Version 0.9.0 -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
- ps: |
$requiredPesterVersion = '4.3.1'
$pester = Get-Module Pester -ListAvailable | Where-Object { $_.Version -eq $requiredPesterVersion }
$pester
if ($null -eq $pester)
{
if ($null -eq (Get-Module -ListAvailable PowershellGet))
{
# WMF 4 image build
nuget install Pester -Version $requiredPesterVersion -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
}
else
{
# Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4)
Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser
}
}
- ps: |
# the legacy WMF4 image only has the old preview SDKs of dotnet
$globalDotJson = Get-Content .\global.json -Raw | ConvertFrom-Json
$dotNetCoreSDKVersion = $globalDotJson.sdk.version
if (-not ((dotnet --version).StartsWith($dotNetCoreSDKVersion)))
{
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1
.\dotnet-install.ps1 -Version $dotNetCoreSDKVersion
}
- ps: Import-Module .\tools\appveyor.psm1
- ps: if ($env:PowerShellEdition -eq 'WindowsPowerShell') { Invoke-AppveyorInstall }
- pwsh: if ($env:PowerShellEdition -eq 'PowerShellCore') { Import-Module .\tools\appveyor.psm1; Invoke-AppveyorInstall }

build_script:
- ps: |
$PSVersionTable
Write-Verbose "Pester version: $((Get-Command Invoke-Pester).Version)" -Verbose
Write-Verbose ".NET SDK version: $(dotnet --version)" -Verbose
Push-Location C:\projects\psscriptanalyzer
# Test build using netstandard to test whether APIs are being called that are not available in .Net Core. Remove output afterwards.
.\buildCoreClr.ps1 -Framework netstandard1.6 -Configuration Release -Build
git clean -dfx
C:\projects\psscriptanalyzer\buildCoreClr.ps1 -Framework net451 -Configuration $env:BuildConfiguration -Build
C:\projects\psscriptanalyzer\build.ps1 -BuildDocs
Pop-Location

# branches to build
branches:
# whitelist
only:
- master
- development
- ps: |
if ($env:PowerShellEdition -eq 'WindowsPowerShell') {
Invoke-AppveyorBuild -CheckoutPath $env:APPVEYOR_BUILD_FOLDER -BuildConfiguration $env:BuildConfiguration -BuildType 'FullCLR'
}
- pwsh: |
if ($env:PowerShellEdition -eq 'PowerShellCore') {
Import-Module .\tools\appveyor.psm1 # Appveyor does not persist pwsh sessions like it does for ps
Invoke-AppveyorBuild -CheckoutPath $env:APPVEYOR_BUILD_FOLDER -BuildConfiguration $env:BuildConfiguration -BuildType 'NetStandard'
}

# Run Pester tests and store the results
# Test scripts are not in a module function because the tests behave differently for unknown reasons in AppVeyor
test_script:
- SET PATH=c:\Program Files\WindowsPowerShell\Modules\;%PATH%;
- ps: |
copy-item "C:\projects\psscriptanalyzer\out\PSScriptAnalyzer" "$Env:ProgramFiles\WindowsPowerShell\Modules\" -Recurse -Force
$testResultsFile = ".\TestResults.xml"
$testScripts = "C:\projects\psscriptanalyzer\Tests\Engine","C:\projects\psscriptanalyzer\Tests\Rules"
$testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile))
if ($testResults.FailedCount -gt 0) {
throw "$($testResults.FailedCount) tests failed."
}
- ps: |
if ($env:PowerShellEdition -eq 'WindowsPowerShell') {
$modulePath = $env:PSModulePath.Split([System.IO.Path]::PathSeparator) | Where-Object { Test-Path $_} | Select-Object -First 1
Copy-Item "${env:APPVEYOR_BUILD_FOLDER}\out\PSScriptAnalyzer" "$modulePath\" -Recurse -Force
$testResultsFile = ".\TestResults.xml"
$testScripts = "${env:APPVEYOR_BUILD_FOLDER}\Tests\Engine","${env:APPVEYOR_BUILD_FOLDER}\Tests\Rules"
$testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/${env:APPVEYOR_JOB_ID}", (Resolve-Path $testResultsFile))
if ($testResults.FailedCount -gt 0) {
throw "$($testResults.FailedCount) tests failed."
}
}
- pwsh: |
if ($env:PowerShellEdition -eq 'PowerShellCore') {
$modulePath = $env:PSModulePath.Split(';') | Where-Object { Test-Path $_} | Select-Object -First 1
Copy-Item "${env:APPVEYOR_BUILD_FOLDER}\out\PSScriptAnalyzer" "$modulePath\" -Recurse -Force
$testResultsFile = ".\TestResults.xml"
$testScripts = "${env:APPVEYOR_BUILD_FOLDER}\Tests\Engine","${env:APPVEYOR_BUILD_FOLDER}\Tests\Rules"
$testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/${env:APPVEYOR_JOB_ID}", (Resolve-Path $testResultsFile))
if ($testResults.FailedCount -gt 0) {
throw "$($testResults.FailedCount) tests failed."
}
}

# Upload the project along with TestResults as a zip archive
# Upload the project along with test results as a zip archive
on_finish:
- ps: |
$stagingDirectory = (Resolve-Path ..).Path
$zipFile = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip"
Add-Type -assemblyname System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($pwd, $zipFile)
@(
# You can add other artifacts here
(ls $zipFile)
) | % { Push-AppveyorArtifact $_.FullName }
- ps: Invoke-AppveyorFinish
80 changes: 80 additions & 0 deletions tools/appveyor.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

$ErrorActionPreference = 'Stop'

# Implements the AppVeyor 'install' step and installs the required versions of Pester, platyPS and the .Net Core SDK if needed.
function Invoke-AppVeyorInstall {
$requiredPesterVersion = '4.3.1'
$pester = Get-Module Pester -ListAvailable | Where-Object { $_.Version -eq $requiredPesterVersion }
if ($null -eq $pester) {
if ($null -eq (Get-Module -ListAvailable PowershellGet)) {
# WMF 4 image build
nuget install Pester -Version $requiredPesterVersion -source https://www.powershellgallery.com/api/v2 -outputDirectory "$env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
}
else {
# Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4)
Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser
}
}

if ($null -eq (Get-Module -ListAvailable PowershellGet)) {
# WMF 4 image build
nuget install platyPS -Version 0.9.0 -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
}
else {
Install-Module -Name platyPS -Force -Scope CurrentUser -RequiredVersion '0.9.0'
}

# the legacy WMF4 image only has the old preview SDKs of dotnet
$globalDotJson = Get-Content (Join-Path $PSScriptRoot '..\global.json') -Raw | ConvertFrom-Json
$dotNetCoreSDKVersion = $globalDotJson.sdk.version
if (-not ((dotnet --version).StartsWith($dotNetCoreSDKVersion))) {
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1
.\dotnet-install.ps1 -Version $dotNetCoreSDKVersion
Remove-Item .\dotnet-install.ps1
}
}

# Implements the AppVeyor 'build_script' step
function Invoke-AppVeyorBuild {
Param(
[Parameter(Mandatory)]
[ValidateSet('FullCLR', 'NetStandard')]
$BuildType,

[Parameter(Mandatory)]
[ValidateSet('Release', 'PSv3Release')]
$BuildConfiguration,

[Parameter(Mandatory)]
[ValidateScript( {Test-Path $_})]
$CheckoutPath
)

$PSVersionTable
Write-Verbose "Pester version: $((Get-Command Invoke-Pester).Version)" -Verbose
Write-Verbose ".NET SDK version: $(dotnet --version)" -Verbose
Push-Location $CheckoutPath
[Environment]::SetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", 1) # avoid unneccessary initialization in CI
if ($BuildType -eq 'FullCLR') {
.\buildCoreClr.ps1 -Framework net451 -Configuration $BuildConfiguration -Build
}
elseif ($BuildType -eq 'NetStandard') {
.\buildCoreClr.ps1 -Framework netstandard1.6 -Configuration Release -Build
}
.\build.ps1 -BuildDocs
Pop-Location
}

# Implements AppVeyor 'on_finish' step
function Invoke-AppveyorFinish {
$stagingDirectory = (Resolve-Path ..).Path
$zipFile = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip"
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'
[System.IO.Compression.ZipFile]::CreateFromDirectory($pwd, $zipFile)
@(
# You can add other artifacts here
(Get-ChildItem $zipFile)
) | ForEach-Object { Push-AppveyorArtifact $_.FullName }
}