From 026b1224fd8385070cdef7a37dd016a2d8dac4d5 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 9 Feb 2026 15:24:37 -0600 Subject: [PATCH 1/2] Use Helix ListFiles endpoint to work around dnceng#6072 The Helix work item Details API returns incorrect file URIs for files in subdirectories (path flattening) and rejects unicode characters in filenames. The separate ListFiles endpoint returns direct blob storage URIs that work for all filenames. Replace the previous workaround (reconstructing permalink URIs from FileName) with a call to ListFiles, which completely bypasses both the subdirectory and unicode bugs. --- .../ci-analysis/references/helix-artifacts.md | 7 +-- .../ci-analysis/scripts/Get-CIStatus.ps1 | 46 +++++++++++++++---- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/.github/skills/ci-analysis/references/helix-artifacts.md b/.github/skills/ci-analysis/references/helix-artifacts.md index 42d17b2eabcf6a..cecd253efdb024 100644 --- a/.github/skills/ci-analysis/references/helix-artifacts.md +++ b/.github/skills/ci-analysis/references/helix-artifacts.md @@ -47,9 +47,10 @@ Always query the specific work item to see what's available rather than assuming Artifacts may be at the root level or nested in subdirectories like `xharness-output/logs/`. -> **Note:** The Helix API has a known bug ([dotnet/dnceng#6072](https://github.com/dotnet/dnceng/issues/6072)) where -> file URIs for subdirectory files are incorrect. The script works around this by rebuilding URIs from the `FileName` -> field, but raw API responses may return broken links for files like `xharness-output/wasm-console.log`. +> **Note:** The Helix work item Details API has a known bug ([dotnet/dnceng#6072](https://github.com/dotnet/dnceng/issues/6072)) where +> file URIs for subdirectory files are incorrect, and unicode characters in filenames are rejected. +> The script works around this by using the separate `ListFiles` endpoint (`GET .../workitems/{id}/files`) +> which returns direct blob storage URIs that work for all filenames regardless of subdirectories or unicode. ## Binlog Files diff --git a/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 b/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 index eb23c4ad50181e..71f8988503e5fb 100644 --- a/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 +++ b/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 @@ -1351,6 +1351,31 @@ function Get-HelixWorkItems { } } +function Get-HelixWorkItemFiles { + <# + .SYNOPSIS + Fetches work item files via the ListFiles endpoint which returns direct blob storage URIs. + .DESCRIPTION + Workaround for https://github.com/dotnet/dnceng/issues/6072: + The Details endpoint returns incorrect permalink URIs for files in subdirectories + and rejects unicode characters in filenames. The ListFiles endpoint returns direct + blob storage URIs that always work, regardless of subdirectory depth or unicode. + #> + param([string]$JobId, [string]$WorkItemName) + + $encodedWorkItem = [uri]::EscapeDataString($WorkItemName) + $url = "https://helix.dot.net/api/2019-06-17/jobs/$JobId/workitems/$encodedWorkItem/files" + + try { + $files = Invoke-CachedRestMethod -Uri $url -TimeoutSec $TimeoutSec -AsJson + return $files + } + catch { + Write-Warning "Failed to fetch files for work item ${WorkItemName}: $_" + return $null + } +} + function Get-HelixWorkItemDetails { param([string]$JobId, [string]$WorkItemName) @@ -1359,17 +1384,18 @@ function Get-HelixWorkItemDetails { try { $response = Invoke-CachedRestMethod -Uri $url -TimeoutSec $TimeoutSec -AsJson - # Workaround for https://github.com/dotnet/dnceng/issues/6072: - # Helix API returns incorrect file URIs for files in subdirectories - # (e.g., xharness-output/testResults.xml). Rebuild URI from FileName. - if ($response -and $response.Files) { - $encodedWorkItem = [uri]::EscapeDataString($WorkItemName) - foreach ($file in $response.Files) { - if ($file.FileName -and $file.FileName -match '/') { - $encodedFileName = ($file.FileName -split '/' | ForEach-Object { [uri]::EscapeDataString($_) }) -join '/' - $file.Uri = "https://helix.dot.net/api/jobs/$JobId/workitems/$encodedWorkItem/files/$encodedFileName?api-version=2019-06-17" + # Replace Files from the Details endpoint with results from ListFiles. + # The Details endpoint has broken URIs for subdirectory and unicode filenames + # (https://github.com/dotnet/dnceng/issues/6072). ListFiles returns direct + # blob storage URIs that always work. + $listFiles = Get-HelixWorkItemFiles -JobId $JobId -WorkItemName $WorkItemName + if ($listFiles) { + $response.Files = @($listFiles | ForEach-Object { + [PSCustomObject]@{ + FileName = $_.Name + Uri = $_.Link } - } + }) } return $response From da4dadb0df2bd35624ef47dd19c9a53fdf421d2e Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 9 Feb 2026 15:49:30 -0600 Subject: [PATCH 2/2] Fix endpoint placeholder and add URL encoding to Details endpoint - helix-artifacts.md: Change {id} to {workItemName} for consistency - Get-CIStatus.ps1: URL-encode WorkItemName in Get-HelixWorkItemDetails to match Get-HelixWorkItemFiles (unicode/special char safety) --- .github/skills/ci-analysis/references/helix-artifacts.md | 2 +- .github/skills/ci-analysis/scripts/Get-CIStatus.ps1 | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/skills/ci-analysis/references/helix-artifacts.md b/.github/skills/ci-analysis/references/helix-artifacts.md index cecd253efdb024..16bd426aad04ad 100644 --- a/.github/skills/ci-analysis/references/helix-artifacts.md +++ b/.github/skills/ci-analysis/references/helix-artifacts.md @@ -49,7 +49,7 @@ Artifacts may be at the root level or nested in subdirectories like `xharness-ou > **Note:** The Helix work item Details API has a known bug ([dotnet/dnceng#6072](https://github.com/dotnet/dnceng/issues/6072)) where > file URIs for subdirectory files are incorrect, and unicode characters in filenames are rejected. -> The script works around this by using the separate `ListFiles` endpoint (`GET .../workitems/{id}/files`) +> The script works around this by using the separate `ListFiles` endpoint (`GET .../workitems/{workItemName}/files`) > which returns direct blob storage URIs that work for all filenames regardless of subdirectories or unicode. ## Binlog Files diff --git a/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 b/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 index 71f8988503e5fb..e386604be3fa5e 100644 --- a/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 +++ b/.github/skills/ci-analysis/scripts/Get-CIStatus.ps1 @@ -1379,7 +1379,8 @@ function Get-HelixWorkItemFiles { function Get-HelixWorkItemDetails { param([string]$JobId, [string]$WorkItemName) - $url = "https://helix.dot.net/api/2019-06-17/jobs/$JobId/workitems/$WorkItemName" + $encodedWorkItem = [uri]::EscapeDataString($WorkItemName) + $url = "https://helix.dot.net/api/2019-06-17/jobs/$JobId/workitems/$encodedWorkItem" try { $response = Invoke-CachedRestMethod -Uri $url -TimeoutSec $TimeoutSec -AsJson