-
-
Notifications
You must be signed in to change notification settings - Fork 0
153 lines (138 loc) · 6.35 KB
/
Copy pathCI.yaml
File metadata and controls
153 lines (138 loc) · 6.35 KB
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
150
151
152
153
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pull-requests: write
jobs:
lint:
name: PSScriptAnalyzer Lint
runs-on: ubuntu-latest
# Guard against a hung step burning the 6-hour default. Lint normally
# finishes in well under a minute.
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
# Skip lint on the un-initialized template — the literal `./{{ModuleName}}`
# path argument can't be parsed by PowerShell (the double braces split into
# mismatched script-block delimiters), so Invoke-ScriptAnalyzer fails with
# a positional-argument error before it ever touches the folder. Same
# marker as the unit-tests job below.
- name: Detect template state
id: template_guard
shell: bash
run: |
if [ -f CHANGELOG.template.md ]; then
echo "is_template=true" >> "$GITHUB_OUTPUT"
else
echo "is_template=false" >> "$GITHUB_OUTPUT"
fi
# No module cache here on purpose -- see the note in the unit-tests job.
# The cache this replaced held 209 bytes: PSScriptAnalyzer ships on the
# runner image, so it was never installed into the cached path and the
# cache only ever restored an empty directory. Install only when the
# image does not already provide it, rather than unconditionally -- the
# module is ~339 MB on disk and re-downloading it every run is far more
# expensive than the cache ever saved.
- name: Install PSScriptAnalyzer
if: steps.template_guard.outputs.is_template == 'false'
shell: pwsh
run: |
# Pin to the version build.depend.psd1 declares, so lint results here match
# a local ./build.ps1 -Task Analyze. Accepting whatever the runner image
# happens to ship means the two can disagree silently.
$required = (Import-PowerShellDataFile -Path build.depend.psd1).PSScriptAnalyzer.Version
$installed = Get-Module -Name PSScriptAnalyzer -ListAvailable |
Where-Object { $_.Version -eq $required }
if ($installed) {
Write-Host "PSScriptAnalyzer $required already available; skipping install."
return
}
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module -Name PSScriptAnalyzer -RequiredVersion $required -Force -Scope CurrentUser
- name: Run PSScriptAnalyzer
if: steps.template_guard.outputs.is_template == 'false'
shell: pwsh
run: |
$required = (Import-PowerShellDataFile -Path build.depend.psd1).PSScriptAnalyzer.Version
Import-Module -Name PSScriptAnalyzer -RequiredVersion $required -Force -ErrorAction Stop
$results = Invoke-ScriptAnalyzer -Path ./{{ModuleName}} -Recurse -Settings PSGallery -ReportSummary
$errors = $results | Where-Object { $_.Severity -eq 'Error' }
if ($results) {
Write-Host "::group::PSScriptAnalyzer Results"
$results | Format-Table -AutoSize
Write-Host "::endgroup::"
}
if ($errors) {
Write-Host "::error::PSScriptAnalyzer found $($errors.Count) error(s)"
exit 1
}
Write-Host "PSScriptAnalyzer passed with no errors"
unit-tests:
name: Unit Tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
# Guard against a hung step burning the 6-hour default. A cold run --
# installing every dependency from the gallery -- completes in about
# 90 seconds. The specific hazard this caught: BuildHelpers' Invoke-Git
# calls WaitForExit() before draining stdout, so on Windows a HEAD commit
# message larger than the 4096-byte pipe buffer deadlocks the build with
# no output at all. Keep merge-commit messages short.
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v7
# Skip subsequent steps on the un-initialized template — Build's
# GENERATEMARKDOWN task can't import the manifest while {{GUID}} is still
# a literal placeholder. Marker: CHANGELOG.template.md exists only
# pre-init; Initialize-Template.ps1 moves it onto CHANGELOG.md during
# init, so downstream repos run the full job. The marker path contains
# no placeholder token, so init's substitution loop leaves this guard
# intact when the workflow is copied into a new module.
# hashFiles() is not allowed in jobs.<job_id>.if, so we evaluate it in a
# step and gate downstream steps on the resulting output.
- name: Detect template state
id: template_guard
shell: bash
run: |
if [ -f CHANGELOG.template.md ]; then
echo "is_template=true" >> "$GITHUB_OUTPUT"
else
echo "is_template=false" >> "$GITHUB_OUTPUT"
fi
# No module cache here on purpose. Measured on a derived repo, same tree:
# ubuntu 27s warm / 27s cold, macOS 16s / 26s, Windows 28s / 50s. The
# three jobs run in parallel, so the cache bought at most ~22s of
# wall-clock. Against that it made pull-request runs warm and main runs
# cold, so a PR could pass on a code path main never exercised.
# build.ps1 -Bootstrap gates installation on Invoke-PSDepend -Test, so a
# runner that already satisfies the dependency file does no install work.
- name: Build and Test
if: steps.template_guard.outputs.is_template == 'false'
shell: pwsh
run: |
New-Item -Path out -ItemType Directory -Force | Out-Null
./build.ps1 -Task Build,Test -Bootstrap
- name: Upload Coverage to Codecov
if: success() && steps.template_guard.outputs.is_template == 'false' && env.CODECOV_TOKEN != ''
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
uses: codecov/codecov-action@v7
with:
token: ${{ env.CODECOV_TOKEN }}
files: out/codeCoverage.xml
flags: ${{ matrix.os }}
fail_ci_if_error: false
- name: Upload Test Results
if: always() && steps.template_guard.outputs.is_template == 'false'
uses: actions/upload-artifact@v7
with:
name: test-results-${{ matrix.os }}
path: out/
retention-days: 30