Skip to content

Commit ba56db0

Browse files
committed
Skip auto-open of the report in headless/CI runs (+ ADOQR_NO_OPEN)
The end-of-run auto-open invoked the platform opener unconditionally. On a headless agent (scheduled pipeline, container, CI) xdg-open is often absent or fails with no display; under PowerShell 7.4 a missing/failing native command is a terminating error, which the script's trap turns into a FATAL ERROR — failing the run even though the assessment and reports succeeded. Suppress auto-open in non-interactive contexts and make it best-effort: - Add Test-ShouldAutoOpenReport, honoring ADOQR_NO_OPEN (parity with the Bash entry point) plus CI / TF_BUILD (GitHub Actions, Azure Pipelines). - Wrap the opener in try/catch so a missing or failing opener degrades to a verbose message instead of a fatal error. - Add Pester coverage, document ADOQR_NO_OPEN in the README, and record the change in CHANGELOG.
1 parent 0abe4fc commit ba56db0

5 files changed

Lines changed: 82 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ and this project adheres to Semantic Versioning.
1010
### Added
1111
- Executive summary now includes an Organization Extensions section that lists all extensions with Installed vs Default classification and installed-first ordering.
1212
- Top navigation now includes an Extensions anchor placed before Run Comparison for faster access to extension findings.
13+
- `ADOQR_NO_OPEN` environment variable to suppress auto-opening the executive report (parity with the Bash entry point).
1314

1415
### Fixed
16+
- Auto-opening the executive report is now skipped in non-interactive contexts (when `ADOQR_NO_OPEN` is set, or under CI/Azure Pipelines via `CI`/`TF_BUILD`) and wrapped so a missing or failing opener — e.g. no `xdg-open` on a headless agent — can no longer turn an otherwise successful assessment into a fatal error. This makes scheduled/container runs reliable.
1517
- Auto-opening the executive HTML report at the end of a run now uses the platform-native opener (`open` on macOS, `xdg-open` on Linux, `Start-Process` on Windows) instead of `Start-Process` for all platforms, which raised `Permission denied` on macOS/Linux because PowerShell tried to execute the `.html` file as a binary.
1618
- Pipeline Authorization Scope checks now evaluate effective scope using project/org pipeline settings (`enforceJobAuthScope` and `enforceJobAuthScopeForReleases`) before pipeline-level values, preventing false positives when scope is enforced at project level.
1719
- Organization policy checks now evaluate policy `value` (with safe casing/boolean normalization) and include the new helper functions in parallel runspace serialization, fixing false results for `OAUTH-02` (SSH Access Disabled) and aligning `OAUTH-01` with the actual policy state.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ az login
9292

9393
Reports are saved to a timestamped subfolder under `assessments/`. The
9494
executive HTML summary auto-opens in your browser when the assessment
95-
completes.
95+
completes. Auto-opening is skipped automatically in CI and other
96+
non-interactive environments; set `ADOQR_NO_OPEN=1` to suppress it anywhere.
9697

9798
If the Azure DevOps Azure CLI extension is not already installed, adoqr
9899
installs it automatically before the review starts.

invoke-adoqr.ps1

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5529,6 +5529,31 @@ function Import-AdoqrSettings {
55295529
return $settings
55305530
}
55315531

5532+
function Test-ShouldAutoOpenReport {
5533+
<#
5534+
.SYNOPSIS
5535+
Decides whether the executive report should auto-open in a browser.
5536+
.DESCRIPTION
5537+
Auto-opening is meaningful only in an interactive desktop session. It is
5538+
suppressed when explicitly disabled via ADOQR_NO_OPEN or when running in
5539+
a non-interactive automation context (CI, scheduled pipelines,
5540+
containers), where launching a browser has no effect and can surface a
5541+
missing-opener error. ADOQR_NO_OPEN mirrors the Bash entry point.
5542+
.PARAMETER EnvironmentVariables
5543+
Hashtable of relevant environment variables (ADOQR_NO_OPEN, TF_BUILD,
5544+
CI). Injected for testability; callers pass the live $env: values.
5545+
#>
5546+
[CmdletBinding()]
5547+
param(
5548+
[hashtable]$EnvironmentVariables = @{}
5549+
)
5550+
5551+
if (-not [string]::IsNullOrWhiteSpace($EnvironmentVariables['ADOQR_NO_OPEN'])) { return $false } # explicit opt-out
5552+
if (-not [string]::IsNullOrWhiteSpace($EnvironmentVariables['TF_BUILD'])) { return $false } # Azure Pipelines
5553+
if (-not [string]::IsNullOrWhiteSpace($EnvironmentVariables['CI'])) { return $false } # GitHub Actions & most CIs
5554+
return $true
5555+
}
5556+
55325557
#endregion
55335558

