Skip to content

[ci] Fix macOS hosted image label on internal pipeline#12005

Open
jonathanpeppers wants to merge 2 commits into
mainfrom
jonathanpeppers-friendly-train
Open

[ci] Fix macOS hosted image label on internal pipeline#12005
jonathanpeppers wants to merge 2 commits into
mainfrom
jonathanpeppers-friendly-train

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Jul 7, 2026

Copy link
Copy Markdown
Member

Why

Builds on the internal DevDiv pipeline started failing on the macOS MSBuild test jobs with:

No image label found to route agent pool Azure Pipelines.

PR #11708 bumped HostedMacImage from macOS-14-arm64 to macOS-15-arm64. However, Microsoft has paused the macOS-15 ARM64 hosted-agent limited public preview on the Azure Pipelines pool:

The macOS 15 Sequoia ARM64 limited public preview has been paused. Any Azure DevOps organization currently using it can continue to do so.

DevDiv was not already onboarded to the macOS-15-arm64 preview (it had been on macOS-14-arm64), so that label no longer routes to any agent, and the internal builds fail. The only valid macOS labels on the hosted Azure Pipelines pool are now macOS-14, macOS-15, and macOS-26 (no ARM64 variant).

What

  • variables.yaml: point HostedMacImage at macOS-15 (Intel) instead of the paused macOS-15-arm64. This matches the label the public pipeline was already using, which is why dnceng-public stayed green.
  • azure-pipelines-public.yaml: drop the now-redundant HostedMacImage: macOS-15 override, since it is identical to the new default. The public-only LinuxPoolImage override stays, as it has no default.

HostedMacImageWithEmulator was already macOS-15 (never had the -arm64 suffix), so no change was needed there.

Follow-on: Java.Interop Mac lane

Switching the hosted Mac pool from ARM64 to Intel also broke the Java.Interop Mac lane, which had hard-coded nativeAotRid: osx-arm64. Publishing/running the Hello-NativeAOTFromJNI NativeAOT sample for osx-arm64 on an x64 agent produces a .dylib the x64 JDK cannot dlopen:

incompatible architecture (have 'arm64', need 'x86_64')

That run step is continueOnError: true, but it still records an error that the trailing fail-on-issue step turns into a lane failure.

  • stage-java-interop-tests.yaml: detect the agent architecture at runtime via Agent.OSArchitecture and publish/run the sample for the matching RID (osx-arm64 on Apple Silicon, osx-x64 on Intel), so the lane stays correct regardless of the hosted pool's architecture.

Why not just omit the RID and let the CLI pick the default?

The lane targets net10.0 on a .NET 10 SDK, so you might expect PublishAot to infer the host RID automatically. It does, but only for publish, and the lane runs two commands:

dotnet publish -r <rid> samples/Hello-NativeAOTFromJNI/...
dotnet build   -r <rid> -t:RunJavaSample samples/Hello-NativeAOTFromJNI/...
  • The dotnet publish step would be fine without -r: PublishAot=true triggers an automatic RuntimeIdentifier, so it infers the host RID and writes to bin/Release/<host-rid>/publish/.
  • The RunJavaSample step would break: that automatic-RID behavior is restricted to dotnet publish (publish-only note). The run step is a dotnet build, so without -r its RuntimeIdentifier stays empty.

RunJavaSample executes from the publish output directory:

<Exec Command="&quot;$(JavaPath)&quot; -classpath ..."
      WorkingDirectory="$(MSBuildThisFileDirectory)$(PublishDir)" />

$(PublishDir) defaults to bin/$(Configuration)/$(TargetFramework)/$(RuntimeIdentifier)/publish/. If we omit the RID, publish writes to .../osx-x64/publish/ (inferred RID) while the build/run step looks in .../net10.0/publish/ (no RID) - so the .dylib and jars aren't found and the run fails. Passing an explicit RID to both commands keeps their $(PublishDir) aligned, which is why runtime arch detection (rather than omitting the RID) is the correct fix.

PR #11708 bumped `HostedMacImage` to `macOS-15-arm64`, but Microsoft has paused the macOS-15 ARM64 hosted-agent limited public preview on the `Azure Pipelines` pool. DevDiv was not already onboarded to that preview (it was on `macOS-14-arm64`), so the `macOS-15-arm64` label no longer routes and internal builds fail with:

    No image label found to route agent pool Azure Pipelines.

The only valid macOS labels on the hosted `Azure Pipelines` pool are now `macOS-14`, `macOS-15`, and `macOS-26` (no ARM64 variant). Point `HostedMacImage` at `macOS-15` (Intel), matching what the public pipeline already used.

Also remove the now-redundant `HostedMacImage` override in `azure-pipelines-public.yaml`, since it matches the new default.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 7, 2026 13:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Azure DevOps pipeline variables so internal DevDiv macOS jobs route to a valid Microsoft-hosted agent image label, after the macOS-15-arm64 limited preview was paused.

Changes:

  • Change the default HostedMacImage from macOS-15-arm64 to macOS-15 in the shared variables template.
  • Remove the redundant HostedMacImage override from the public pipeline since it now matches the template default.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
build-tools/automation/yaml-templates/variables.yaml Pins HostedMacImage to macOS-15 so internal hosted macOS jobs can route to available agents.
build-tools/automation/azure-pipelines-public.yaml Removes the now-redundant HostedMacImage override in the public pipeline variables section.

Comment thread build-tools/automation/yaml-templates/variables.yaml
Comment thread build-tools/automation/azure-pipelines-public.yaml
The Java.Interop Mac lane hard-coded `nativeAotRid: osx-arm64` for the NativeAOT sample. Now that the hosted Mac pool runs on Intel (macOS-15 x64), publishing/running Hello-NativeAOTFromJNI for `osx-arm64` produces a .dylib the x64 JDK cannot dlopen:

    incompatible architecture (have 'arm64', need 'x86_64')

The run step is `continueOnError: true`, but it still records an error that the trailing `fail-on-issue` step turns into a lane failure.

Detect the agent architecture at runtime via `Agent.OSArchitecture` and publish/run the sample for the matching RID (osx-arm64 on Apple Silicon, osx-x64 on Intel), so the lane stays correct regardless of the hosted pool's architecture.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants