Skip to content

Commit 2e87add

Browse files
committed
ci: add gallery-installed validation
1 parent ae46694 commit 2e87add

12 files changed

Lines changed: 445 additions & 10 deletions
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
name: psgraph-gallery-installed-e2e
2+
3+
on:
4+
push:
5+
paths:
6+
- '.github/workflows/gallery-installed-e2e.yml'
7+
- 'eng/Test-GalleryInstalledPSQuickGraph.ps1'
8+
9+
workflow_dispatch:
10+
inputs:
11+
module_version:
12+
description: 'Optional exact PSGallery module version to validate, e.g. 2.5.0-beta5. Empty uses latest visible version.'
13+
required: false
14+
default: ''
15+
16+
release:
17+
types: [published]
18+
19+
jobs:
20+
gallery-installed:
21+
name: ${{ matrix.os }} / ${{ matrix.rid }}
22+
runs-on: ${{ matrix.os }}
23+
permissions:
24+
contents: read
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
include:
29+
- os: ubuntu-24.04
30+
rid: linux-x64
31+
- os: windows-2022
32+
rid: win-x64
33+
- os: macos-14
34+
rid: osx-arm64
35+
36+
steps:
37+
- name: Checkout code
38+
uses: actions/checkout@v4
39+
40+
- name: Install PowerShell
41+
uses: PSModule/install-powershell@v1
42+
with:
43+
Version: latest
44+
45+
- name: Verify PowerShell version
46+
shell: pwsh
47+
run: |
48+
$PSVersionTable.PSVersion.ToString() | Write-Host
49+
50+
- name: Resolve module version
51+
id: module
52+
shell: pwsh
53+
run: |
54+
if ('${{ github.event_name }}' -eq 'release') {
55+
$tag = '${{ github.ref }}' -replace '^refs/tags/', ''
56+
$tag = $tag -replace '^v', ''
57+
if ($tag -notmatch '^[0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9\-]+)?$') {
58+
throw 'Bad tag format. Expected vX.Y.Z or vX.Y.Z-label.'
59+
}
60+
61+
$moduleVersion = $tag
62+
}
63+
elseif (-not [string]::IsNullOrWhiteSpace('${{ github.event.inputs.module_version }}')) {
64+
$moduleVersion = '${{ github.event.inputs.module_version }}'
65+
if ($moduleVersion -notmatch '^[0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9\-]+)?$') {
66+
throw 'Manual module_version must look like X.Y.Z or X.Y.Z-label.'
67+
}
68+
}
69+
else {
70+
$module = Find-Module -Name PSQuickGraph -Repository PSGallery -AllowPrerelease -ErrorAction Stop | Select-Object -First 1
71+
if ($null -eq $module) {
72+
throw 'PSQuickGraph was not found in PSGallery.'
73+
}
74+
75+
$moduleVersion = $module.Version.ToString()
76+
}
77+
78+
$allowPrerelease = $moduleVersion.Contains('-')
79+
"module_version=$moduleVersion" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
80+
"allow_prerelease=$allowPrerelease" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
81+
82+
- name: Install PSQuickGraph from PSGallery
83+
shell: pwsh
84+
run: |
85+
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
86+
87+
$moduleVersion = '${{ steps.module.outputs.module_version }}'
88+
$allowPrerelease = '${{ steps.module.outputs.allow_prerelease }}' -eq 'True'
89+
90+
$installParameters = @{
91+
Name = 'PSQuickGraph'
92+
Repository = 'PSGallery'
93+
RequiredVersion = $moduleVersion
94+
Scope = 'CurrentUser'
95+
Force = $true
96+
ErrorAction = 'Stop'
97+
}
98+
99+
if ($allowPrerelease) {
100+
$installParameters.AllowPrerelease = $true
101+
}
102+
103+
$maxAttempts = 12
104+
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
105+
try {
106+
Install-Module @installParameters
107+
break
108+
}
109+
catch {
110+
if ($attempt -eq $maxAttempts) {
111+
throw
112+
}
113+
114+
Write-Warning "Install-Module failed on attempt $attempt/$maxAttempts. Waiting for PSGallery propagation before retrying. $($_.Exception.Message)"
115+
Start-Sleep -Seconds 30
116+
}
117+
}
118+
119+
$installedParameters = @{
120+
Name = 'PSQuickGraph'
121+
RequiredVersion = $moduleVersion
122+
ErrorAction = 'Stop'
123+
}
124+
125+
if ($allowPrerelease) {
126+
$installedParameters.AllowPrerelease = $true
127+
}
128+
129+
$installed = Get-InstalledModule @installedParameters
130+
if ($null -eq $installed) {
131+
throw "PSQuickGraph $moduleVersion was not found after Install-Module."
132+
}
133+
134+
- name: Run gallery-installed smoke suite
135+
shell: pwsh
136+
run: |
137+
$outputDirectory = Join-Path $PWD 'artifacts/gallery-installed-e2e/${{ matrix.rid }}'
138+
pwsh -NoLogo -NoProfile -File ./eng/Test-GalleryInstalledPSQuickGraph.ps1 `
139+
-ModuleName PSQuickGraph `
140+
-RequiredVersion '${{ steps.module.outputs.module_version }}' `
141+
-OutputDirectory $outputDirectory
142+
143+
- name: Ensure Pester is available
144+
shell: pwsh
145+
run: |
146+
$pester = Get-Module -ListAvailable -Name Pester |
147+
Where-Object { $_.Version -ge [version]'5.0.0' } |
148+
Sort-Object Version -Descending |
149+
Select-Object -First 1
150+
151+
if ($null -eq $pester) {
152+
Install-Module -Name Pester -Repository PSGallery -Scope CurrentUser -Force -SkipPublisherCheck -ErrorAction Stop
153+
}
154+
155+
- name: Run gallery-installed Pester suite
156+
shell: pwsh
157+
env:
158+
PSGRAPH_TEST_MODULE_NAME: PSQuickGraph
159+
PSGRAPH_TEST_MODULE_VERSION: ${{ steps.module.outputs.module_version }}
160+
run: |
161+
Invoke-Pester -Path ./PsGraph.Pester.Tests -CI
162+
163+
- name: Upload gallery-installed artifacts
164+
if: always()
165+
uses: actions/upload-artifact@v4
166+
with:
167+
name: gallery-installed-e2e-${{ matrix.rid }}
168+
path: artifacts/gallery-installed-e2e/${{ matrix.rid }}
169+
if-no-files-found: warn

PsGraph.Pester.Tests/PSGraph.Basic.Tests.ps1

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1"
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'New-Graph' {
@@ -47,4 +48,4 @@ Describe 'New-Graph' {
4748
Add-Edge -From H -To I -Graph $graph | Out-Null
4849
Add-Edge -From M -To B -Graph $graph | Out-Null
4950
}
50-
}
51+
}

PsGraph.Pester.Tests/PSGraph.DsmClustering.Config.Tests.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1" -Verbose
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'Start-DSMClustering AlgorithmConfig coercion' {

PsGraph.Pester.Tests/PSGraph.GraphDistanceVector.Tests.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1"
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'Get-GraphDistanceVector' {

PsGraph.Pester.Tests/PSGraph.GraphPath.Tests.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1"
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'Get-GraphPath' {

PsGraph.Pester.Tests/PSGraph.GraphTopologicalSort.Tests.ps1

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1"
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
4+
5+
function Skip-IfGraphTopologicalSortUnavailable {
6+
$allowMissingTopologicalSort = $env:PSGRAPH_ALLOW_MISSING_TOPOLOGICAL_SORT -eq '1'
7+
if ($allowMissingTopologicalSort -and -not (Get-Command -Name Get-GraphTopologicalSort -ErrorAction SilentlyContinue)) {
8+
Set-ItResult -Skipped -Because 'Get-GraphTopologicalSort is not exported by this installed PSQuickGraph version.'
9+
return $true
10+
}
11+
12+
return $false
13+
}
314
}
415

516
Describe 'Get-GraphTopologicalSort' {
617
It 'Should return source vertices before dependent vertices' {
18+
if (Skip-IfGraphTopologicalSortUnavailable) { return }
19+
720
$graph = New-Graph
821
Add-Edge -From A -To B -Graph $graph | Out-Null
922
Add-Edge -From A -To C -Graph $graph | Out-Null
@@ -21,6 +34,8 @@ Describe 'Get-GraphTopologicalSort' {
2134
}
2235

2336
It 'Should return targets before sources when reversed' {
37+
if (Skip-IfGraphTopologicalSortUnavailable) { return }
38+
2439
$graph = New-Graph
2540
Add-Edge -From A -To B -Graph $graph | Out-Null
2641
Add-Edge -From B -To C -Graph $graph | Out-Null
@@ -31,6 +46,8 @@ Describe 'Get-GraphTopologicalSort' {
3146
}
3247

3348
It 'Should throw for cyclic graphs' {
49+
if (Skip-IfGraphTopologicalSortUnavailable) { return }
50+
3451
$graph = New-Graph
3552
Add-Edge -From A -To B -Graph $graph | Out-Null
3653
Add-Edge -From B -To A -Graph $graph | Out-Null

PsGraph.Pester.Tests/PSGraph.ImportGraph.Tests.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1" -Force
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'Import-Graph CSV' {

PsGraph.Pester.Tests/PSGraph.InOutEdge.Tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1"
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'Get-InEdge' {
@@ -72,4 +73,3 @@ Describe 'Get-OutEdge' {
7273
$outEdges | Should -BeNullOrEmpty
7374
}
7475
}
75-
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
function Import-PSGraphTestModule {
2+
[CmdletBinding()]
3+
param(
4+
[string] $ModuleName = $(if ([string]::IsNullOrWhiteSpace($env:PSGRAPH_TEST_MODULE_NAME)) { 'PSQuickGraph' } else { $env:PSGRAPH_TEST_MODULE_NAME }),
5+
6+
[string] $RequiredVersion = $env:PSGRAPH_TEST_MODULE_VERSION,
7+
8+
[string] $ModuleManifestPath = $env:PSGRAPH_TEST_MODULE_MANIFEST
9+
)
10+
11+
$ErrorActionPreference = 'Stop'
12+
13+
if (-not [string]::IsNullOrWhiteSpace($ModuleManifestPath)) {
14+
if (-not (Test-Path -LiteralPath $ModuleManifestPath)) {
15+
throw "PSGraph test module manifest '$ModuleManifestPath' was not found."
16+
}
17+
18+
Import-Module -Name (Resolve-Path -LiteralPath $ModuleManifestPath).Path -Force -ErrorAction Stop
19+
return
20+
}
21+
22+
if (-not [string]::IsNullOrWhiteSpace($RequiredVersion)) {
23+
$installedParameters = @{
24+
Name = $ModuleName
25+
RequiredVersion = $RequiredVersion
26+
ErrorAction = 'Stop'
27+
}
28+
29+
if ($RequiredVersion.Contains('-')) {
30+
$installedParameters.AllowPrerelease = $true
31+
}
32+
33+
$installedModule = Get-InstalledModule @installedParameters | Select-Object -First 1
34+
if ($null -eq $installedModule) {
35+
throw "PSGraph test module '$ModuleName' $RequiredVersion was not found."
36+
}
37+
38+
$manifestPath = Join-Path $installedModule.InstalledLocation "$ModuleName.psd1"
39+
if (-not (Test-Path -LiteralPath $manifestPath)) {
40+
$manifestPath = Get-ChildItem -LiteralPath $installedModule.InstalledLocation -Filter '*.psd1' |
41+
Select-Object -First 1 -ExpandProperty FullName
42+
}
43+
44+
if (-not (Test-Path -LiteralPath $manifestPath)) {
45+
throw "PSGraph test module manifest was not found under '$($installedModule.InstalledLocation)'."
46+
}
47+
48+
Import-Module -Name $manifestPath -Force -ErrorAction Stop
49+
return
50+
}
51+
52+
$defaultManifestPath = Join-Path $PSScriptRoot '../PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1'
53+
if (Test-Path -LiteralPath $defaultManifestPath) {
54+
Import-Module -Name (Resolve-Path -LiteralPath $defaultManifestPath).Path -Force -ErrorAction Stop
55+
return
56+
}
57+
58+
Import-Module -Name $ModuleName -Force -ErrorAction Stop
59+
}

PsGraph.Pester.Tests/PSGraph.TestGraphPath.Tests.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
BeforeAll {
2-
Import-Module "./PSGraph.Tests/bin/Debug/net9.0/PSQuickGraph.psd1" -Force
2+
. "$PSScriptRoot/PSGraph.TestBootstrap.ps1"
3+
Import-PSGraphTestModule
34
}
45

56
Describe 'Test-GraphPath' {

0 commit comments

Comments
 (0)