Fetch Host JIT trace files from functions-release at build time#11719
Fetch Host JIT trace files from functions-release at build time#11719Francisco-Gamino wants to merge 2 commits intodevfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the coldstart pipeline to source the host’s out-of-proc JIT trace files from the functions-release repo at build time (instead of keeping them in this repo), ensuring PreJIT/ is populated before dotnet publish.
Changes:
- Added
jitTraceRepoPathas a shared pipeline variable for the functions-release JIT trace location. - Added a pipeline step to download
coldstart.jittraceandlinux.coldstart.jittracevia ADO REST API intosrc/WebJobs.Script.WebHost/PreJIT/with retries and failure-on-error behavior. - Added an explicit
.NET 10install step in the coldstart job.
Reviewed changes
Copilot reviewed 2 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| eng/ci/templates/variables/coldstart.yml | Introduces jitTraceRepoPath variable for the functions-release JIT trace location. |
| eng/ci/templates/official/jobs/run-coldstart.yml | Downloads JIT trace artifacts into PreJIT/ before publishing; also adds an explicit .NET 10 install step. |
| - task: UseDotNet@2 | ||
| displayName: Install .NET 10 | ||
| inputs: | ||
| packageType: sdk | ||
| version: 10.x | ||
|
|
There was a problem hiding this comment.
This installs .NET 10 again after /eng/ci/templates/install-dotnet.yml, which already installs the SDK pinned by global.json via useGlobalJson: true. The extra UseDotNet@2 version: 10.x step is redundant and can change which dotnet ends up on PATH (potentially diverging from the pinned SDK). Consider removing this step unless there’s a concrete need for a second .NET 10 install.
| - task: UseDotNet@2 | |
| displayName: Install .NET 10 | |
| inputs: | |
| packageType: sdk | |
| version: 10.x |
| $token = "$(System.AccessToken)" | ||
| $headers = @{ | ||
| Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$token")) | ||
| } |
There was a problem hiding this comment.
$(System.AccessToken) can be empty unless the job is configured to allow scripts to access the OAuth token. Consider failing fast when $token is null/empty with a clear error, and/or explicitly wiring the token into the step (e.g., via env:) so this doesn’t silently produce 401s depending on pipeline settings.
| } | ||
|
|
||
| $jitTracePath = "$(jitTraceRepoPath)" | ||
| $baseUrl = "https://dev.azure.com/azfunc/internal/_apis/git/repositories/functions-release/items" |
There was a problem hiding this comment.
The base URL is hardcoded to a specific org/project (dev.azure.com/azfunc/internal). If this pipeline is ever run in a different project or via forks, this will break. Prefer using built-in variables like $(System.CollectionUri) / $(System.TeamProject) and constructing the REST URL from those, keeping only the repository name/id as the hardcoded part if needed.
| $baseUrl = "https://dev.azure.com/azfunc/internal/_apis/git/repositories/functions-release/items" | |
| $collectionUri = "$(System.CollectionUri)".TrimEnd('/') | |
| $teamProject = "$(System.TeamProject)" | |
| $repositoryName = "functions-release" | |
| $baseUrl = "$collectionUri/$teamProject/_apis/git/repositories/$repositoryName/items" |
|
|
||
| foreach ($file in $files) { | ||
| $url = "${baseUrl}?path=${jitTracePath}/${file}&download=true&api-version=7.1" | ||
| $dest = Join-Path $targetDir $file | ||
| Write-Host "Downloading $file from functions-release (${jitTracePath})..." | ||
| try { | ||
| Invoke-RestMethod -Uri $url -Headers $headers -OutFile $dest -MaximumRetryCount 3 -RetryIntervalSec 5 -ErrorAction Stop | ||
| $lineCount = (Get-Content $dest | Measure-Object -Line).Lines | ||
| Write-Host "Downloaded $file ($lineCount lines) to $dest" |
There was a problem hiding this comment.
The download call has no explicit timeout, so a transient network stall can hang the job for a long time. Also, Get-Content reads the entire jittrace file to count lines, which can be very slow/memory-heavy. Consider adding a reasonable -TimeoutSec and logging/validating via file size (e.g., Get-Item) instead of reading the full content.
| foreach ($file in $files) { | |
| $url = "${baseUrl}?path=${jitTracePath}/${file}&download=true&api-version=7.1" | |
| $dest = Join-Path $targetDir $file | |
| Write-Host "Downloading $file from functions-release (${jitTracePath})..." | |
| try { | |
| Invoke-RestMethod -Uri $url -Headers $headers -OutFile $dest -MaximumRetryCount 3 -RetryIntervalSec 5 -ErrorAction Stop | |
| $lineCount = (Get-Content $dest | Measure-Object -Line).Lines | |
| Write-Host "Downloaded $file ($lineCount lines) to $dest" | |
| $downloadTimeoutSec = 300 | |
| foreach ($file in $files) { | |
| $url = "${baseUrl}?path=${jitTracePath}/${file}&download=true&api-version=7.1" | |
| $dest = Join-Path $targetDir $file | |
| Write-Host "Downloading $file from functions-release (${jitTracePath})..." | |
| try { | |
| Invoke-RestMethod -Uri $url -Headers $headers -OutFile $dest -MaximumRetryCount 3 -RetryIntervalSec 5 -TimeoutSec $downloadTimeoutSec -ErrorAction Stop | |
| $downloadedFile = Get-Item -Path $dest -ErrorAction Stop | |
| if ($downloadedFile.Length -le 0) { | |
| throw "Downloaded file '$file' is empty." | |
| } | |
| Write-Host "Downloaded $file ($($downloadedFile.Length) bytes) to $dest" |
| # Download the latest out-of-proc JIT trace files from functions-release and place them | ||
| # in PreJIT/ so they are included in the host publish output. The files have been removed | ||
| # from the host repo; this step is the sole source of truth. | ||
| - pwsh: | |
There was a problem hiding this comment.
Azure pipelines has first-class support for fetching artifacts from another pipeline. Any reason we are not using that here?
There was a problem hiding this comment.
The JIT trace files are committed files in the functions-release repository (dev), not pipeline artifacts. DownloadPipelineArtifact only works for artifacts published by pipeline runs.
To access these files, I will use a repository resource with a checkout of the other repo instead.
…ld time The JIT trace files in src/WebJobs.Script.WebHost/PreJIT/ were stale because the canonical source of truth moved to the functions-release repo (artifacts/Host/JitTrace/dev/). This change: - Deletes coldstart.jittrace and linux.coldstart.jittrace from PreJIT/ - Adds functions-release as an ADO repository resource in host.coldstart.yml - Adds checkout + copy steps in run-coldstart.yml to place the latest JIT trace files in PreJIT/ before dotnet publish - Extracts the repo path to jitTraceRepoPath variable in coldstart.yml - No changes to the .csproj glob (PreJIT\*.jittrace) or merge-jittrace.yml
931a9b3 to
3c3e594
Compare
|
This PR has been replaced by #11722. |
Issue describing the changes in this PR
The JIT trace files in
PreJIT/have been moved tofunctions-release(artifacts/Host/JitTrace/dev/).Changes
coldstart.jittraceandlinux.coldstart.jittracefromsrc/WebJobs.Script.WebHost/PreJIT/run-coldstart.ymlthat downloads the latest files fromfunctions-releasevia ADO REST API intoPreJIT/beforedotnet publishjitTraceRepoPathvariable incoldstart.ymlMaximumRetryCount 3,RetryIntervalSec 5) and fail the pipeline on download failureTesting
createJitTrace=false) completes successfullycreateJitTrace=trueproduces valid merged JIT trace artifactsPull request checklist
IMPORTANT: Currently, changes must be backported to the
in-procbranch to be included in Core Tools and non-Flex deployments.in-procbranch is not requiredrelease_notes.mdAdditional information
Additional PR information