Skip to content

Commit b69a8a3

Browse files
committed
Honor ADOQR_OUTPUT_PATH env var as the default -OutputPath
The Dockerfile sets ENV ADOQR_OUTPUT_PATH=/reports and exposes /reports as a VOLUME, but invoke-adoqr.ps1 never read that variable: -OutputPath defaulted to $PSScriptRoot/assessments (i.e. /opt/adoqr/assessments in the image). Running the container as documented without an explicit -OutputPath wrote reports to an ephemeral in-container folder that was discarded on --rm, leaving the mounted /reports volume empty. Resolve the effective output directory with the precedence -OutputPath argument > $env:ADOQR_OUTPUT_PATH > assessments/ next to the script, via a small testable helper (Resolve-AdoqrOutputPath). An explicit -OutputPath still takes precedence, so existing usage is unchanged. - Add Resolve-AdoqrOutputPath and wire it into Main using PSBoundParameters to distinguish an explicit -OutputPath from the default. - Update -OutputPath comment-based help and the Dockerfile usage notes. - Add Pester coverage (tests/OutputPath.Tests.ps1) and register the helper in the test bootstrap. - Record the fix in CHANGELOG under Unreleased.
1 parent 0abe4fc commit b69a8a3

5 files changed

Lines changed: 80 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to Semantic Versioning.
1212
- Top navigation now includes an Extensions anchor placed before Run Comparison for faster access to extension findings.
1313

1414
### Fixed
15+
- `-OutputPath` now falls back to the `ADOQR_OUTPUT_PATH` environment variable when it is not supplied, so the Docker image's `ENV ADOQR_OUTPUT_PATH=/reports` (previously read by nothing) is honored. Reports generated from the container now land on the mounted `/reports` volume by default instead of an ephemeral in-container folder that was discarded on `--rm`. An explicit `-OutputPath` still takes precedence.
1516
- 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.
1617
- 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.
1718
- 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.

Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
# -v $(pwd)/reports:/reports \
66
# -v $HOME/.azure:/root/.azure \
77
# ghcr.io/microsoft/adoqr:latest \
8-
# -Organization MyOrg -OutputPath /reports -OutputFormat all
8+
# -Organization MyOrg -OutputFormat all
9+
#
10+
# Reports are written to /reports by default via the ADOQR_OUTPUT_PATH env var
11+
# set below, which is exposed as a volume — bind-mount a host path to keep them
12+
# after the container exits. Pass -OutputPath to override the destination.
913
#
1014
# To authenticate non-interactively, mount your existing Azure CLI profile
1115
# (~/.azure) into the container as shown above, or run `az login` inside the

invoke-adoqr.ps1

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
.PARAMETER Project
1515
Optional. One or more project names. If omitted, all projects are assessed.
1616
.PARAMETER OutputPath
17-
Directory for report files. Defaults to current directory.
17+
Directory for report files. When omitted, falls back to the
18+
ADOQR_OUTPUT_PATH environment variable if it is set (the Docker image uses
19+
this to target its /reports volume), otherwise an "assessments" folder next
20+
to this script. Each run writes to a timestamped subfolder under it.
1821
.PARAMETER MaxParallel
1922
Maximum concurrency for project assessment. Default 3.
2023
Requires PowerShell 7+ for parallel execution. Values 2-4 recommended to avoid ADO rate limiting.
@@ -5529,6 +5532,36 @@ function Import-AdoqrSettings {
55295532
return $settings
55305533
}
55315534

