/
PSHitchhiker.build.ps1
149 lines (123 loc) · 4.74 KB
/
PSHitchhiker.build.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Include: Settings
. './PSHitchhiker.settings.ps1'
# Include: build_utils
. './build_utils.ps1'
# Synopsis: Run/Publish Tests and Fail Build on Error
task Test BeforeTest, RunTests, ConfirmTestsPassed, AfterTest
# Synopsis: Run full Pipleline.
task . Clean, Analyze, Test, Archive, Publish
# Synopsis: Install Build Dependencies
task InstallDependencies {
# Cant run an Invoke-Build Task without Invoke-Build.
Install-Module -Name InvokeBuild -Force
Install-Module -Name DscResourceTestHelper -Force
Install-Module -Name Pester -Force
Install-Module -Name PSScriptAnalyzer -Force
}
# Synopsis: Clean Artifacts Directory
task Clean BeforeClean, {
if(Test-Path -Path $Artifacts)
{
Remove-Item "$Artifacts/*" -Recurse -Force
}
New-Item -ItemType Directory -Path $Artifacts -Force
# Temp
& git clone https://github.com/Xainey/PSTestReport.git
}, AfterClean
# Synopsis: Lint Code with PSScriptAnalyzer
task Analyze BeforeAnalyze, {
$scriptAnalyzerParams = @{
Path = $ModulePath
Severity = @('Error', 'Warning')
Recurse = $true
Verbose = $false
}
$saResults = Invoke-ScriptAnalyzer @scriptAnalyzerParams
# Save Analyze Results as JSON
$saResults | ConvertTo-Json | Set-Content (Join-Path $Artifacts "ScriptAnalysisResults.json")
if ($saResults) {
$saResults | Format-Table
throw "One or more PSScriptAnalyzer errors/warnings where found."
}
}, AfterAnalyze
# Synopsis: Test the project with Pester. Publish Test and Coverage Reports
task RunTests {
$invokePesterParams = @{
OutputFile = (Join-Path $Artifacts "TestResults.xml")
OutputFormat = 'NUnitXml'
Strict = $true
PassThru = $true
Verbose = $false
EnableExit = $false
CodeCoverage = (Get-ChildItem -Path "$ModulePath\*.ps1" -Exclude "*.Tests.*" -Recurse).FullName
}
# Publish Test Results as NUnitXml
$testResults = Invoke-Pester @invokePesterParams;
# Save Test Results as JSON
$testresults | ConvertTo-Json -Depth 5 | Set-Content (Join-Path $Artifacts "PesterResults.json")
# Old: Publish Code Coverage as HTML
# $moduleInfo = @{
# TestResults = $testResults
# BuildNumber = $BuildNumber
# Repository = $Settings.Repository
# PercentCompliance = $PercentCompliance
# OutputFile = (Join-Path $Artifacts "Coverage.htm")
# }
#
# Publish-CoverageHTML @moduleInfo
# Temp: Publish Test Report
$options = @{
BuildNumber = $BuildNumber
GitRepo = $Settings.GitRepo
GitRepoURL = $Settings.ProjectUrl
CiURL = $Settings.CiURL
ShowHitCommands = $true
Compliance = ($PercentCompliance / 100)
ScriptAnalyzerFile = (Join-Path $Artifacts "ScriptAnalyzerResults.json")
PesterFile = (Join-Path $Artifacts "PesterResults.json")
OutputDir = "$Artifacts"
}
. ".\PSTestReport\Invoke-PSTestReport.ps1" @options
}
# Synopsis: Throws and error if any tests do not pass for CI usage
task ConfirmTestsPassed {
# Fail Build after reports are created, this allows CI to publish test results before failing
[xml] $xml = Get-Content (Join-Path $Artifacts "TestResults.xml")
$numberFails = $xml."test-results".failures
assert($numberFails -eq 0) ('Failed "{0}" unit tests.' -f $numberFails)
# Fail Build if Coverage is under requirement
$json = Get-Content (Join-Path $Artifacts "PesterResults.json") | ConvertFrom-Json
$overallCoverage = [Math]::Floor(($json.CodeCoverage.NumberOfCommandsExecuted / $json.CodeCoverage.NumberOfCommandsAnalyzed) * 100)
assert($OverallCoverage -gt $PercentCompliance) ('A Code Coverage of "{0}" does not meet the build requirement of "{1}"' -f $overallCoverage, $PercentCompliance)
}
# Synopsis: Creates Archived Zip and Nuget Artifacts
task Archive BeforeArchive, {
$moduleInfo = @{
ModuleName = $ModuleName
BuildNumber = $BuildNumber
}
Publish-ArtifactZip @moduleInfo
$nuspecInfo = @{
packageName = $ModuleName
author = $Settings.Author
owners = $Settings.Owners
licenseUrl = $Settings.LicenseUrl
projectUrl = $Settings.ProjectUrl
packageDescription = $Settings.PackageDescription
tags = $Settings.Tags
destinationPath = $Artifacts
BuildNumber = $BuildNumber
}
Publish-NugetPackage @nuspecInfo
}, AfterArchive
# Synopsis: Publish to SMB File Share
task Publish BeforePublish, {
$moduleInfo = @{
RepoName = $Settings.SMBRepoName
RepoPath = $Settings.SMBRepoPath
ModuleName = $ModuleName
ModulePath = "$ModulePath\$ModuleName.psd1"
BuildNumber = $BuildNumber
}
Publish-SMBModule @moduleInfo -Verbose
}, AfterPublish