From ea8c54166739e04f98e7fb201818cb7948ad2f83 Mon Sep 17 00:00:00 2001 From: fadwen <110697945+fadwen@users.noreply.github.com> Date: Sun, 18 Oct 2026 23:55:32 -0700 Subject: [PATCH] ci(help): analyze a folder of fixtures with Test-IntuneScript on Linux The static analysis needs only the file, which makes it the one part of the module a Linux host can use, and nothing tested that: the help job imported the module and checked help. It now writes a remediation detection with return before exit 1 and a Win32 detection with nothing on stdout under the folder layout the suite template describes, runs Test-IntuneScript over the folder, and fails unless both errors are reported with the script type taken from the folder names. --- .github/workflows/quality-gates.yml | 37 +++++++++++++++++++++++++++++ CHANGELOG.md | 4 ++++ CLAUDE.md | 4 +++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality-gates.yml b/.github/workflows/quality-gates.yml index 1262e12..5a18362 100644 --- a/.github/workflows/quality-gates.yml +++ b/.github/workflows/quality-gates.yml @@ -362,3 +362,40 @@ jobs: throw 'MAML help was not served on a case-sensitive filesystem.' } Write-Host 'All commands served full help from MAML.' + + # The static analysis is the one part of the module a Linux host can use: it needs the + # file and nothing else. This step keeps that true. The script type is inferred from + # folder names, so the fixtures use the layouts the suite template describes, with the + # separators this host writes; the harness and the log readers stay Windows-only. + - name: Analyze scripts on Linux + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + Import-Module ./IntuneScriptLab.psd1 -Force + + $root = Join-Path ([System.IO.Path]::GetTempPath()) "isl-linux-$([guid]::NewGuid().ToString('N'))" + $remediation = Join-Path $root 'Remediations/Widget' + $win32 = Join-Path $root 'Win32/Widget' + New-Item -ItemType Directory -Path $remediation, $win32 -Force | Out-Null + # return before exit 1: the remediation never runs (IslExitCodeIssue, Error) + Set-Content -Path (Join-Path $remediation 'Detect.ps1') -Value "if (Test-Path /tmp/x) { return 'ok' }`nexit 1" + # exit 0 with nothing on stdout: the app is never detected (IslOutputIssue, Error) + Set-Content -Path (Join-Path $win32 'Detect.ps1') -Value "if (Test-Path /tmp/x) { exit 0 }`nexit 1" + + $findings = @(Test-IntuneScript -Path $root) + $findings | Format-Table Severity, RuleName, Line, @{ n = 'Script'; e = { Split-Path (Split-Path $_.ScriptPath) -Leaf } } -AutoSize | Out-String | Write-Host + + $failed = @() + $exit = @($findings | Where-Object { $_.RuleName -eq 'IslExitCodeIssue' -and $_.Severity -eq 'Error' -and $_.ScriptPath -like '*Remediations*' }) + if (-not $exit) { $failed += 'the return-before-exit detection was not reported' } + $output = @($findings | Where-Object { $_.RuleName -eq 'IslOutputIssue' -and $_.Severity -eq 'Error' -and $_.ScriptPath -like '*Win32*' }) + if (-not $output) { $failed += 'the silent Win32 detection was not reported' } + $context = @($findings | Where-Object { $_.RuleName -eq 'IslAssumedContext' -and $_.Message -like '*Win32Detection*' }) + if (-not $context) { $failed += 'the Win32 folder did not set the script type' } + Remove-Item -Path $root -Recurse -Force + + if ($failed) { + $failed | ForEach-Object { Write-Host "FAILED: $_" } + throw 'Test-IntuneScript did not analyze the fixtures on Linux.' + } + Write-Host 'Test-IntuneScript analyzed both fixtures on Linux with the expected findings.' diff --git a/CHANGELOG.md b/CHANGELOG.md index 092a80c..e20c54c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ release notes. ### Changed +- The `help` job in `quality-gates.yml`, the one that runs on Linux, also analyzes a folder of two + fixture scripts with `Test-IntuneScript` and fails unless the return-before-exit detection and the + silent Win32 detection are reported with the script type taken from the folder names. The static + analysis needs only the file, and that is now tested where it is claimed. - `Validation/Findings.md` records an enrollment of the Windows 11 Home ARM64 device: in 75 minutes and 11 syncs the service never sent the Intune Management Extension, so the agent's behaviour on ARM64 stays a host survey until a Pro or Enterprise ARM64 device is available. The LAPS diff --git a/CLAUDE.md b/CLAUDE.md index bf62233..9b54e8d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -68,7 +68,9 @@ backslash entry names (build zips entry by entry with forward slashes). The harness launches `powershell.exe` hosts by architecture, reads the registry and registers scheduled tasks, so the suites run on Windows only: the `desktop` job under 5.1 and the `arm64` -job on Windows on ARM. The `help` job proves the module imports on Linux; nothing else there runs. +job on Windows on ARM. The `help` job proves the module imports on Linux and that +`Test-IntuneScript` analyzes a folder there, with the script type inferred from forward-slash +paths; no suite and no harness run there. ### Variable names are case-insensitive, and nested functions have their own `$PSBoundParameters`