Skip to content

Commit 021711e

Browse files
bergmeisterJamesWTruher
authored andcommitted
Add PowerShell Core Build+Test to Appveyor CI (#939)
* test using pwsh * fix yaml syntax * install platyps on pwsh * appveyor still uses pwsh 6.0.0 * fix 1 test for pwsh. 1 remaining * make test pending that is failing on pwsh on Windows as well. * re-fix test for pwsh * really fix test and simplify * tweak and optimize appveyor.yml * extract appveyor steps into ps module to eliminate code duplication * fix and simplify test script * fix path problem and put appveyor finish into module as well * pwsh sessions are not being persisted on appveyor. Fix module deployment as well * remove wmf4 image temporarily to run it on the fork again * revert test script to non-module version because some tests failed * try fix yaml syntax * use consistent space and try $ErrorActionPreference = 'Stop' in appveyor module * fix appveyorfinish for pwsh and give test-appveyor function a last try * take out invoke-appveyortest method since it does not work in the appveyor environment * add wmf4 image as it is ready for PW now. * install platyps in a wmf4 friendly way * let's try if we can remove the hard coded checkout path (fingers crossed this works in WMF as well) * let's try if we can rename the PowerShellEdition to something more meaningful (again fingers crossed for the WMF 4 build) * Set DOTNET_SKIP_FIRST_TIME_EXPERIENCE to 1 to speed-up WMF4 builds, which have to install the .net sdk from scratch * make indentation consistent after rename * remove setting PATH for psmodulepath in yaml (not needed for VS 2017 image, let's hope it works for WMF 4 as well) * use OS agnostic file separator and fix case sensitivity as a preparation for a Linux build+test (which already works when adding additional Import-Module calls but has 13 failing tests)
1 parent d6dc001 commit 021711e

File tree

4 files changed

+145
-76
lines changed

4 files changed

+145
-76
lines changed

Tests/Engine/InvokeScriptAnalyzer.tests.ps1

+20-3
Original file line numberDiff line numberDiff line change
@@ -523,18 +523,35 @@ Describe "Test -Fix Switch" {
523523

524524
Describe "Test -EnableExit Switch" {
525525
It "Returns exit code equivalent to number of warnings" {
526-
powershell -Command 'Import-Module PSScriptAnalyzer; Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit'
526+
if ($IsCoreCLR) {
527+
pwsh -command 'Import-Module PSScriptAnalyzer; Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit'
528+
}
529+
else {
530+
powershell -command 'Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit'
531+
}
527532
$LASTEXITCODE | Should -Be 1
528533
}
529534

530535
Describe "-ReportSummary switch" {
531536
$reportSummaryFor1Warning = '*1 rule violation found. Severity distribution: Error = 0, Warning = 1, Information = 0*'
532537
It "prints the correct report summary using the -NoReportSummary switch" {
533-
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci -ReportSummary'
538+
if ($IsCoreCLR) {
539+
$result = pwsh -command 'Import-Module PSScriptAnalyzer; Invoke-Scriptanalyzer -ScriptDefinition gci -ReportSummary'
540+
}
541+
else {
542+
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci -ReportSummary'
543+
}
544+
534545
"$result" | Should -BeLike $reportSummaryFor1Warning
535546
}
536547
It "does not print the report summary when not using -NoReportSummary switch" {
537-
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci'
548+
if ($IsCoreCLR) {
549+
$result = pwsh -command 'Import-Module PSScriptAnalyzer; Invoke-Scriptanalyzer -ScriptDefinition gci'
550+
}
551+
else {
552+
$result = powershell -command 'Invoke-Scriptanalyzer -ScriptDefinition gci'
553+
}
554+
538555
"$result" | Should -Not -BeLike $reportSummaryFor1Warning
539556
}
540557
}

Tests/Rules/UseToExportFieldsInManifest.tests.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Describe "UseManifestExportFields" {
8383
$results[0].Extent.Text | Should -Be "'*'"
8484
}
8585

86-
It "suggests corrections for AliasesToExport with wildcard" -pending:($IsLinux -or $IsMacOS) {
86+
It "suggests corrections for AliasesToExport with wildcard" -pending:($IsCoreClr) {
8787
$violations = Run-PSScriptAnalyzerRule $testManifestBadAliasesWildcardPath
8888
$violationFilepath = Join-path $testManifestPath $testManifestBadAliasesWildcardPath
8989
Test-CorrectionExtent $violationFilepath $violations[0] 1 "'*'" "@('gbar', 'gfoo')"

appveyor.yml

+44-72
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,63 @@
11
environment:
22
matrix:
33
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
4-
PowerShellEdition: Desktop
4+
PowerShellEdition: PowerShellCore
5+
BuildConfiguration: Release
6+
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
7+
PowerShellEdition: WindowsPowerShell
58
BuildConfiguration: Release
69
- APPVEYOR_BUILD_WORKER_IMAGE: WMF 4
7-
PowerShellEdition: Desktop
10+
PowerShellEdition: WindowsPowerShell
811
BuildConfiguration: PSv3Release
912

10-
# clone directory
11-
clone_folder: c:\projects\psscriptanalyzer
12-
1313
# cache Nuget packages and dotnet CLI cache
1414
cache:
1515
- '%USERPROFILE%\.nuget\packages -> appveyor.yml'
1616
- '%LocalAppData%\Microsoft\dotnet -> appveyor.yml'
1717

18-
# Install Pester
1918
install:
20-
- ps: nuget install platyPS -Version 0.9.0 -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
21-
- ps: |
22-
$requiredPesterVersion = '4.3.1'
23-
$pester = Get-Module Pester -ListAvailable | Where-Object { $_.Version -eq $requiredPesterVersion }
24-
$pester
25-
if ($null -eq $pester)
26-
{
27-
if ($null -eq (Get-Module -ListAvailable PowershellGet))
28-
{
29-
# WMF 4 image build
30-
nuget install Pester -Version $requiredPesterVersion -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
31-
}
32-
else
33-
{
34-
# Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4)
35-
Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser
36-
}
37-
}
38-
- ps: |
39-
# the legacy WMF4 image only has the old preview SDKs of dotnet
40-
$globalDotJson = Get-Content .\global.json -Raw | ConvertFrom-Json
41-
$dotNetCoreSDKVersion = $globalDotJson.sdk.version
42-
if (-not ((dotnet --version).StartsWith($dotNetCoreSDKVersion)))
43-
{
44-
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1
45-
.\dotnet-install.ps1 -Version $dotNetCoreSDKVersion
46-
}
19+
- ps: Import-Module .\tools\appveyor.psm1
20+
- ps: if ($env:PowerShellEdition -eq 'WindowsPowerShell') { Invoke-AppveyorInstall }
21+
- pwsh: if ($env:PowerShellEdition -eq 'PowerShellCore') { Import-Module .\tools\appveyor.psm1; Invoke-AppveyorInstall }
4722

4823
build_script:
49-
- ps: |
50-
$PSVersionTable
51-
Write-Verbose "Pester version: $((Get-Command Invoke-Pester).Version)" -Verbose
52-
Write-Verbose ".NET SDK version: $(dotnet --version)" -Verbose
53-
Push-Location C:\projects\psscriptanalyzer
54-
# Test build using netstandard to test whether APIs are being called that are not available in .Net Core. Remove output afterwards.
55-
.\buildCoreClr.ps1 -Framework netstandard1.6 -Configuration Release -Build
56-
git clean -dfx
57-
C:\projects\psscriptanalyzer\buildCoreClr.ps1 -Framework net451 -Configuration $env:BuildConfiguration -Build
58-
C:\projects\psscriptanalyzer\build.ps1 -BuildDocs
59-
Pop-Location
60-
61-
# branches to build
62-
branches:
63-
# whitelist
64-
only:
65-
- master
66-
- development
24+
- ps: |
25+
if ($env:PowerShellEdition -eq 'WindowsPowerShell') {
26+
Invoke-AppveyorBuild -CheckoutPath $env:APPVEYOR_BUILD_FOLDER -BuildConfiguration $env:BuildConfiguration -BuildType 'FullCLR'
27+
}
28+
- pwsh: |
29+
if ($env:PowerShellEdition -eq 'PowerShellCore') {
30+
Import-Module .\tools\appveyor.psm1 # Appveyor does not persist pwsh sessions like it does for ps
31+
Invoke-AppveyorBuild -CheckoutPath $env:APPVEYOR_BUILD_FOLDER -BuildConfiguration $env:BuildConfiguration -BuildType 'NetStandard'
32+
}
6733
68-
# Run Pester tests and store the results
34+
# Test scripts are not in a module function because the tests behave differently for unknown reasons in AppVeyor
6935
test_script:
70-
- SET PATH=c:\Program Files\WindowsPowerShell\Modules\;%PATH%;
71-
- ps: |
72-
copy-item "C:\projects\psscriptanalyzer\out\PSScriptAnalyzer" "$Env:ProgramFiles\WindowsPowerShell\Modules\" -Recurse -Force
73-
$testResultsFile = ".\TestResults.xml"
74-
$testScripts = "C:\projects\psscriptanalyzer\Tests\Engine","C:\projects\psscriptanalyzer\Tests\Rules"
75-
$testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru
76-
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile))
77-
if ($testResults.FailedCount -gt 0) {
78-
throw "$($testResults.FailedCount) tests failed."
79-
}
36+
- ps: |
37+
if ($env:PowerShellEdition -eq 'WindowsPowerShell') {
38+
$modulePath = $env:PSModulePath.Split([System.IO.Path]::PathSeparator) | Where-Object { Test-Path $_} | Select-Object -First 1
39+
Copy-Item "${env:APPVEYOR_BUILD_FOLDER}\out\PSScriptAnalyzer" "$modulePath\" -Recurse -Force
40+
$testResultsFile = ".\TestResults.xml"
41+
$testScripts = "${env:APPVEYOR_BUILD_FOLDER}\Tests\Engine","${env:APPVEYOR_BUILD_FOLDER}\Tests\Rules"
42+
$testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru
43+
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/${env:APPVEYOR_JOB_ID}", (Resolve-Path $testResultsFile))
44+
if ($testResults.FailedCount -gt 0) {
45+
throw "$($testResults.FailedCount) tests failed."
46+
}
47+
}
48+
- pwsh: |
49+
if ($env:PowerShellEdition -eq 'PowerShellCore') {
50+
$modulePath = $env:PSModulePath.Split(';') | Where-Object { Test-Path $_} | Select-Object -First 1
51+
Copy-Item "${env:APPVEYOR_BUILD_FOLDER}\out\PSScriptAnalyzer" "$modulePath\" -Recurse -Force
52+
$testResultsFile = ".\TestResults.xml"
53+
$testScripts = "${env:APPVEYOR_BUILD_FOLDER}\Tests\Engine","${env:APPVEYOR_BUILD_FOLDER}\Tests\Rules"
54+
$testResults = Invoke-Pester -Script $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru
55+
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/${env:APPVEYOR_JOB_ID}", (Resolve-Path $testResultsFile))
56+
if ($testResults.FailedCount -gt 0) {
57+
throw "$($testResults.FailedCount) tests failed."
58+
}
59+
}
8060
81-
# Upload the project along with TestResults as a zip archive
61+
# Upload the project along with test results as a zip archive
8262
on_finish:
83-
- ps: |
84-
$stagingDirectory = (Resolve-Path ..).Path
85-
$zipFile = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip"
86-
Add-Type -assemblyname System.IO.Compression.FileSystem
87-
[System.IO.Compression.ZipFile]::CreateFromDirectory($pwd, $zipFile)
88-
@(
89-
# You can add other artifacts here
90-
(ls $zipFile)
91-
) | % { Push-AppveyorArtifact $_.FullName }
63+
- ps: Invoke-AppveyorFinish

tools/appveyor.psm1

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
$ErrorActionPreference = 'Stop'
5+
6+
# Implements the AppVeyor 'install' step and installs the required versions of Pester, platyPS and the .Net Core SDK if needed.
7+
function Invoke-AppVeyorInstall {
8+
$requiredPesterVersion = '4.3.1'
9+
$pester = Get-Module Pester -ListAvailable | Where-Object { $_.Version -eq $requiredPesterVersion }
10+
if ($null -eq $pester) {
11+
if ($null -eq (Get-Module -ListAvailable PowershellGet)) {
12+
# WMF 4 image build
13+
nuget install Pester -Version $requiredPesterVersion -source https://www.powershellgallery.com/api/v2 -outputDirectory "$env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
14+
}
15+
else {
16+
# Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4)
17+
Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser
18+
}
19+
}
20+
21+
if ($null -eq (Get-Module -ListAvailable PowershellGet)) {
22+
# WMF 4 image build
23+
nuget install platyPS -Version 0.9.0 -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion
24+
}
25+
else {
26+
Install-Module -Name platyPS -Force -Scope CurrentUser -RequiredVersion '0.9.0'
27+
}
28+
29+
# the legacy WMF4 image only has the old preview SDKs of dotnet
30+
$globalDotJson = Get-Content (Join-Path $PSScriptRoot '..\global.json') -Raw | ConvertFrom-Json
31+
$dotNetCoreSDKVersion = $globalDotJson.sdk.version
32+
if (-not ((dotnet --version).StartsWith($dotNetCoreSDKVersion))) {
33+
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1
34+
.\dotnet-install.ps1 -Version $dotNetCoreSDKVersion
35+
Remove-Item .\dotnet-install.ps1
36+
}
37+
}
38+
39+
# Implements the AppVeyor 'build_script' step
40+
function Invoke-AppVeyorBuild {
41+
Param(
42+
[Parameter(Mandatory)]
43+
[ValidateSet('FullCLR', 'NetStandard')]
44+
$BuildType,
45+
46+
[Parameter(Mandatory)]
47+
[ValidateSet('Release', 'PSv3Release')]
48+
$BuildConfiguration,
49+
50+
[Parameter(Mandatory)]
51+
[ValidateScript( {Test-Path $_})]
52+
$CheckoutPath
53+
)
54+
55+
$PSVersionTable
56+
Write-Verbose "Pester version: $((Get-Command Invoke-Pester).Version)" -Verbose
57+
Write-Verbose ".NET SDK version: $(dotnet --version)" -Verbose
58+
Push-Location $CheckoutPath
59+
[Environment]::SetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", 1) # avoid unneccessary initialization in CI
60+
if ($BuildType -eq 'FullCLR') {
61+
.\buildCoreClr.ps1 -Framework net451 -Configuration $BuildConfiguration -Build
62+
}
63+
elseif ($BuildType -eq 'NetStandard') {
64+
.\buildCoreClr.ps1 -Framework netstandard1.6 -Configuration Release -Build
65+
}
66+
.\build.ps1 -BuildDocs
67+
Pop-Location
68+
}
69+
70+
# Implements AppVeyor 'on_finish' step
71+
function Invoke-AppveyorFinish {
72+
$stagingDirectory = (Resolve-Path ..).Path
73+
$zipFile = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip"
74+
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'
75+
[System.IO.Compression.ZipFile]::CreateFromDirectory($pwd, $zipFile)
76+
@(
77+
# You can add other artifacts here
78+
(Get-ChildItem $zipFile)
79+
) | ForEach-Object { Push-AppveyorArtifact $_.FullName }
80+
}

0 commit comments

Comments
 (0)