55345559
#region Main
@@ -6238,15 +6263,33 @@ Write-Host ""
62386263

62396264
Write-Progress -Activity "Assessment" -Completed
62406265

6241-
# Auto-open the executive report in the default browser (cross-platform)
6242-
if ($IsMacOS) {
6243-
& open $htmlReportPath
6266+
# Auto-open the executive report in the default browser (cross-platform).
6267+
# Skipped in non-interactive contexts (ADOQR_NO_OPEN, CI, scheduled pipelines,
6268+
# containers); wrapped so a missing or failing opener never turns a successful
6269+
# assessment into a fatal error.
6270+
$openEnv = @{
6271+
ADOQR_NO_OPEN = $env:ADOQR_NO_OPEN
6272+
TF_BUILD = $env:TF_BUILD
6273+
CI = $env:CI
62446274
}
6245-
elseif ($IsLinux) {
6246-
& xdg-open $htmlReportPath
6275+
if (Test-ShouldAutoOpenReport -EnvironmentVariables $openEnv) {
6276+
try {
6277+
if ($IsMacOS) {
6278+
& open $htmlReportPath
6279+
}
6280+
elseif ($IsLinux) {
6281+
& xdg-open $htmlReportPath
6282+
}
6283+
else {
6284+
Start-Process $htmlReportPath
6285+
}
6286+
}
6287+
catch {
6288+
Write-Verbose "Could not auto-open the executive report: $($_.Exception.Message)"
6289+
}
62476290
}
62486291
else {
6249-
Start-Process $htmlReportPath
6292+
Write-Verbose "Auto-open suppressed (ADOQR_NO_OPEN set or non-interactive/CI environment). Report: $htmlReportPath"
62506293
}
62516294

62526295
#endregion

tests/AutoOpen.Tests.ps1

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' }
2+
3+
BeforeAll {
4+
. $PSScriptRoot/_Bootstrap.ps1
5+
}
6+
7+
Describe 'Test-ShouldAutoOpenReport' {
8+
It 'opens when no suppressing environment variables are set' {
9+
Test-ShouldAutoOpenReport -EnvironmentVariables @{} | Should -BeTrue
10+
}
11+
12+
It 'suppresses when ADOQR_NO_OPEN is set' {
13+
Test-ShouldAutoOpenReport -EnvironmentVariables @{ ADOQR_NO_OPEN = '1' } | Should -BeFalse
14+
}
15+
16+
It 'suppresses under Azure Pipelines (TF_BUILD)' {
17+
Test-ShouldAutoOpenReport -EnvironmentVariables @{ TF_BUILD = 'True' } | Should -BeFalse
18+
}
19+
20+
It 'suppresses under generic CI (CI)' {
21+
Test-ShouldAutoOpenReport -EnvironmentVariables @{ CI = 'true' } | Should -BeFalse
22+
}
23+
24+
It 'treats empty/whitespace values as not set' {
25+
Test-ShouldAutoOpenReport -EnvironmentVariables @{ ADOQR_NO_OPEN = ''; TF_BUILD = ' '; CI = $null } |
26+
Should -BeTrue
27+
}
28+
}

tests/_Bootstrap.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ $wantedFns = @(
3535
'Get-AdoqrHeaderCss'
3636
'Get-AdoqrHeaderHtml'
3737
'Import-AdoqrSettings'
38+
'Test-ShouldAutoOpenReport'
3839
)
3940

4041
$funcs = $tree.FindAll({

0 commit comments

Comments
 (0)