mirror of
https://github.com/GoodOlClint/PSProxmoxVE.git
synced 2026-09-03 18:55:33 +00:00
Merge pull request #115 from GoodOlClint/ci/pin-pester
ci: pin Pester by exact version everywhere it is installed
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
name: Unit Tests
|
||||
|
||||
# Pinned, not floored. Pester is installed fresh on every run, so a version range
|
||||
# lets a new major reach the required checks with no commit to this repo (#112).
|
||||
# Keep in step with PESTER_VERSION in tests/Dockerfile.test.
|
||||
env:
|
||||
PESTER_VERSION: 6.1.0
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
@@ -81,17 +87,26 @@ jobs:
|
||||
name: module-${{ matrix.framework }}-${{ matrix.artifact_os }}
|
||||
path: ./publish/${{ matrix.framework }}/
|
||||
|
||||
- name: Install Pester 5 (PS 5.1)
|
||||
# -RequiredVersion accepts an empty value and degrades to "latest" with
|
||||
# exit 0, so an unset variable would silently restore the float this pin
|
||||
# removes. Fail the job instead.
|
||||
- name: Verify PESTER_VERSION is set
|
||||
shell: pwsh
|
||||
run: |
|
||||
if ([string]::IsNullOrWhiteSpace($env:PESTER_VERSION)) { throw 'PESTER_VERSION is not set' }
|
||||
"Pinning Pester to $env:PESTER_VERSION"
|
||||
|
||||
- name: Install Pester (PS 5.1)
|
||||
if: matrix.ps_version == '5.1'
|
||||
shell: powershell
|
||||
run: |
|
||||
Install-Module -Name Pester -MinimumVersion 5.0 -Force -Scope CurrentUser -SkipPublisherCheck
|
||||
Install-Module -Name Pester -RequiredVersion $env:PESTER_VERSION -Force -Scope CurrentUser -SkipPublisherCheck
|
||||
|
||||
- name: Install Pester 5 (PS 7.x)
|
||||
- name: Install Pester (PS 7.x)
|
||||
if: matrix.ps_version != '5.1'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Install-Module -Name Pester -MinimumVersion 5.0 -Force -Scope CurrentUser
|
||||
Install-Module -Name Pester -RequiredVersion $env:PESTER_VERSION -Force -Scope CurrentUser
|
||||
|
||||
- name: Copy module to module path (PS 5.1)
|
||||
if: matrix.ps_version == '5.1'
|
||||
@@ -121,7 +136,7 @@ jobs:
|
||||
if: matrix.ps_version == '5.1'
|
||||
shell: powershell
|
||||
run: |
|
||||
Import-Module Pester -MinimumVersion 5.0
|
||||
Import-Module Pester -RequiredVersion $env:PESTER_VERSION
|
||||
$config = New-PesterConfiguration
|
||||
$config.Run.Path = "tests/PSProxmoxVE.Tests"
|
||||
$config.Run.Exit = $true
|
||||
@@ -136,7 +151,7 @@ jobs:
|
||||
if: matrix.ps_version != '5.1'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Import-Module Pester -MinimumVersion 5.0
|
||||
Import-Module Pester -RequiredVersion $env:PESTER_VERSION
|
||||
$config = New-PesterConfiguration
|
||||
$config.Run.Path = "tests/PSProxmoxVE.Tests"
|
||||
$config.Run.Exit = $true
|
||||
@@ -175,6 +190,16 @@ jobs:
|
||||
- name: preflight-cleanup self-check
|
||||
run: bash tests/infrastructure/scripts/preflight-cleanup.test.sh
|
||||
|
||||
# The pin lives in two files; split-brain is exactly the unexplained
|
||||
# breakage D017 exists to prevent, so assert they agree.
|
||||
- name: Pester pin agrees across workflow and image
|
||||
run: |
|
||||
wf=$(sed -n 's/^ PESTER_VERSION: *//p' .github/workflows/unit-tests.yml)
|
||||
img=$(sed -n 's/^ARG PESTER_VERSION=//p' tests/Dockerfile.test)
|
||||
echo "workflow=$wf image=$img"
|
||||
[ -n "$wf" ] && [ -n "$img" ] || { echo "could not read one of the pins" >&2; exit 1; }
|
||||
[ "$wf" = "$img" ] || { echo "PESTER_VERSION differs: workflow=$wf image=$img" >&2; exit 1; }
|
||||
|
||||
- name: Shell syntax check
|
||||
run: |
|
||||
for f in tests/infrastructure/scripts/*.sh; do
|
||||
|
||||
@@ -6,7 +6,8 @@ C# binary PowerShell module for managing Proxmox VE (PVE) infrastructure. Two pr
|
||||
- `src/PSProxmoxVE/` — Cmdlets and module surface (targets netstandard2.0)
|
||||
- `src/PSProxmoxVE.Core/` — Services, models, HTTP client (targets netstandard2.0)
|
||||
|
||||
Tests: xUnit (`tests/PSProxmoxVE.Core.Tests/`) and Pester 5 (`tests/PSProxmoxVE.Tests/`).
|
||||
Tests: xUnit (`tests/PSProxmoxVE.Core.Tests/`) and Pester (`tests/PSProxmoxVE.Tests/`), pinned by
|
||||
`PESTER_VERSION` in `.github/workflows/unit-tests.yml` and `tests/Dockerfile.test`.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@ Thank you for your interest in contributing! This document provides guidelines a
|
||||
|
||||
- [.NET SDK 10.0+](https://dotnet.microsoft.com/download)
|
||||
- [PowerShell 7.2+](https://github.com/PowerShell/PowerShell) (for running Pester tests)
|
||||
- [Pester 5](https://pester.dev/) (`Install-Module Pester -MinimumVersion 5.0 -Force`)
|
||||
- [Pester](https://pester.dev/) — match CI's pin: `Install-Module Pester -RequiredVersion 6.1.0 -Force`
|
||||
(the version is `PESTER_VERSION` in `.github/workflows/unit-tests.yml`)
|
||||
- An IDE with C# support (Visual Studio, VS Code with C# Dev Kit, Rider)
|
||||
|
||||
### Building
|
||||
|
||||
@@ -634,6 +634,27 @@ still fails the job. `run-integration.sh` returns 3 for a genuine test failure a
|
||||
reach or authenticate to a node; only 3 is suppressed. Suppressing both would let a botched reboot
|
||||
report success while the lane learned nothing.
|
||||
|
||||
### Amendment 2026-09-01 — the pin covers the test tooling, not just the nested PVE packages
|
||||
|
||||
The gating lane's own tooling is pinned by exact version for the same reason its nested PVE packages
|
||||
are: `Pester` in `tests/Dockerfile.test` (`ARG PESTER_VERSION`) and in `.github/workflows/unit-tests.yml`
|
||||
(`env.PESTER_VERSION`), installed and imported with `-RequiredVersion` at every site, including the
|
||||
suite's own import inside the container. The Dockerfile promotes the ARG to `ENV` so the version is
|
||||
discoverable at runtime. Both files must name the same version, and `shell-selfchecks` asserts it.
|
||||
|
||||
Before this, both sites used `-MinimumVersion 5.0` with no ceiling. The image is rebuilt on every CI
|
||||
run and Pester is installed fresh on every unit-test run, so PSGallery decided the version — a new
|
||||
major could reach the merge gate with no commit to this repository, surfacing as unexplained test
|
||||
breakage on whichever PR happened to run next. That is the same class of moving input the lane split
|
||||
exists to eliminate; the difference is only that it moves in the test runner rather than in PVE.
|
||||
|
||||
It had already happened silently: steps named "Install Pester 5" were resolving 6.1.0 on both the
|
||||
PowerShell 5.1 and 7.x legs, because Pester 6 declares `PowerShellVersion 5.1` and so installs on
|
||||
Windows PowerShell too. Nothing broke — the suite uses only constructs common to 5 and 6 — but
|
||||
nobody chose it.
|
||||
|
||||
Bumping is a deliberate commit that changes both files together.
|
||||
|
||||
### Anti-pattern (do not reintroduce)
|
||||
```bash
|
||||
# NEVER in first-boot.sh — this is the mismatch that left a node unclustered
|
||||
|
||||
+13
-3
@@ -36,12 +36,22 @@ RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
|
||||
&& ln -s /root/.dotnet/tools/pwsh /usr/local/bin/pwsh; \
|
||||
fi
|
||||
|
||||
# Install Pester and prepare module directory
|
||||
# Install Pester and prepare module directory.
|
||||
# Pinned, not floored: this image is rebuilt on every CI run, so a version range
|
||||
# lets a new Pester major reach the gating lane with no commit to this repo.
|
||||
# Bump deliberately, the way D017 treats the nested PVE package set.
|
||||
ARG PESTER_VERSION=6.1.0
|
||||
RUN pwsh -NoProfile -Command \
|
||||
'Set-PSRepository -Name PSGallery -InstallationPolicy Trusted; \
|
||||
Install-Module -Name Pester -MinimumVersion 5.0 -Scope AllUsers -Force' \
|
||||
"Set-PSRepository -Name PSGallery -InstallationPolicy Trusted; \
|
||||
Install-Module -Name Pester -RequiredVersion $PESTER_VERSION -Scope AllUsers -Force" \
|
||||
&& pwsh -NoProfile -Command \
|
||||
"if (-not (Get-Module -ListAvailable Pester | Where-Object Version -eq '$PESTER_VERSION')) { throw 'Pester $PESTER_VERSION not installed' }" \
|
||||
&& mkdir -p /usr/local/share/powershell/Modules/PSProxmoxVE
|
||||
|
||||
# Promoted to ENV so the suite can pin its import too — the install pin alone
|
||||
# does not bind the point of use if a second Pester ever reaches PSModulePath.
|
||||
ENV PESTER_VERSION=$PESTER_VERSION
|
||||
|
||||
WORKDIR /repo
|
||||
CMD ["pwsh", "-NoProfile"]
|
||||
|
||||
|
||||
@@ -565,7 +565,11 @@ cmd_test() {
|
||||
pwsh -NoProfile -Command "
|
||||
\$PveVersion = '$v'
|
||||
\$TestFilter = '$pester_filter_arg'
|
||||
Import-Module Pester -MinimumVersion 5.0
|
||||
\$pesterVersion = \$env:PESTER_VERSION
|
||||
if ([string]::IsNullOrWhiteSpace(\$pesterVersion)) {
|
||||
throw 'PESTER_VERSION is not set — refusing to import whichever Pester happens to be present'
|
||||
}
|
||||
Import-Module Pester -RequiredVersion \$pesterVersion
|
||||
\$config = New-PesterConfiguration
|
||||
|
||||
if (\$TestFilter) {
|
||||
|
||||
Reference in New Issue
Block a user