Skip to content

Commit 18f68e8

Browse files
committed
fix: repair JaCoCo sourcefile paths before CodeScene upload
Pester's JaCoCo output (after the source-mirrored coverage migration) emits package + sourcefilename pairs that double the relative path (package="src/private/build" + sourcefilename="private/build/Foo.ps1"), so CodeScene's cs-coverage rejects the upload with "The coverage data does not contains any records related to the current repo". Invoke-CodeSceneAnalysis.ps1 now normalizes <class sourcefilename> and <sourcefile name> attributes to bare filenames before upload so package + sourcefile resolves to real repository paths.
1 parent d5c3e7b commit 18f68e8

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5353
### Fixed
5454
- `Test-NovaBuild` and `% nova test` no longer emit `Remove-Item -Recurse` progress bars during the Pester run; `$global:ProgressPreference` is saved and restored around the test execution so CI logs stay clean.
5555
- Code coverage in `Test-NovaBuild` now runs against the source files, instead of the built `dist/<ModuleName>/<ModuleName>.psm1` file so measured coverage percentages and line numbers align with the deployed module.
56+
- `Invoke-CodeSceneAnalysis.ps1` now normalizes Pester's JaCoCo output before upload so the `<class sourcefilename>` and `<sourcefile name>` entries are bare filenames and `package + sourcefile` resolves to real repository paths. This fixes the CodeScene `cs-coverage upload` failure "The coverage data does not contains any records related to the current repo" that appeared after the source-mirrored coverage migration.
5657

5758

5859
### Security

scripts/build/ci/Invoke-CodeSceneAnalysis.ps1

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,36 @@ function Invoke-CodeSceneAnalysisTrigger {
103103
}
104104
}
105105

106+
function Repair-PesterJaCoCoCoveragePath {
107+
param([Parameter(Mandatory)][string]$Path)
108+
109+
[xml]$document = Get-Content -LiteralPath $Path -Raw
110+
$changed = $false
111+
112+
foreach ($class in $document.SelectNodes('//class[@sourcefilename]')) {
113+
$original = $class.GetAttribute('sourcefilename')
114+
$normalized = [System.IO.Path]::GetFileName($original)
115+
if ($normalized -ne $original) {
116+
$class.SetAttribute('sourcefilename', $normalized)
117+
$changed = $true
118+
}
119+
}
120+
121+
foreach ($sourcefile in $document.SelectNodes('//sourcefile[@name]')) {
122+
$original = $sourcefile.GetAttribute('name')
123+
$normalized = [System.IO.Path]::GetFileName($original)
124+
if ($normalized -ne $original) {
125+
$sourcefile.SetAttribute('name', $normalized)
126+
$changed = $true
127+
}
128+
}
129+
130+
if ($changed) {
131+
$document.Save($Path)
132+
Write-Host "Normalized JaCoCo sourcefile paths in '$Path' so package + sourcefile resolve to repo files."
133+
}
134+
}
135+
106136
$shouldUploadCoverage = Test-CodeSceneCoverageUploadRequested -CoveragePath $CoveragePath -UploadCoverage:$UploadCoverage
107137
$shouldRunAnalysis = $TriggerAnalysis.IsPresent
108138

@@ -117,6 +147,7 @@ $accessToken = Get-RequiredCodeSceneValue -Name 'CS_ACCESS_TOKEN'
117147

118148
if ($shouldUploadCoverage) {
119149
$resolvedCoveragePath = Resolve-CodeSceneCoveragePath -CoveragePath $CoveragePath
150+
Repair-PesterJaCoCoCoveragePath -Path $resolvedCoveragePath
120151

121152
if (-not (Get-Command -Name 'cs-coverage' -ErrorAction SilentlyContinue)) {
122153
throw "The 'cs-coverage' CLI was not found on PATH. Install the CodeScene coverage upload tool before running this script."

tests/CodeSceneAnalysis.Tests.ps1

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,42 @@ Set-Location '$emptyWorkingDir'
162162
$result.ExitCode | Should -Not -Be 0
163163
($result.Output -join [Environment]::NewLine) | Should -Match 'No JaCoCo coverage file was found at'
164164
}
165+
166+
It 'normalizes Pester JaCoCo sourcefile paths so package + sourcefile resolves to repo files' {
167+
$coverageDir = Join-Path $TestDrive 'pester-jacoco'
168+
New-Item -ItemType Directory -Path $coverageDir -Force | Out-Null
169+
$coveragePath = Join-Path $coverageDir 'coverage.xml'
170+
Set-Content -LiteralPath $coveragePath -Encoding utf8 -Value @'
171+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
172+
<report name="Pester">
173+
<package name="src/private/build">
174+
<class name="src/private/build/Foo" sourcefilename="private/build/Foo.ps1" />
175+
<sourcefile name="private/build/Foo.ps1" />
176+
</package>
177+
</report>
178+
'@
179+
180+
$runnerContent = @"
181+
function cs-coverage {
182+
`$global:LASTEXITCODE = 0
183+
return
184+
}
185+
186+
[Environment]::SetEnvironmentVariable('CS_URL', 'https://codescene.example.test')
187+
[Environment]::SetEnvironmentVariable('CS_PROJECT_ID', '123')
188+
[Environment]::SetEnvironmentVariable('CS_ACCESS_TOKEN', 'token')
189+
190+
& '$codeSceneAnalysisScriptPath' -CoveragePath '$coveragePath'
191+
"@
192+
193+
$result = Invoke-CodeSceneAnalysisTestScript -RunnerContent $runnerContent
194+
195+
$result.ExitCode | Should -Be 0 -Because ($result.Output -join [Environment]::NewLine)
196+
197+
[xml]$rewritten = Get-Content -LiteralPath $coveragePath -Raw
198+
$class = $rewritten.SelectSingleNode('//class[@sourcefilename]')
199+
$class.GetAttribute('sourcefilename') | Should -Be 'Foo.ps1'
200+
$sourcefile = $rewritten.SelectSingleNode('//sourcefile[@name]')
201+
$sourcefile.GetAttribute('name') | Should -Be 'Foo.ps1'
202+
}
165203
}

0 commit comments

Comments
 (0)