5535+
function Resolve-AdoqrOutputPath {
5536+
<#
5537+
.SYNOPSIS
5538+
Resolves the effective report output directory.
5539+
.DESCRIPTION
5540+
Applies the output-directory precedence: an explicit -OutputPath
5541+
argument wins; otherwise the ADOQR_OUTPUT_PATH environment variable is
5542+
honored when set (this is how the Docker image points reports at its
5543+
/reports volume); otherwise the supplied default is used. Empty or
5544+
whitespace-only values are treated as "not provided".
5545+
.PARAMETER ExplicitPath
5546+
The value passed via -OutputPath, or $null/empty when the caller did
5547+
not specify it.
5548+
.PARAMETER EnvPath
5549+
The ADOQR_OUTPUT_PATH environment variable value (may be $null/empty).
5550+
.PARAMETER DefaultPath
5551+
Fallback directory when neither of the above is provided.
5552+
#>
5553+
[CmdletBinding()]
5554+
param(
5555+
[string]$ExplicitPath,
5556+
[string]$EnvPath,
5557+
[string]$DefaultPath
5558+
)
5559+
5560+
if (-not [string]::IsNullOrWhiteSpace($ExplicitPath)) { return $ExplicitPath }
5561+
if (-not [string]::IsNullOrWhiteSpace($EnvPath)) { return $EnvPath }
5562+
return $DefaultPath
5563+
}
5564+
55325565
#endregion
55335566

55345567
#region Main
@@ -5555,6 +5588,13 @@ $script:ExtMgmtUrl = "https://extmgmt.dev.azure.com/$OrgShortName"
55555588
$script:AuditUrl = "https://auditservice.dev.azure.com/$OrgShortName"
55565589
$script:FeedsUrl = "https://feeds.dev.azure.com/$OrgShortName"
55575590

5591+
# Resolve the effective output directory.
5592+
# Precedence: -OutputPath argument > $env:ADOQR_OUTPUT_PATH > assessments/ next
5593+
# to the script. Honoring ADOQR_OUTPUT_PATH lets the Docker image direct reports
5594+
# to its mounted /reports volume without callers having to pass -OutputPath.
5595+
$explicitOutputPath = if ($PSBoundParameters.ContainsKey('OutputPath')) { $OutputPath } else { $null }
5596+
$OutputPath = Resolve-AdoqrOutputPath -ExplicitPath $explicitOutputPath -EnvPath $env:ADOQR_OUTPUT_PATH -DefaultPath (Join-Path $PSScriptRoot 'assessments')
5597+
55585598
# Ensure output directory exists — create timestamped subfolder per run
55595599
$timestamp = Get-Date -Format "yyyy-MM-dd-HHmmss"
55605600
$orgSafeForPath = ($OrgShortName -replace '[^a-zA-Z0-9\-]', '-').ToLower().Trim('-')

tests/OutputPath.Tests.ps1

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' }
2+
3+
BeforeAll {
4+
. $PSScriptRoot/_Bootstrap.ps1
5+
}
6+
7+
Describe 'Resolve-AdoqrOutputPath' {
8+
It 'prefers an explicit -OutputPath over the env var and default' {
9+
Resolve-AdoqrOutputPath -ExplicitPath '/explicit' -EnvPath '/env' -DefaultPath '/def' |
10+
Should -Be '/explicit'
11+
}
12+
13+
It 'honors ADOQR_OUTPUT_PATH when no explicit path is given' {
14+
Resolve-AdoqrOutputPath -ExplicitPath $null -EnvPath '/env' -DefaultPath '/def' |
15+
Should -Be '/env'
16+
}
17+
18+
It 'treats a whitespace-only explicit path as not provided' {
19+
Resolve-AdoqrOutputPath -ExplicitPath ' ' -EnvPath '/env' -DefaultPath '/def' |
20+
Should -Be '/env'
21+
}
22+
23+
It 'ignores an empty ADOQR_OUTPUT_PATH and uses the default' {
24+
Resolve-AdoqrOutputPath -ExplicitPath $null -EnvPath '' -DefaultPath '/def' |
25+
Should -Be '/def'
26+
}
27+
28+
It 'falls back to the default when neither explicit nor env is set' {
29+
Resolve-AdoqrOutputPath -ExplicitPath $null -EnvPath $null -DefaultPath '/def' |
30+
Should -Be '/def'
31+
}
32+
}

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+
'Resolve-AdoqrOutputPath'
3839
)
3940

4041
$funcs = $tree.FindAll({

0 commit comments

Comments
 (0)